--- old/./.hgtags Thu May 16 16:28:13 2013 +++ new/./.hgtags Thu May 16 16:28:13 2013 @@ -493,3 +493,9 @@ d90c913b810356d43c8e64f08c0f5e60f9c2ca08 hs24-b41 aa9a5e33e823df5f51e9b5d4e85ae91919424179 jdk7u14-b22 482ff4e18ca3fb97f62fd9fe2823d48721fdee28 hs24-b42 +34a398422e596f9160335c0376cdfbc13baebb39 jdk7u40-b23 +2efcfec8a6dc4deb84bdfb6d0531556719a118f8 hs24-b43 +a36051465050a52485c29b9eef7135003f528528 jdk7u40-b24 +7eabf05bddea524aa4a00c1fc6f2eba21c06e275 hs24-b44 +a8a071629df4856a44660143c6dd8e7843cdcca2 jdk7u40-b25 +69fecd3e06892e95a32ce4c27f85b1d61e946fc8 hs24-b45 --- old/make/hotspot_version Thu May 16 16:28:15 2013 +++ new/make/hotspot_version Thu May 16 16:28:15 2013 @@ -35,7 +35,7 @@ HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=43 +HS_BUILD_NUMBER=45 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 --- old/make/windows/makefiles/compile.make Thu May 16 16:28:17 2013 +++ new/make/windows/makefiles/compile.make Thu May 16 16:28:17 2013 @@ -52,7 +52,7 @@ # improving the quality of crash log stack traces involving jvm.dll. # These are always used in all compiles -CXX_FLAGS=/nologo /W3 /WX +CXX_FLAGS=$(EXTRA_CFLAGS) /nologo /W3 /WX # Let's add debug information when Full Debug Symbols is enabled !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1" --- old/make/windows/makefiles/defs.make Thu May 16 16:28:19 2013 +++ new/make/windows/makefiles/defs.make Thu May 16 16:28:19 2013 @@ -193,7 +193,7 @@ MAKE_ARGS += JDK_BUILD_NUMBER=$(COOKED_BUILD_NUMBER) endif -NMAKE= MAKEFLAGS= MFLAGS= nmake -NOLOGO +NMAKE= MAKEFLAGS= MFLAGS= EXTRA_CFLAGS="$(EXTRA_CFLAGS)" nmake -NOLOGO ifndef SYSTEM_UNAME SYSTEM_UNAME := $(shell uname) export SYSTEM_UNAME --- old/src/cpu/sparc/vm/templateTable_sparc.cpp Thu May 16 16:28:21 2013 +++ new/src/cpu/sparc/vm/templateTable_sparc.cpp Thu May 16 16:28:21 2013 @@ -62,6 +62,13 @@ noreg /* pre_val */, tmp, true /*preserve_o_regs*/); + // G1 barrier needs uncompressed oop for region cross check. + Register new_val = val; + if (UseCompressedOops && val != G0) { + new_val = tmp; + __ mov(val, new_val); + } + if (index == noreg ) { assert(Assembler::is_simm13(offset), "fix this code"); __ store_heap_oop(val, base, offset); @@ -78,7 +85,7 @@ __ add(base, index, base); } } - __ g1_write_barrier_post(base, val, tmp); + __ g1_write_barrier_post(base, new_val, tmp); } } break; --- old/src/cpu/x86/vm/templateTable_x86_64.cpp Thu May 16 16:28:23 2013 +++ new/src/cpu/x86/vm/templateTable_x86_64.cpp Thu May 16 16:28:23 2013 @@ -156,14 +156,19 @@ if (val == noreg) { __ store_heap_oop_null(Address(rdx, 0)); } else { + // G1 barrier needs uncompressed oop for region cross check. + Register new_val = val; + if (UseCompressedOops) { + new_val = rbx; + __ movptr(new_val, val); + } __ store_heap_oop(Address(rdx, 0), val); __ g1_write_barrier_post(rdx /* store_adr */, - val /* new_val */, + new_val /* new_val */, r15_thread /* thread */, r8 /* tmp */, rbx /* tmp2 */); } - } break; #endif // SERIALGC --- old/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu May 16 16:28:25 2013 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu May 16 16:28:25 2013 @@ -669,7 +669,7 @@ } } -void ConcurrentMark::set_phase(uint active_tasks, bool concurrent) { +void ConcurrentMark::set_concurrency(uint active_tasks) { assert(active_tasks <= _max_task_num, "we should not have more"); _active_tasks = active_tasks; @@ -678,7 +678,11 @@ _terminator = ParallelTaskTerminator((int) active_tasks, _task_queues); _first_overflow_barrier_sync.set_n_workers((int) active_tasks); _second_overflow_barrier_sync.set_n_workers((int) active_tasks); +} +void ConcurrentMark::set_concurrency_and_phase(uint active_tasks, bool concurrent) { + set_concurrency(active_tasks); + _concurrent = concurrent; // We propagate this to all tasks, not just the active ones. for (int i = 0; i < (int) _max_task_num; ++i) @@ -691,7 +695,9 @@ // false before we start remark. At this point we should also be // in a STW phase. assert(!concurrent_marking_in_progress(), "invariant"); - assert(_finger == _heap_end, "only way to get here"); + assert(_finger == _heap_end, + err_msg("only way to get here: _finger: "PTR_FORMAT", _heap_end: "PTR_FORMAT, + _finger, _heap_end)); update_g1_committed(true); } } @@ -859,20 +865,28 @@ gclog_or_tty->print_cr("[%d] leaving first barrier", task_num); } - // let task 0 do this - if (task_num == 0) { - // task 0 is responsible for clearing the global data structures - // We should be here because of an overflow. During STW we should - // not clear the overflow flag since we rely on it being true when - // we exit this method to abort the pause and restart concurent - // marking. - reset_marking_state(concurrent() /* clear_overflow */); - force_overflow()->update(); + // If we're executing the concurrent phase of marking, reset the marking + // state; otherwise the marking state is reset after reference processing, + // during the remark pause. + // If we reset here as a result of an overflow during the remark we will + // see assertion failures from any subsequent set_concurrency_and_phase() + // calls. + if (concurrent()) { + // let the task 0 do this + if (task_num == 0) { + // task 0 is responsible for clearing the global data structures + // We should be here because of an overflow. During STW we should + // not clear the overflow flag since we rely on it being true when + // we exit this method to abort the pause and restart concurent + // marking. + reset_marking_state(true /* clear_overflow */); + force_overflow()->update(); - if (G1Log::fine()) { - gclog_or_tty->date_stamp(PrintGCDateStamps); - gclog_or_tty->stamp(PrintGCTimeStamps); - gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]"); + if (G1Log::fine()) { + gclog_or_tty->date_stamp(PrintGCDateStamps); + gclog_or_tty->stamp(PrintGCTimeStamps); + gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]"); + } } } @@ -892,7 +906,7 @@ if (concurrent()) { ConcurrentGCThread::stsJoin(); } - // at this point everything should be re-initialised and ready to go + // at this point everything should be re-initialized and ready to go if (verbose_low()) { gclog_or_tty->print_cr("[%d] leaving second barrier", task_num); @@ -950,8 +964,8 @@ double mark_step_duration_ms = G1ConcMarkStepDurationMillis; the_task->do_marking_step(mark_step_duration_ms, - true /* do_stealing */, - true /* do_termination */); + true /* do_termination */, + false /* is_serial*/); double end_time_sec = os::elapsedTime(); double end_vtime_sec = os::elapsedVTime(); @@ -1107,8 +1121,8 @@ uint active_workers = MAX2(1U, parallel_marking_threads()); - // Parallel task terminator is set in "set_phase()" - set_phase(active_workers, true /* concurrent */); + // Parallel task terminator is set in "set_concurrency_and_phase()" + set_concurrency_and_phase(active_workers, true /* concurrent */); CMConcurrentMarkingTask markingTask(this, cmThread()); if (use_parallel_marking_threads()) { @@ -1160,12 +1174,22 @@ if (has_overflown()) { // Oops. We overflowed. Restart concurrent marking. _restart_for_overflow = true; - // Clear the marking state because we will be restarting - // marking due to overflowing the global mark stack. - reset_marking_state(); if (G1TraceMarkStackOverflow) { gclog_or_tty->print_cr("\nRemark led to restart for overflow."); } + + // Verify the heap w.r.t. the previous marking bitmap. + if (VerifyDuringGC) { + HandleMark hm; // handle scope + gclog_or_tty->print(" VerifyDuringGC:(overflow)"); + Universe::heap()->prepare_for_verify(); + Universe::verify(/* silent */ false, + /* option */ VerifyOption_G1UsePrevMarking); + } + + // Clear the marking state because we will be restarting + // marking due to overflowing the global mark stack. + reset_marking_state(); } else { // Aggregate the per-task counting data that we have accumulated // while marking. @@ -2051,7 +2075,8 @@ assert(tmp_free_list.is_empty(), "post-condition"); } -// Support closures for reference procssing in G1 +// Supporting Object and Oop closures for reference discovery +// and processing in during marking bool G1CMIsAliveClosure::do_object_b(oop obj) { HeapWord* addr = (HeapWord*)obj; @@ -2059,74 +2084,30 @@ (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_ill(obj)); } -class G1CMKeepAliveClosure: public OopClosure { - G1CollectedHeap* _g1; - ConcurrentMark* _cm; - public: - G1CMKeepAliveClosure(G1CollectedHeap* g1, ConcurrentMark* cm) : - _g1(g1), _cm(cm) { - assert(Thread::current()->is_VM_thread(), "otherwise fix worker id"); - } +// 'Keep Alive' oop closure used by both serial parallel reference processing. +// Uses the CMTask associated with a worker thread (for serial reference +// processing the CMTask for worker 0 is used) to preserve (mark) and +// trace referent objects. +// +// Using the CMTask and embedded local queues avoids having the worker +// threads operating on the global mark stack. This reduces the risk +// of overflowing the stack - which we would rather avoid at this late +// state. Also using the tasks' local queues removes the potential +// of the workers interfering with each other that could occur if +// operating on the global stack. - virtual void do_oop(narrowOop* p) { do_oop_work(p); } - virtual void do_oop( oop* p) { do_oop_work(p); } - - template void do_oop_work(T* p) { - oop obj = oopDesc::load_decode_heap_oop(p); - HeapWord* addr = (HeapWord*)obj; - - if (_cm->verbose_high()) { - gclog_or_tty->print_cr("\t[0] we're looking at location " - "*"PTR_FORMAT" = "PTR_FORMAT, - p, (void*) obj); - } - - if (_g1->is_in_g1_reserved(addr) && _g1->is_obj_ill(obj)) { - _cm->mark_and_count(obj); - _cm->mark_stack_push(obj); - } - } -}; - -class G1CMDrainMarkingStackClosure: public VoidClosure { - ConcurrentMark* _cm; - CMMarkStack* _markStack; - G1CMKeepAliveClosure* _oopClosure; +class G1CMKeepAliveAndDrainClosure: public OopClosure { + ConcurrentMark* _cm; + CMTask* _task; + int _ref_counter_limit; + int _ref_counter; + bool _is_serial; public: - G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMMarkStack* markStack, - G1CMKeepAliveClosure* oopClosure) : - _cm(cm), - _markStack(markStack), - _oopClosure(oopClosure) { } - - void do_void() { - _markStack->drain((OopClosure*)_oopClosure, _cm->nextMarkBitMap(), false); - } -}; - -// 'Keep Alive' closure used by parallel reference processing. -// An instance of this closure is used in the parallel reference processing -// code rather than an instance of G1CMKeepAliveClosure. We could have used -// the G1CMKeepAliveClosure as it is MT-safe. Also reference objects are -// placed on to discovered ref lists once so we can mark and push with no -// need to check whether the object has already been marked. Using the -// G1CMKeepAliveClosure would mean, however, having all the worker threads -// operating on the global mark stack. This means that an individual -// worker would be doing lock-free pushes while it processes its own -// discovered ref list followed by drain call. If the discovered ref lists -// are unbalanced then this could cause interference with the other -// workers. Using a CMTask (and its embedded local data structures) -// avoids that potential interference. -class G1CMParKeepAliveAndDrainClosure: public OopClosure { - ConcurrentMark* _cm; - CMTask* _task; - int _ref_counter_limit; - int _ref_counter; - public: - G1CMParKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task) : - _cm(cm), _task(task), + G1CMKeepAliveAndDrainClosure(ConcurrentMark* cm, CMTask* task, bool is_serial) : + _cm(cm), _task(task), _is_serial(is_serial), _ref_counter_limit(G1RefProcDrainInterval) { assert(_ref_counter_limit > 0, "sanity"); + assert(!_is_serial || _task->task_id() == 0, "only task 0 for serial code"); _ref_counter = _ref_counter_limit; } @@ -2146,23 +2127,27 @@ _ref_counter--; if (_ref_counter == 0) { - // We have dealt with _ref_counter_limit references, pushing them and objects - // reachable from them on to the local stack (and possibly the global stack). - // Call do_marking_step() to process these entries. We call the routine in a - // loop, which we'll exit if there's nothing more to do (i.e. we're done - // with the entries that we've pushed as a result of the deal_with_reference - // calls above) or we overflow. - // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag - // while there may still be some work to do. (See the comment at the - // beginning of CMTask::do_marking_step() for those conditions - one of which - // is reaching the specified time target.) It is only when - // CMTask::do_marking_step() returns without setting the has_aborted() flag - // that the marking has completed. + // We have dealt with _ref_counter_limit references, pushing them + // and objects reachable from them on to the local stack (and + // possibly the global stack). Call CMTask::do_marking_step() to + // process these entries. + // + // We call CMTask::do_marking_step() in a loop, which we'll exit if + // there's nothing more to do (i.e. we're done with the entries that + // were pushed as a result of the CMTask::deal_with_reference() calls + // above) or we overflow. + // + // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() + // flag while there may still be some work to do. (See the comment at + // the beginning of CMTask::do_marking_step() for those conditions - + // one of which is reaching the specified time target.) It is only + // when CMTask::do_marking_step() returns without setting the + // has_aborted() flag that the marking step has completed. do { double mark_step_duration_ms = G1ConcMarkStepDurationMillis; _task->do_marking_step(mark_step_duration_ms, - false /* do_stealing */, - false /* do_termination */); + false /* do_termination */, + _is_serial); } while (_task->has_aborted() && !_cm->has_overflown()); _ref_counter = _ref_counter_limit; } @@ -2174,36 +2159,50 @@ } }; -class G1CMParDrainMarkingStackClosure: public VoidClosure { +// 'Drain' oop closure used by both serial and parallel reference processing. +// Uses the CMTask associated with a given worker thread (for serial +// reference processing the CMtask for worker 0 is used). Calls the +// do_marking_step routine, with an unbelievably large timeout value, +// to drain the marking data structures of the remaining entries +// added by the 'keep alive' oop closure above. + +class G1CMDrainMarkingStackClosure: public VoidClosure { ConcurrentMark* _cm; - CMTask* _task; + CMTask* _task; + bool _is_serial; public: - G1CMParDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task) : - _cm(cm), _task(task) { } + G1CMDrainMarkingStackClosure(ConcurrentMark* cm, CMTask* task, bool is_serial) : + _cm(cm), _task(task), _is_serial(is_serial) { + assert(!_is_serial || _task->task_id() == 0, "only task 0 for serial code"); + } void do_void() { do { if (_cm->verbose_high()) { - gclog_or_tty->print_cr("\t[%d] Drain: Calling do marking_step", - _task->task_id()); + gclog_or_tty->print_cr("\t[%d] Drain: Calling do_marking_step - serial: %s", + _task->task_id(), BOOL_TO_STR(_is_serial)); } - // We call CMTask::do_marking_step() to completely drain the local and - // global marking stacks. The routine is called in a loop, which we'll - // exit if there's nothing more to do (i.e. we'completely drained the - // entries that were pushed as a result of applying the - // G1CMParKeepAliveAndDrainClosure to the entries on the discovered ref - // lists above) or we overflow the global marking stack. - // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() flag - // while there may still be some work to do. (See the comment at the - // beginning of CMTask::do_marking_step() for those conditions - one of which - // is reaching the specified time target.) It is only when - // CMTask::do_marking_step() returns without setting the has_aborted() flag - // that the marking has completed. + // We call CMTask::do_marking_step() to completely drain the local + // and global marking stacks of entries pushed by the 'keep alive' + // oop closure (an instance of G1CMKeepAliveAndDrainClosure above). + // + // CMTask::do_marking_step() is called in a loop, which we'll exit + // if there's nothing more to do (i.e. we'completely drained the + // entries that were pushed as a a result of applying the 'keep alive' + // closure to the entries on the discovered ref lists) or we overflow + // the global marking stack. + // + // Note: CMTask::do_marking_step() can set the CMTask::has_aborted() + // flag while there may still be some work to do. (See the comment at + // the beginning of CMTask::do_marking_step() for those conditions - + // one of which is reaching the specified time target.) It is only + // when CMTask::do_marking_step() returns without setting the + // has_aborted() flag that the marking step has completed. _task->do_marking_step(1000000000.0 /* something very large */, - true /* do_stealing */, - true /* do_termination */); + true /* do_termination */, + _is_serial); } while (_task->has_aborted() && !_cm->has_overflown()); } }; @@ -2242,13 +2241,16 @@ G1CollectedHeap* g1h, ConcurrentMark* cm) : AbstractGangTask("Process reference objects in parallel"), - _proc_task(proc_task), _g1h(g1h), _cm(cm) { } + _proc_task(proc_task), _g1h(g1h), _cm(cm) { + ReferenceProcessor* rp = _g1h->ref_processor_cm(); + assert(rp->processing_is_mt(), "shouldn't be here otherwise"); + } virtual void work(uint worker_id) { - CMTask* marking_task = _cm->task(worker_id); + CMTask* task = _cm->task(worker_id); G1CMIsAliveClosure g1_is_alive(_g1h); - G1CMParKeepAliveAndDrainClosure g1_par_keep_alive(_cm, marking_task); - G1CMParDrainMarkingStackClosure g1_par_drain(_cm, marking_task); + G1CMKeepAliveAndDrainClosure g1_par_keep_alive(_cm, task, false /* is_serial */); + G1CMDrainMarkingStackClosure g1_par_drain(_cm, task, false /* is_serial */); _proc_task.work(worker_id, g1_is_alive, g1_par_keep_alive, g1_par_drain); } @@ -2256,12 +2258,15 @@ void G1CMRefProcTaskExecutor::execute(ProcessTask& proc_task) { assert(_workers != NULL, "Need parallel worker threads."); + assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm); - // We need to reset the phase for each task execution so that - // the termination protocol of CMTask::do_marking_step works. - _cm->set_phase(_active_workers, false /* concurrent */); + // We need to reset the concurrency level before each + // proxy task execution, so that the termination protocol + // and overflow handling in CMTask::do_marking_step() knows + // how many workers to wait for. + _cm->set_concurrency(_active_workers); _g1h->set_par_threads(_active_workers); _workers->run_task(&proc_task_proxy); _g1h->set_par_threads(0); @@ -2283,9 +2288,17 @@ void G1CMRefProcTaskExecutor::execute(EnqueueTask& enq_task) { assert(_workers != NULL, "Need parallel worker threads."); + assert(_g1h->ref_processor_cm()->processing_is_mt(), "processing is not MT"); G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task); + // Not strictly necessary but... + // + // We need to reset the concurrency level before each + // proxy task execution, so that the termination protocol + // and overflow handling in CMTask::do_marking_step() knows + // how many workers to wait for. + _cm->set_concurrency(_active_workers); _g1h->set_par_threads(_active_workers); _workers->run_task(&enq_task_proxy); _g1h->set_par_threads(0); @@ -2292,6 +2305,16 @@ } void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { + if (has_overflown()) { + // Skip processing the discovered references if we have + // overflown the global marking stack. Reference objects + // only get discovered once so it is OK to not + // de-populate the discovered reference lists. We could have, + // but the only benefit would be that, when marking restarts, + // less reference objects are discovered. + return; + } + ResourceMark rm; HandleMark hm; @@ -2313,65 +2336,78 @@ // See the comment in G1CollectedHeap::ref_processing_init() // about how reference processing currently works in G1. - // Process weak references. + // Set the soft reference policy rp->setup_policy(clear_all_soft_refs); assert(_markStack.isEmpty(), "mark stack should be empty"); - G1CMKeepAliveClosure g1_keep_alive(g1h, this); - G1CMDrainMarkingStackClosure - g1_drain_mark_stack(this, &_markStack, &g1_keep_alive); + // Instances of the 'Keep Alive' and 'Complete GC' closures used + // in serial reference processing. Note these closures are also + // used for serially processing (by the the current thread) the + // JNI references during parallel reference processing. + // + // These closures do not need to synchronize with the worker + // threads involved in parallel reference processing as these + // instances are executed serially by the current thread (e.g. + // reference processing is not multi-threaded and is thus + // performed by the current thread instead of a gang worker). + // + // The gang tasks involved in parallel reference procssing create + // their own instances of these closures, which do their own + // synchronization among themselves. + G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0), true /* is_serial */); + G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), true /* is_serial */); - // We use the work gang from the G1CollectedHeap and we utilize all - // the worker threads. - uint active_workers = g1h->workers() ? g1h->workers()->active_workers() : 1U; + // We need at least one active thread. If reference processing + // is not multi-threaded we use the current (VMThread) thread, + // otherwise we use the work gang from the G1CollectedHeap and + // we utilize all the worker threads we can. + bool processing_is_mt = rp->processing_is_mt() && g1h->workers() != NULL; + uint active_workers = (processing_is_mt ? g1h->workers()->active_workers() : 1U); active_workers = MAX2(MIN2(active_workers, _max_task_num), 1U); + // Parallel processing task executor. G1CMRefProcTaskExecutor par_task_executor(g1h, this, g1h->workers(), active_workers); + AbstractRefProcTaskExecutor* executor = (processing_is_mt ? &par_task_executor : NULL); ReferenceProcessorStats stats; - if (rp->processing_is_mt()) { - // Set the degree of MT here. If the discovery is done MT, there - // may have been a different number of threads doing the discovery - // and a different number of discovered lists may have Ref objects. - // That is OK as long as the Reference lists are balanced (see - // balance_all_queues() and balance_queues()). - rp->set_active_mt_degree(active_workers); - stats = rp->process_discovered_references(&g1_is_alive, - &g1_keep_alive, - &g1_drain_mark_stack, - &par_task_executor, - g1h->gc_timer_cm()); + // Set the concurrency level. The phase was already set prior to + // executing the remark task. + set_concurrency(active_workers); - // The work routines of the parallel keep_alive and drain_marking_stack - // will set the has_overflown flag if we overflow the global marking - // stack. - } else { - stats = rp->process_discovered_references(&g1_is_alive, - &g1_keep_alive, - &g1_drain_mark_stack, - NULL, - g1h->gc_timer_cm()); - } + // Set the degree of MT processing here. If the discovery was done MT, + // the number of threads involved during discovery could differ from + // the number of active workers. This is OK as long as the discovered + // Reference lists are balanced (see balance_all_queues() and balance_queues()). + rp->set_active_mt_degree(active_workers); + // Process the weak references. + stats = rp->process_discovered_references(&g1_is_alive, + &g1_keep_alive, + &g1_drain_mark_stack, + executor, + g1h->gc_timer_cm()); + + // The do_oop work routines of the keep_alive and drain_marking_stack + // oop closures will set the has_overflown flag if we overflow the + // global marking stack. + g1h->gc_tracer_cm()->report_gc_reference_stats(stats); assert(_markStack.overflow() || _markStack.isEmpty(), "mark stack should be empty (unless it overflowed)"); + if (_markStack.overflow()) { - // Should have been done already when we tried to push an + // This should have been done already when we tried to push an // entry on to the global mark stack. But let's do it again. set_has_overflown(); } - if (rp->processing_is_mt()) { - assert(rp->num_q() == active_workers, "why not"); - rp->enqueue_discovered_references(&par_task_executor); - } else { - rp->enqueue_discovered_references(); - } + assert(rp->num_q() == active_workers, "why not"); + rp->enqueue_discovered_references(executor); + rp->verify_no_references_recorded(); assert(!rp->discovery_enabled(), "Post condition"); } @@ -2390,8 +2426,8 @@ class CMRemarkTask: public AbstractGangTask { private: - ConcurrentMark *_cm; - + ConcurrentMark* _cm; + bool _is_serial; public: void work(uint worker_id) { // Since all available tasks are actually started, we should @@ -2401,8 +2437,8 @@ task->record_start_time(); do { task->do_marking_step(1000000000.0 /* something very large */, - true /* do_stealing */, - true /* do_termination */); + true /* do_termination */, + _is_serial); } while (task->has_aborted() && !_cm->has_overflown()); // If we overflow, then we do not want to restart. We instead // want to abort remark and do concurrent marking again. @@ -2410,8 +2446,8 @@ } } - CMRemarkTask(ConcurrentMark* cm, int active_workers) : - AbstractGangTask("Par Remark"), _cm(cm) { + CMRemarkTask(ConcurrentMark* cm, int active_workers, bool is_serial) : + AbstractGangTask("Par Remark"), _cm(cm), _is_serial(is_serial) { _cm->terminator()->reset_for_reuse(active_workers); } }; @@ -2432,30 +2468,40 @@ active_workers = (uint) ParallelGCThreads; g1h->workers()->set_active_workers(active_workers); } - set_phase(active_workers, false /* concurrent */); + set_concurrency_and_phase(active_workers, false /* concurrent */); // Leave _parallel_marking_threads at it's // value originally calculated in the ConcurrentMark // constructor and pass values of the active workers // through the gang in the task. - CMRemarkTask remarkTask(this, active_workers); + CMRemarkTask remarkTask(this, active_workers, false /* is_serial */); + // We will start all available threads, even if we decide that the + // active_workers will be fewer. The extra ones will just bail out + // immediately. g1h->set_par_threads(active_workers); g1h->workers()->run_task(&remarkTask); g1h->set_par_threads(0); } else { G1CollectedHeap::StrongRootsScope srs(g1h); - // this is remark, so we'll use up all available threads uint active_workers = 1; - set_phase(active_workers, false /* concurrent */); + set_concurrency_and_phase(active_workers, false /* concurrent */); - CMRemarkTask remarkTask(this, active_workers); - // We will start all available threads, even if we decide that the - // active_workers will be fewer. The extra ones will just bail out - // immediately. + // Note - if there's no work gang then the VMThread will be + // the thread to execute the remark - serially. We have + // to pass true for the is_serial parameter so that + // CMTask::do_marking_step() doesn't enter the sync + // barriers in the event of an overflow. Doing so will + // cause an assert that the current thread is not a + // concurrent GC thread. + CMRemarkTask remarkTask(this, active_workers, true /* is_serial*/); remarkTask.work(0); } SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); - guarantee(satb_mq_set.completed_buffers_num() == 0, "invariant"); + guarantee(has_overflown() || + satb_mq_set.completed_buffers_num() == 0, + err_msg("Invariant: has_overflown = %s, num buffers = %d", + BOOL_TO_STR(has_overflown()), + satb_mq_set.completed_buffers_num())); print_stats(); @@ -3776,8 +3822,8 @@ /***************************************************************************** - The do_marking_step(time_target_ms) method is the building block - of the parallel marking framework. It can be called in parallel + The do_marking_step(time_target_ms, ...) method is the building + block of the parallel marking framework. It can be called in parallel with other invocations of do_marking_step() on different tasks (but only one per task, obviously) and concurrently with the mutator threads, or during remark, hence it eliminates the need @@ -3787,7 +3833,7 @@ pauses too, since do_marking_step() ensures that it aborts before it needs to yield. - The data structures that is uses to do marking work are the + The data structures that it uses to do marking work are the following: (1) Marking Bitmap. If there are gray objects that appear only @@ -3836,7 +3882,7 @@ (2) When a global overflow (on the global stack) has been triggered. Before the task aborts, it will actually sync up with the other tasks to ensure that all the marking data structures - (local queues, stacks, fingers etc.) are re-initialised so that + (local queues, stacks, fingers etc.) are re-initialized so that when do_marking_step() completes, the marking phase can immediately restart. @@ -3873,11 +3919,25 @@ place, it was natural to piggy-back all the other conditions on it too and not constantly check them throughout the code. + If do_termination is true then do_marking_step will enter its + termination protocol. + + The value of is_serial must be true when do_marking_step is being + called serially (i.e. by the VMThread) and do_marking_step should + skip any synchronization in the termination and overflow code. + Examples include the serial remark code and the serial reference + processing closures. + + The value of is_serial must be false when do_marking_step is + being called by any of the worker threads in a work gang. + Examples include the concurrent marking code (CMMarkingTask), + the MT remark code, and the MT reference processing closures. + *****************************************************************************/ void CMTask::do_marking_step(double time_target_ms, - bool do_stealing, - bool do_termination) { + bool do_termination, + bool is_serial) { assert(time_target_ms >= 1.0, "minimum granularity is 1ms"); assert(concurrent() == _cm->concurrent(), "they should be the same"); @@ -3898,6 +3958,12 @@ _start_time_ms = os::elapsedVTime() * 1000.0; statsOnly( _interval_start_time_ms = _start_time_ms ); + // If do_stealing is true then do_marking_step will attempt to + // steal work from the other CMTasks. It only makes sense to + // enable stealing when the termination protocol is enabled + // and do_marking_step() is not being called serially. + bool do_stealing = do_termination && !is_serial; + double diff_prediction_ms = g1_policy->get_new_prediction(&_marking_step_diffs_ms); _time_target_ms = time_target_ms - diff_prediction_ms; @@ -4138,10 +4204,12 @@ } _termination_start_time_ms = os::elapsedVTime() * 1000.0; + // The CMTask class also extends the TerminatorTerminator class, // hence its should_exit_termination() method will also decide // whether to exit the termination protocol or not. - bool finished = _cm->terminator()->offer_termination(this); + bool finished = (is_serial || + _cm->terminator()->offer_termination(this)); double termination_end_time_ms = os::elapsedVTime() * 1000.0; _termination_time_ms += termination_end_time_ms - _termination_start_time_ms; @@ -4221,20 +4289,28 @@ gclog_or_tty->print_cr("[%d] detected overflow", _task_id); } - _cm->enter_first_sync_barrier(_task_id); - // When we exit this sync barrier we know that all tasks have - // stopped doing marking work. So, it's now safe to - // re-initialise our data structures. At the end of this method, - // task 0 will clear the global data structures. + if (!is_serial) { + // We only need to enter the sync barrier if being called + // from a parallel context + _cm->enter_first_sync_barrier(_task_id); + // When we exit this sync barrier we know that all tasks have + // stopped doing marking work. So, it's now safe to + // re-initialise our data structures. At the end of this method, + // task 0 will clear the global data structures. + } + statsOnly( ++_aborted_overflow ); // We clear the local state of this task... clear_region_fields(); - // ...and enter the second barrier. - _cm->enter_second_sync_barrier(_task_id); - // At this point everything has bee re-initialised and we're + if (!is_serial) { + // ...and enter the second barrier. + _cm->enter_second_sync_barrier(_task_id); + } + // At this point, if we're during the concurrent phase of + // marking, everything has been re-initialized and we're // ready to restart. } --- old/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu May 16 16:28:27 2013 +++ new/src/share/vm/gc_implementation/g1/concurrentMark.hpp Thu May 16 16:28:27 2013 @@ -354,8 +354,8 @@ friend class CalcLiveObjectsClosure; friend class G1CMRefProcTaskProxy; friend class G1CMRefProcTaskExecutor; - friend class G1CMParKeepAliveAndDrainClosure; - friend class G1CMParDrainMarkingStackClosure; + friend class G1CMKeepAliveAndDrainClosure; + friend class G1CMDrainMarkingStackClosure; protected: ConcurrentMarkThread* _cmThread; // the thread doing the work @@ -470,9 +470,12 @@ // structures are initialised to a sensible and predictable state. void set_non_marking_state(); + // Called to indicate how many threads are currently active. + void set_concurrency(uint active_tasks); + // It should be called to indicate which phase we're in (concurrent // mark or remark) and how many threads are currently active. - void set_phase(uint active_tasks, bool concurrent); + void set_concurrency_and_phase(uint active_tasks, bool concurrent); // prints all gathered CM-related statistics void print_stats(); @@ -1117,7 +1120,9 @@ // trying not to exceed the given duration. However, it might exit // prematurely, according to some conditions (i.e. SATB buffers are // available for processing). - void do_marking_step(double target_ms, bool do_stealing, bool do_termination); + void do_marking_step(double target_ms, + bool do_termination, + bool is_serial); // These two calls start and stop the timer void record_start_time() { --- old/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu May 16 16:28:29 2013 +++ new/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu May 16 16:28:29 2013 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1313,233 +1313,239 @@ gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); - GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL); - TraceCollectorStats tcs(g1mm()->full_collection_counters()); - TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); + { + GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL); + TraceCollectorStats tcs(g1mm()->full_collection_counters()); + TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); - double start = os::elapsedTime(); - g1_policy()->record_full_collection_start(); + double start = os::elapsedTime(); + g1_policy()->record_full_collection_start(); - // Note: When we have a more flexible GC logging framework that - // allows us to add optional attributes to a GC log record we - // could consider timing and reporting how long we wait in the - // following two methods. - wait_while_free_regions_coming(); - // If we start the compaction before the CM threads finish - // scanning the root regions we might trip them over as we'll - // be moving objects / updating references. So let's wait until - // they are done. By telling them to abort, they should complete - // early. - _cm->root_regions()->abort(); - _cm->root_regions()->wait_until_scan_finished(); - append_secondary_free_list_if_not_empty_with_lock(); + // Note: When we have a more flexible GC logging framework that + // allows us to add optional attributes to a GC log record we + // could consider timing and reporting how long we wait in the + // following two methods. + wait_while_free_regions_coming(); + // If we start the compaction before the CM threads finish + // scanning the root regions we might trip them over as we'll + // be moving objects / updating references. So let's wait until + // they are done. By telling them to abort, they should complete + // early. + _cm->root_regions()->abort(); + _cm->root_regions()->wait_until_scan_finished(); + append_secondary_free_list_if_not_empty_with_lock(); - gc_prologue(true); - increment_total_collections(true /* full gc */); - increment_old_marking_cycles_started(); + gc_prologue(true); + increment_total_collections(true /* full gc */); + increment_old_marking_cycles_started(); - size_t g1h_prev_used = used(); - assert(used() == recalculate_used(), "Should be equal"); + assert(used() == recalculate_used(), "Should be equal"); - verify_before_gc(); + verify_before_gc(); - pre_full_gc_dump(gc_timer); + pre_full_gc_dump(gc_timer); - COMPILER2_PRESENT(DerivedPointerTable::clear()); + COMPILER2_PRESENT(DerivedPointerTable::clear()); - // Disable discovery and empty the discovered lists - // for the CM ref processor. - ref_processor_cm()->disable_discovery(); - ref_processor_cm()->abandon_partial_discovery(); - ref_processor_cm()->verify_no_references_recorded(); + // Disable discovery and empty the discovered lists + // for the CM ref processor. + ref_processor_cm()->disable_discovery(); + ref_processor_cm()->abandon_partial_discovery(); + ref_processor_cm()->verify_no_references_recorded(); - // Abandon current iterations of concurrent marking and concurrent - // refinement, if any are in progress. We have to do this before - // wait_until_scan_finished() below. - concurrent_mark()->abort(); + // Abandon current iterations of concurrent marking and concurrent + // refinement, if any are in progress. We have to do this before + // wait_until_scan_finished() below. + concurrent_mark()->abort(); - // Make sure we'll choose a new allocation region afterwards. - release_mutator_alloc_region(); - abandon_gc_alloc_regions(); - g1_rem_set()->cleanupHRRS(); + // Make sure we'll choose a new allocation region afterwards. + release_mutator_alloc_region(); + abandon_gc_alloc_regions(); + g1_rem_set()->cleanupHRRS(); - // We should call this after we retire any currently active alloc - // regions so that all the ALLOC / RETIRE events are generated - // before the start GC event. - _hr_printer.start_gc(true /* full */, (size_t) total_collections()); + // We should call this after we retire any currently active alloc + // regions so that all the ALLOC / RETIRE events are generated + // before the start GC event. + _hr_printer.start_gc(true /* full */, (size_t) total_collections()); - // We may have added regions to the current incremental collection - // set between the last GC or pause and now. We need to clear the - // incremental collection set and then start rebuilding it afresh - // after this full GC. - abandon_collection_set(g1_policy()->inc_cset_head()); - g1_policy()->clear_incremental_cset(); - g1_policy()->stop_incremental_cset_building(); + // We may have added regions to the current incremental collection + // set between the last GC or pause and now. We need to clear the + // incremental collection set and then start rebuilding it afresh + // after this full GC. + abandon_collection_set(g1_policy()->inc_cset_head()); + g1_policy()->clear_incremental_cset(); + g1_policy()->stop_incremental_cset_building(); - tear_down_region_sets(false /* free_list_only */); - g1_policy()->set_gcs_are_young(true); + tear_down_region_sets(false /* free_list_only */); + g1_policy()->set_gcs_are_young(true); - // See the comments in g1CollectedHeap.hpp and - // G1CollectedHeap::ref_processing_init() about - // how reference processing currently works in G1. + // See the comments in g1CollectedHeap.hpp and + // G1CollectedHeap::ref_processing_init() about + // how reference processing currently works in G1. - // Temporarily make discovery by the STW ref processor single threaded (non-MT). - ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false); + // Temporarily make discovery by the STW ref processor single threaded (non-MT). + ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false); - // Temporarily clear the STW ref processor's _is_alive_non_header field. - ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL); + // Temporarily clear the STW ref processor's _is_alive_non_header field. + ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL); - ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); - ref_processor_stw()->setup_policy(do_clear_all_soft_refs); + ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); + ref_processor_stw()->setup_policy(do_clear_all_soft_refs); - // Do collection work - { - HandleMark hm; // Discard invalid handles created during gc - G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs); - } + // Do collection work + { + HandleMark hm; // Discard invalid handles created during gc + G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs); + } - assert(free_regions() == 0, "we should not have added any free regions"); - rebuild_region_sets(false /* free_list_only */); + assert(free_regions() == 0, "we should not have added any free regions"); + rebuild_region_sets(false /* free_list_only */); - // Enqueue any discovered reference objects that have - // not been removed from the discovered lists. - ref_processor_stw()->enqueue_discovered_references(); + // Enqueue any discovered reference objects that have + // not been removed from the discovered lists. + ref_processor_stw()->enqueue_discovered_references(); - COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); + COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); - MemoryService::track_memory_usage(); + MemoryService::track_memory_usage(); - verify_after_gc(); + verify_after_gc(); - assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); - ref_processor_stw()->verify_no_references_recorded(); + assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); + ref_processor_stw()->verify_no_references_recorded(); - // Note: since we've just done a full GC, concurrent - // marking is no longer active. Therefore we need not - // re-enable reference discovery for the CM ref processor. - // That will be done at the start of the next marking cycle. - assert(!ref_processor_cm()->discovery_enabled(), "Postcondition"); - ref_processor_cm()->verify_no_references_recorded(); + // Note: since we've just done a full GC, concurrent + // marking is no longer active. Therefore we need not + // re-enable reference discovery for the CM ref processor. + // That will be done at the start of the next marking cycle. + assert(!ref_processor_cm()->discovery_enabled(), "Postcondition"); + ref_processor_cm()->verify_no_references_recorded(); - reset_gc_time_stamp(); - // Since everything potentially moved, we will clear all remembered - // sets, and clear all cards. Later we will rebuild remembered - // sets. We will also reset the GC time stamps of the regions. - clear_rsets_post_compaction(); - check_gc_time_stamps(); + reset_gc_time_stamp(); + // Since everything potentially moved, we will clear all remembered + // sets, and clear all cards. Later we will rebuild remembered + // sets. We will also reset the GC time stamps of the regions. + clear_rsets_post_compaction(); + check_gc_time_stamps(); - // Resize the heap if necessary. - resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); + // Resize the heap if necessary. + resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); - if (_hr_printer.is_active()) { - // We should do this after we potentially resize the heap so - // that all the COMMIT / UNCOMMIT events are generated before - // the end GC event. + if (_hr_printer.is_active()) { + // We should do this after we potentially resize the heap so + // that all the COMMIT / UNCOMMIT events are generated before + // the end GC event. - print_hrs_post_compaction(); - _hr_printer.end_gc(true /* full */, (size_t) total_collections()); - } + print_hrs_post_compaction(); + _hr_printer.end_gc(true /* full */, (size_t) total_collections()); + } - if (_cg1r->use_cache()) { - _cg1r->clear_and_record_card_counts(); - _cg1r->clear_hot_cache(); - } + if (_cg1r->use_cache()) { + _cg1r->clear_and_record_card_counts(); + _cg1r->clear_hot_cache(); + } - // Rebuild remembered sets of all regions. - if (G1CollectedHeap::use_parallel_gc_threads()) { - uint n_workers = - AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(), - workers()->active_workers(), - Threads::number_of_non_daemon_threads()); - assert(UseDynamicNumberOfGCThreads || - n_workers == workers()->total_workers(), - "If not dynamic should be using all the workers"); - workers()->set_active_workers(n_workers); - // Set parallel threads in the heap (_n_par_threads) only - // before a parallel phase and always reset it to 0 after - // the phase so that the number of parallel threads does - // no get carried forward to a serial phase where there - // may be code that is "possibly_parallel". - set_par_threads(n_workers); + // Rebuild remembered sets of all regions. + if (G1CollectedHeap::use_parallel_gc_threads()) { + uint n_workers = + AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(), + workers()->active_workers(), + Threads::number_of_non_daemon_threads()); + assert(UseDynamicNumberOfGCThreads || + n_workers == workers()->total_workers(), + "If not dynamic should be using all the workers"); + workers()->set_active_workers(n_workers); + // Set parallel threads in the heap (_n_par_threads) only + // before a parallel phase and always reset it to 0 after + // the phase so that the number of parallel threads does + // no get carried forward to a serial phase where there + // may be code that is "possibly_parallel". + set_par_threads(n_workers); - ParRebuildRSTask rebuild_rs_task(this); - assert(check_heap_region_claim_values( - HeapRegion::InitialClaimValue), "sanity check"); - assert(UseDynamicNumberOfGCThreads || - workers()->active_workers() == workers()->total_workers(), - "Unless dynamic should use total workers"); - // Use the most recent number of active workers - assert(workers()->active_workers() > 0, - "Active workers not properly set"); - set_par_threads(workers()->active_workers()); - workers()->run_task(&rebuild_rs_task); - set_par_threads(0); - assert(check_heap_region_claim_values( - HeapRegion::RebuildRSClaimValue), "sanity check"); - reset_heap_region_claim_values(); - } else { - RebuildRSOutOfRegionClosure rebuild_rs(this); - heap_region_iterate(&rebuild_rs); - } + ParRebuildRSTask rebuild_rs_task(this); + assert(check_heap_region_claim_values( + HeapRegion::InitialClaimValue), "sanity check"); + assert(UseDynamicNumberOfGCThreads || + workers()->active_workers() == workers()->total_workers(), + "Unless dynamic should use total workers"); + // Use the most recent number of active workers + assert(workers()->active_workers() > 0, + "Active workers not properly set"); + set_par_threads(workers()->active_workers()); + workers()->run_task(&rebuild_rs_task); + set_par_threads(0); + assert(check_heap_region_claim_values( + HeapRegion::RebuildRSClaimValue), "sanity check"); + reset_heap_region_claim_values(); + } else { + RebuildRSOutOfRegionClosure rebuild_rs(this); + heap_region_iterate(&rebuild_rs); + } - if (G1Log::fine()) { - print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity()); - } + if (true) { // FIXME + // Ask the permanent generation to adjust size for full collections + perm()->compute_new_size(); + } - if (true) { // FIXME - // Ask the permanent generation to adjust size for full collections - perm()->compute_new_size(); - } +#ifdef TRACESPINNING + ParallelTaskTerminator::print_termination_counts(); +#endif - // Start a new incremental collection set for the next pause - assert(g1_policy()->collection_set() == NULL, "must be"); - g1_policy()->start_incremental_cset_building(); + // Discard all rset updates + JavaThread::dirty_card_queue_set().abandon_logs(); + assert(!G1DeferredRSUpdate + || (G1DeferredRSUpdate && + (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any"); - // Clear the _cset_fast_test bitmap in anticipation of adding - // regions to the incremental collection set for the next - // evacuation pause. - clear_cset_fast_test(); + _young_list->reset_sampled_info(); + // At this point there should be no regions in the + // entire heap tagged as young. + assert(check_young_list_empty(true /* check_heap */), + "young list should be empty at this point"); - init_mutator_alloc_region(); + // Update the number of full collections that have been completed. + increment_old_marking_cycles_completed(false /* concurrent */); - double end = os::elapsedTime(); - g1_policy()->record_full_collection_end(); + _hrs.verify_optional(); + verify_region_sets_optional(); -#ifdef TRACESPINNING - ParallelTaskTerminator::print_termination_counts(); -#endif + // Start a new incremental collection set for the next pause + assert(g1_policy()->collection_set() == NULL, "must be"); + g1_policy()->start_incremental_cset_building(); - gc_epilogue(true); + // Clear the _cset_fast_test bitmap in anticipation of adding + // regions to the incremental collection set for the next + // evacuation pause. + clear_cset_fast_test(); - // Discard all rset updates - JavaThread::dirty_card_queue_set().abandon_logs(); - assert(!G1DeferredRSUpdate - || (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any"); + init_mutator_alloc_region(); - _young_list->reset_sampled_info(); - // At this point there should be no regions in the - // entire heap tagged as young. - assert( check_young_list_empty(true /* check_heap */), - "young list should be empty at this point"); + double end = os::elapsedTime(); + g1_policy()->record_full_collection_end(); - // Update the number of full collections that have been completed. - increment_old_marking_cycles_completed(false /* concurrent */); + if (G1Log::fine()) { + g1_policy()->print_heap_transition(); + } - _hrs.verify_optional(); - verify_region_sets_optional(); + // We must call G1MonitoringSupport::update_sizes() in the same scoping level + // as an active TraceMemoryManagerStats object (i.e. before the destructor for the + // TraceMemoryManagerStats is called) so that the G1 memory pools are updated + // before any GC notifications are raised. + g1mm()->update_sizes(); + gc_epilogue(true); + } + + if (G1Log::finer()) { + g1_policy()->print_detailed_heap_transition(); + } + print_heap_after_gc(); trace_heap_after_gc(gc_tracer); - // We must call G1MonitoringSupport::update_sizes() in the same scoping level - // as an active TraceMemoryManagerStats object (i.e. before the destructor for the - // TraceMemoryManagerStats is called) so that the G1 memory pools are updated - // before any GC notifications are raised. - g1mm()->update_sizes(); + post_full_gc_dump(gc_timer); } - post_full_gc_dump(gc_timer); - gc_timer->register_gc_end(os::elapsed_counter()); gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); @@ -2018,8 +2024,12 @@ // Since max_byte_size is aligned to the size of a heap region (checked // above), we also need to align the perm gen size as it might not be. - const size_t total_reserved = max_byte_size + - align_size_up(pgs->max_size(), HeapRegion::GrainBytes); + size_t total_reserved = 0; + + total_reserved = add_and_check_overflow(total_reserved, max_byte_size); + size_t pg_max_size = (size_t) align_size_up(pgs->max_size(), HeapRegion::GrainBytes); + total_reserved = add_and_check_overflow(total_reserved, pg_max_size); + Universe::check_alignment(total_reserved, HeapRegion::GrainBytes, "g1 heap and perm"); char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); @@ -3357,12 +3367,12 @@ void G1CollectedHeap::verify(bool silent, VerifyOption vo) { - if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { + if (SafepointSynchronize::is_at_safepoint()) { if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } VerifyRootsClosure rootsCl(vo); assert(Thread::current()->is_VM_thread(), - "Expected to be executed serially by the VM thread at this point"); + "Expected to be executed serially by the VM thread at this point"); CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); @@ -3455,7 +3465,8 @@ } guarantee(!failures, "there should not have been any failures"); } else { - if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) "); + if (!silent) + gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) "); } } @@ -3917,7 +3928,6 @@ // The elapsed time induced by the start time below deliberately elides // the possible verification above. double sample_start_time_sec = os::elapsedTime(); - size_t start_used_bytes = used(); #if YOUNG_LIST_VERBOSE gclog_or_tty->print_cr("\nBefore recording pause start.\nYoung_list:"); @@ -3925,8 +3935,7 @@ g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); #endif // YOUNG_LIST_VERBOSE - g1_policy()->record_collection_pause_start(sample_start_time_sec, - start_used_bytes); + g1_policy()->record_collection_pause_start(sample_start_time_sec); double scan_wait_start = os::elapsedTime(); // We have to wait until the CM threads finish scanning the --- old/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu May 16 16:28:32 2013 +++ new/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Thu May 16 16:28:31 2013 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -406,7 +406,6 @@ } _free_regions_at_end_of_collection = _g1->free_regions(); update_young_list_target_length(); - _prev_eden_capacity = _young_list_target_length * HeapRegion::GrainBytes; // We may immediately start allocating regions and placing them on the // collection set list. Initialize the per-collection set info @@ -746,6 +745,7 @@ void G1CollectorPolicy::record_full_collection_start() { _full_collection_start_sec = os::elapsedTime(); + record_heap_size_info_at_start(); // Release the future to-space so that it is available for compaction into. _g1->set_full_collection(); } @@ -788,8 +788,7 @@ _stop_world_start = os::elapsedTime(); } -void G1CollectorPolicy::record_collection_pause_start(double start_time_sec, - size_t start_used) { +void G1CollectorPolicy::record_collection_pause_start(double start_time_sec) { // We only need to do this here as the policy will only be applied // to the GC we're about to start. so, no point is calculating this // every time we calculate / recalculate the target young length. @@ -803,19 +802,14 @@ _trace_gen0_time_data.record_start_collection(s_w_t_ms); _stop_world_start = 0.0; + record_heap_size_info_at_start(); + phase_times()->record_cur_collection_start_sec(start_time_sec); - _cur_collection_pause_used_at_start_bytes = start_used; - _cur_collection_pause_used_regions_at_start = _g1->used_regions(); _pending_cards = _g1->pending_card_num(); _collection_set_bytes_used_before = 0; _bytes_copied_during_gc = 0; - YoungList* young_list = _g1->young_list(); - _eden_bytes_before_gc = young_list->eden_used_bytes(); - _survivor_bytes_before_gc = young_list->survivor_used_bytes(); - _capacity_before_gc = _g1->capacity(); - _last_gc_was_young = false; // do that for any other surv rate groups @@ -1156,6 +1150,21 @@ byte_size_in_proper_unit((double)(bytes)), \ proper_unit_for_byte_size((bytes)) +void G1CollectorPolicy::record_heap_size_info_at_start() { + YoungList* young_list = _g1->young_list(); + _eden_bytes_before_gc = young_list->eden_used_bytes(); + _survivor_bytes_before_gc = young_list->survivor_used_bytes(); + _capacity_before_gc = _g1->capacity(); + + _cur_collection_pause_used_at_start_bytes = _g1->used(); + _cur_collection_pause_used_regions_at_start = _g1->used_regions(); + + size_t eden_capacity_before_gc = + (_young_list_target_length * HeapRegion::GrainBytes) - _survivor_bytes_before_gc; + + _prev_eden_capacity = eden_capacity_before_gc; +} + void G1CollectorPolicy::print_heap_transition() { _g1->print_size_transition(gclog_or_tty, _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity()); @@ -1186,8 +1195,6 @@ EXT_SIZE_PARAMS(_capacity_before_gc), EXT_SIZE_PARAMS(used), EXT_SIZE_PARAMS(capacity)); - - _prev_eden_capacity = eden_capacity; } void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time, --- old/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu May 16 16:28:34 2013 +++ new/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Thu May 16 16:28:34 2013 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -672,34 +672,36 @@ bool need_to_start_conc_mark(const char* source, size_t alloc_word_size = 0); - // Update the heuristic info to record a collection pause of the given - // start time, where the given number of bytes were used at the start. - // This may involve changing the desired size of a collection set. + // Record the start and end of an evacuation pause. + void record_collection_pause_start(double start_time_sec); + void record_collection_pause_end(double pause_time_ms, EvacuationInfo& evacuation_info); - void record_stop_world_start(); + // Record the start and end of a full collection. + void record_full_collection_start(); + void record_full_collection_end(); - void record_collection_pause_start(double start_time_sec, size_t start_used); - // Must currently be called while the world is stopped. - void record_concurrent_mark_init_end(double - mark_init_elapsed_time_ms); + void record_concurrent_mark_init_end(double mark_init_elapsed_time_ms); + // Record start and end of remark. void record_concurrent_mark_remark_start(); void record_concurrent_mark_remark_end(); + // Record start, end, and completion of cleanup. void record_concurrent_mark_cleanup_start(); void record_concurrent_mark_cleanup_end(int no_of_gc_threads); void record_concurrent_mark_cleanup_completed(); - void record_concurrent_pause(); + // Records the information about the heap size for reporting in + // print_detailed_heap_transition + void record_heap_size_info_at_start(); - void record_collection_pause_end(double pause_time, EvacuationInfo& evacuation_info); + // Print heap sizing transition (with less and more detail). void print_heap_transition(); void print_detailed_heap_transition(); - // Record the fact that a full collection occurred. - void record_full_collection_start(); - void record_full_collection_end(); + void record_stop_world_start(); + void record_concurrent_pause(); // Record how much space we copied during a GC. This is typically // called when a GC alloc region is being retired. --- old/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu May 16 16:28:36 2013 +++ new/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp Thu May 16 16:28:36 2013 @@ -132,7 +132,12 @@ og_min_size, og_max_size, yg_min_size, yg_max_size); - const size_t total_reserved = pg_max_size + og_max_size + yg_max_size; + size_t total_reserved = 0; + + total_reserved = add_and_check_overflow(total_reserved, pg_max_size); + total_reserved = add_and_check_overflow(total_reserved, og_max_size); + total_reserved = add_and_check_overflow(total_reserved, yg_max_size); + char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); // The main part of the heap (old gen + young gen) can often use a larger page --- old/src/share/vm/gc_implementation/shared/gcTrace.cpp Thu May 16 16:28:38 2013 +++ new/src/share/vm/gc_implementation/shared/gcTrace.cpp Thu May 16 16:28:38 2013 @@ -97,9 +97,17 @@ ObjectCountEventSenderClosure(GCTracer* gc_tracer) : _gc_tracer(gc_tracer) {} private: void do_cinfo(KlassInfoEntry* entry) { - _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(), - entry->words() * BytesPerWord); + if (is_visible_klass(entry->klass())) { + _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(), + entry->words() * BytesPerWord); + } } + + // Do not expose internal implementation specific classes + bool is_visible_klass(klassOop k) { + return k->klass_part()->oop_is_instance() || + (k->klass_part()->oop_is_array() && k != Universe::systemObjArrayKlassObj()); + } }; void GCTracer::report_object_count_after_gc(BoolObjectClosure *is_alive_cl) { --- old/src/share/vm/gc_interface/collectedHeap.cpp Thu May 16 16:28:40 2013 +++ new/src/share/vm/gc_interface/collectedHeap.cpp Thu May 16 16:28:40 2013 @@ -56,6 +56,9 @@ size_t CollectedHeap::_filler_array_max_size = 0; +const char* CollectedHeap::OverflowMessage + = "The size of the object heap + perm gen exceeds the maximum representable size"; + template <> void EventLogBase::print(outputStream* st, GCMessage& m) { st->print_cr("GC heap %s", m.is_before ? "before" : "after"); @@ -180,6 +183,26 @@ #endif } +size_t CollectedHeap::add_and_check_overflow(size_t total, size_t size) { + assert(size >= 0, "must be"); + size_t result = total + size; + if (result < size) { + // We must have overflowed + vm_exit_during_initialization(CollectedHeap::OverflowMessage); + } + return result; +} + +size_t CollectedHeap::round_up_and_check_overflow(size_t total, size_t size) { + assert(size >= 0, "must be"); + size_t result = round_to(total, size); + if (result < size) { + // We must have overflowed + vm_exit_during_initialization(CollectedHeap::OverflowMessage); + } + return result; +} + #ifndef PRODUCT void CollectedHeap::check_for_bad_heap_word_value(HeapWord* addr, size_t size) { if (CheckMemoryInitialization && ZapUnusedHeapArea) { --- old/src/share/vm/gc_interface/collectedHeap.hpp Thu May 16 16:28:42 2013 +++ new/src/share/vm/gc_interface/collectedHeap.hpp Thu May 16 16:28:42 2013 @@ -92,6 +92,8 @@ // Used for filler objects (static, but initialized in ctor). static size_t _filler_array_max_size; + const static char* OverflowMessage; + GCHeapLog* _gc_heap_log; // Used in support of ReduceInitialCardMarks; only consulted if COMPILER2 is being used @@ -134,6 +136,16 @@ // Reinitialize tlabs before resuming mutators. virtual void resize_all_tlabs(); + // Returns the sum of total and size if the sum does not overflow; + // Otherwise, call vm_exit_during_initialization(). + // The overflow check is performed by comparing the result of the sum against size, which is assumed to be non-zero. + size_t add_and_check_overflow(size_t total, size_t size); + + // Round up total against size and return the value, if the result does not overflow; + // Otherwise, call vm_exit_during_initialization(). + // The overflow check is performed by comparing the round-up result against size, which is assumed to be non-zero. + size_t round_up_and_check_overflow(size_t total, size_t size); + // Allocate from the current thread's TLAB, with broken-out slow path. inline static HeapWord* allocate_from_tlab(KlassHandle klass, Thread* thread, size_t size); static HeapWord* allocate_from_tlab_slow(KlassHandle klass, Thread* thread, size_t size); --- old/src/share/vm/memory/genCollectedHeap.cpp Thu May 16 16:28:44 2013 +++ new/src/share/vm/memory/genCollectedHeap.cpp Thu May 16 16:28:44 2013 @@ -201,9 +201,6 @@ size_t* _total_reserved, int* _n_covered_regions, ReservedSpace* heap_rs){ - const char overflow_msg[] = "The size of the object heap + VM data exceeds " - "the maximum representable size"; - // Now figure out the total size. size_t total_reserved = 0; int n_covered_regions = 0; @@ -211,41 +208,29 @@ os::large_page_size() : os::vm_page_size(); for (int i = 0; i < _n_gens; i++) { - total_reserved += _gen_specs[i]->max_size(); - if (total_reserved < _gen_specs[i]->max_size()) { - vm_exit_during_initialization(overflow_msg); - } + total_reserved = add_and_check_overflow(total_reserved, _gen_specs[i]->max_size()); n_covered_regions += _gen_specs[i]->n_covered_regions(); } + assert(total_reserved % pageSize == 0, err_msg("Gen size; total_reserved=" SIZE_FORMAT ", pageSize=" SIZE_FORMAT, total_reserved, pageSize)); - total_reserved += perm_gen_spec->max_size(); + total_reserved = add_and_check_overflow(total_reserved, perm_gen_spec->max_size()); assert(total_reserved % pageSize == 0, err_msg("Perm size; total_reserved=" SIZE_FORMAT ", pageSize=" SIZE_FORMAT ", perm gen max=" SIZE_FORMAT, total_reserved, pageSize, perm_gen_spec->max_size())); - if (total_reserved < perm_gen_spec->max_size()) { - vm_exit_during_initialization(overflow_msg); - } n_covered_regions += perm_gen_spec->n_covered_regions(); // Add the size of the data area which shares the same reserved area // as the heap, but which is not actually part of the heap. - size_t s = perm_gen_spec->misc_data_size() + perm_gen_spec->misc_code_size(); + size_t misc = perm_gen_spec->misc_data_size() + perm_gen_spec->misc_code_size(); + total_reserved = add_and_check_overflow(total_reserved, misc); - total_reserved += s; - if (total_reserved < s) { - vm_exit_during_initialization(overflow_msg); - } - if (UseLargePages) { assert(total_reserved != 0, "total_reserved cannot be 0"); - total_reserved = round_to(total_reserved, os::large_page_size()); - if (total_reserved < os::large_page_size()) { - vm_exit_during_initialization(overflow_msg); - } + total_reserved = round_up_and_check_overflow(total_reserved, os::large_page_size()); } // Calculate the address at which the heap must reside in order for --- old/src/share/vm/memory/universe.cpp Thu May 16 16:28:46 2013 +++ new/src/share/vm/memory/universe.cpp Thu May 16 16:28:46 2013 @@ -1033,15 +1033,6 @@ void universe2_init() { EXCEPTION_MARK; Universe::genesis(CATCH); - // Although we'd like to verify here that the state of the heap - // is good, we can't because the main thread has not yet added - // itself to the threads list (so, using current interfaces - // we can't "fill" its TLAB), unless TLABs are disabled. - if (VerifyBeforeGC && !UseTLAB && - Universe::heap()->total_collections() >= VerifyGCStartAt) { - Universe::heap()->prepare_for_verify(); - Universe::verify(); // make sure we're starting with a clean slate - } } --- old/src/share/vm/oops/methodOop.cpp Thu May 16 16:28:48 2013 +++ new/src/share/vm/oops/methodOop.cpp Thu May 16 16:28:48 2013 @@ -755,7 +755,9 @@ assert(entry != NULL, "interpreter entry must be non-null"); // Sets both _i2i_entry and _from_interpreted_entry set_interpreter_entry(entry); - if (is_native() && !is_method_handle_intrinsic()) { + + // Don't overwrite already registered native entries. + if (is_native() && !has_native_function()) { set_native_function( SharedRuntime::native_method_throw_unsatisfied_link_error_entry(), !native_bind_event_is_interesting); --- old/src/share/vm/opto/escape.cpp Thu May 16 16:28:50 2013 +++ new/src/share/vm/opto/escape.cpp Thu May 16 16:28:50 2013 @@ -464,6 +464,9 @@ Node* adr = n->in(MemNode::Address); const Type *adr_type = igvn->type(adr); adr_type = adr_type->make_ptr(); + if (adr_type == NULL) { + break; // skip dead nodes + } if (adr_type->isa_oopptr() || (opcode == Op_StoreP || opcode == Op_StoreN) && (adr_type == TypeRawPtr::NOTNULL && @@ -652,14 +655,18 @@ case Op_GetAndSetP: case Op_GetAndSetN: { Node* adr = n->in(MemNode::Address); - if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) { - const Type* t = _igvn->type(n); - if (t->make_ptr() != NULL) { - add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); - } - } const Type *adr_type = _igvn->type(adr); adr_type = adr_type->make_ptr(); +#ifdef ASSERT + if (adr_type == NULL) { + n->dump(1); + assert(adr_type != NULL, "dead node should not be on list"); + break; + } +#endif + if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) { + add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); + } if (adr_type->isa_oopptr() || (opcode == Op_StoreP || opcode == Op_StoreN) && (adr_type == TypeRawPtr::NOTNULL && @@ -1782,9 +1789,8 @@ jobj2->ideal_node()->is_Con()) { // Klass or String constants compare. Need to be careful with // compressed pointers - compare types of ConN and ConP instead of nodes. - const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr(); - const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr(); - assert(t1 != NULL && t2 != NULL, "sanity"); + const Type* t1 = jobj1->ideal_node()->get_ptr_type(); + const Type* t2 = jobj2->ideal_node()->get_ptr_type(); if (t1->make_ptr() == t2->make_ptr()) { return _pcmp_eq; } else { --- old/src/share/vm/opto/graphKit.cpp Thu May 16 16:28:53 2013 +++ new/src/share/vm/opto/graphKit.cpp Thu May 16 16:28:52 2013 @@ -3570,7 +3570,8 @@ Node* no_ctrl = NULL; Node* no_base = __ top(); - Node* zero = __ ConI(0); + Node* zero = __ ConI(0); + Node* zeroX = __ ConX(0); float likely = PROB_LIKELY(0.999); float unlikely = PROB_UNLIKELY(0.999); @@ -3596,7 +3597,9 @@ // if (!marking) __ if_then(marking, BoolTest::ne, zero); { - Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); + BasicType index_bt = TypeX_X->basic_type(); + assert(sizeof(size_t) == type2aelembytes(index_bt), "Loading G1 PtrQueue::_index with wrong size."); + Node* index = __ load(__ ctrl(), index_adr, TypeX_X, index_bt, Compile::AliasIdxRaw); if (do_load) { // load original value @@ -3609,22 +3612,16 @@ Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); // is the queue for this thread full? - __ if_then(index, BoolTest::ne, zero, likely); { + __ if_then(index, BoolTest::ne, zeroX, likely); { // decrement the index - Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); - Node* next_indexX = next_index; -#ifdef _LP64 - // We could refine the type for what it's worth - // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); - next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); -#endif + Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t)))); // Now get the buffer location we will log the previous value into and store it - Node *log_addr = __ AddP(no_base, buffer, next_indexX); + Node *log_addr = __ AddP(no_base, buffer, next_index); __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw); // update the index - __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); + __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw); } __ else_(); { @@ -3651,7 +3648,8 @@ Node* buffer, const TypeFunc* tf) { - Node* zero = __ ConI(0); + Node* zero = __ ConI(0); + Node* zeroX = __ ConX(0); Node* no_base = __ top(); BasicType card_bt = T_BYTE; // Smash zero into card. MUST BE ORDERED WRT TO STORE @@ -3658,19 +3656,13 @@ __ storeCM(__ ctrl(), card_adr, zero, oop_store, oop_alias_idx, card_bt, Compile::AliasIdxRaw); // Now do the queue work - __ if_then(index, BoolTest::ne, zero); { + __ if_then(index, BoolTest::ne, zeroX); { - Node* next_index = __ SubI(index, __ ConI(sizeof(intptr_t))); - Node* next_indexX = next_index; -#ifdef _LP64 - // We could refine the type for what it's worth - // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue); - next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) ); -#endif // _LP64 - Node* log_addr = __ AddP(no_base, buffer, next_indexX); + Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t)))); + Node* log_addr = __ AddP(no_base, buffer, next_index); __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw); - __ store(__ ctrl(), index_adr, next_index, T_INT, Compile::AliasIdxRaw); + __ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw); } __ else_(); { __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread()); @@ -3731,7 +3723,7 @@ // Now some values // Use ctrl to avoid hoisting these values past a safepoint, which could // potentially reset these fields in the JavaThread. - Node* index = __ load(__ ctrl(), index_adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw); + Node* index = __ load(__ ctrl(), index_adr, TypeX_X, TypeX_X->basic_type(), Compile::AliasIdxRaw); Node* buffer = __ load(__ ctrl(), buffer_adr, TypeRawPtr::NOTNULL, T_ADDRESS, Compile::AliasIdxRaw); // Convert the store obj pointer to an int prior to doing math on it --- old/src/share/vm/opto/lcm.cpp Thu May 16 16:28:55 2013 +++ new/src/share/vm/opto/lcm.cpp Thu May 16 16:28:54 2013 @@ -217,9 +217,9 @@ // cannot reason about it; is probably not implicit null exception } else { const TypePtr* tptr; - if (UseCompressedOops && Universe::narrow_oop_shift() == 0) { + if (UseCompressedOops && (Universe::narrow_oop_shift() == 0)) { // 32-bits narrow oop can be the base of address expressions - tptr = base->bottom_type()->make_ptr(); + tptr = base->get_ptr_type(); } else { // only regular oops are expected here tptr = base->bottom_type()->is_ptr(); --- old/src/share/vm/opto/library_call.cpp Thu May 16 16:28:57 2013 +++ new/src/share/vm/opto/library_call.cpp Thu May 16 16:28:56 2013 @@ -2769,7 +2769,7 @@ #ifdef _LP64 if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) { - load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->bottom_type()->make_ptr())); + load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); } #endif --- old/src/share/vm/opto/machnode.cpp Thu May 16 16:28:59 2013 +++ new/src/share/vm/opto/machnode.cpp Thu May 16 16:28:59 2013 @@ -348,7 +348,7 @@ if (base == NodeSentinel) return TypePtr::BOTTOM; const Type* t = base->bottom_type(); - if (UseCompressedOops && Universe::narrow_oop_shift() == 0) { + if (t->isa_narrowoop() && Universe::narrow_oop_shift() == 0) { // 32-bit unscaled narrow oop can be the base of any address expression t = t->make_ptr(); } --- old/src/share/vm/opto/macro.cpp Thu May 16 16:29:01 2013 +++ new/src/share/vm/opto/macro.cpp Thu May 16 16:29:01 2013 @@ -827,7 +827,7 @@ if (field_val->is_EncodeP()) { field_val = field_val->in(1); } else { - field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr())); + field_val = transform_later(new (C) DecodeNNode(field_val, field_val->get_ptr_type())); } } sfpt->add_req(field_val); --- old/src/share/vm/opto/node.cpp Thu May 16 16:29:03 2013 +++ new/src/share/vm/opto/node.cpp Thu May 16 16:29:03 2013 @@ -1383,6 +1383,21 @@ return NULL; } + +/** + * Return a ptr type for nodes which should have it. + */ +const TypePtr* Node::get_ptr_type() const { + const TypePtr* tp = this->bottom_type()->make_ptr(); +#ifdef ASSERT + if (tp == NULL) { + this->dump(1); + assert((tp != NULL), "unexpected node type"); + } +#endif + return tp; +} + // Get a double constant from a ConstNode. // Returns the constant if it is a double ConstNode jdouble Node::getd() const { --- old/src/share/vm/opto/node.hpp Thu May 16 16:29:05 2013 +++ new/src/share/vm/opto/node.hpp Thu May 16 16:29:05 2013 @@ -952,6 +952,8 @@ } const TypeLong* find_long_type() const; + const TypePtr* get_ptr_type() const; + // These guys are called by code generated by ADLC: intptr_t get_ptr() const; intptr_t get_narrowcon() const; --- old/src/share/vm/opto/output.cpp Thu May 16 16:29:07 2013 +++ new/src/share/vm/opto/output.cpp Thu May 16 16:29:07 2013 @@ -931,7 +931,7 @@ scval = new_loc_value( _regalloc, obj_reg, Location::oop ); } } else { - const TypePtr *tp = obj_node->bottom_type()->make_ptr(); + const TypePtr *tp = obj_node->get_ptr_type(); scval = new ConstantOopWriteValue(tp->is_oopptr()->const_oop()->constant_encoding()); } --- old/src/share/vm/opto/subnode.cpp Thu May 16 16:29:09 2013 +++ new/src/share/vm/opto/subnode.cpp Thu May 16 16:29:09 2013 @@ -865,10 +865,11 @@ const TypePtr *r1 = t2->make_ptr(); // Undefined inputs makes for an undefined result - if( TypePtr::above_centerline(r0->_ptr) || - TypePtr::above_centerline(r1->_ptr) ) + if ((r0 == NULL) || (r1 == NULL) || + TypePtr::above_centerline(r0->_ptr) || + TypePtr::above_centerline(r1->_ptr)) { return Type::TOP; - + } if (r0 == r1 && r0->singleton()) { // Equal pointer constants (klasses, nulls, etc.) return TypeInt::CC_EQ; --- old/src/share/vm/prims/methodHandles.cpp Thu May 16 16:29:11 2013 +++ new/src/share/vm/prims/methodHandles.cpp Thu May 16 16:29:11 2013 @@ -1187,6 +1187,28 @@ } JVM_END +/** + * Throws a java/lang/UnsupportedOperationException unconditionally. + * This is required by the specification of MethodHandle.invoke if + * invoked directly. + */ +JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv* env, jobject mh, jobjectArray args)) { + THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invoke cannot be invoked reflectively"); + return NULL; +} +JVM_END + +/** + * Throws a java/lang/UnsupportedOperationException unconditionally. + * This is required by the specification of MethodHandle.invokeExact if + * invoked directly. + */ +JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv* env, jobject mh, jobjectArray args)) { + THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "MethodHandle.invokeExact cannot be invoked reflectively"); + return NULL; +} +JVM_END + /// JVM_RegisterMethodHandleMethods #undef CS // Solaris builds complain @@ -1206,7 +1228,7 @@ #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) // These are the native methods on java.lang.invoke.MethodHandleNatives. -static JNINativeMethod required_methods_JDK8[] = { +static JNINativeMethod MHN_methods[] = { {CC"init", CC"("MEM""OBJ")V", FN_PTR(MHN_init_Mem)}, {CC"expand", CC"("MEM")V", FN_PTR(MHN_expand_Mem)}, {CC"resolve", CC"("MEM""CLS")"MEM, FN_PTR(MHN_resolve_Mem)}, @@ -1224,8 +1246,28 @@ {CC"getMemberVMInfo", CC"("MEM")"OBJ, FN_PTR(MHN_getMemberVMInfo)} }; -// This one function is exported, used by NativeLookup. +static JNINativeMethod MH_methods[] = { + // UnsupportedOperationException throwers + {CC"invoke", CC"(["OBJ")"OBJ, FN_PTR(MH_invoke_UOE)}, + {CC"invokeExact", CC"(["OBJ")"OBJ, FN_PTR(MH_invokeExact_UOE)} +}; +/** + * Helper method to register native methods. + */ +static bool register_natives(JNIEnv* env, jclass clazz, const JNINativeMethod* methods, jint nMethods) { + int status = env->RegisterNatives(clazz, methods, nMethods); + if (status != JNI_OK || env->ExceptionOccurred()) { + warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); + env->ExceptionClear(); + return false; + } + return true; +} + +/** + * This one function is exported, used by NativeLookup. + */ JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) { if (!EnableInvokeDynamic) { warning("JSR 292 is disabled in this JVM. Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable."); @@ -1243,17 +1285,15 @@ MH_class = (jclass) JNIHandles::make_local(env, mirror); } - int status; - if (enable_MH) { ThreadToNativeFromVM ttnfv(thread); - status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod)); - if (status != JNI_OK || env->ExceptionOccurred()) { - warning("JSR 292 method handle code is mismatched to this JVM. Disabling support."); - enable_MH = false; - env->ExceptionClear(); + if (enable_MH) { + enable_MH = register_natives(env, MHN_class, MHN_methods, sizeof(MHN_methods)/sizeof(JNINativeMethod)); } + if (enable_MH) { + enable_MH = register_natives(env, MH_class, MH_methods, sizeof(MH_methods)/sizeof(JNINativeMethod)); + } } if (TraceInvokeDynamic) { --- old/src/share/vm/prims/nativeLookup.cpp Thu May 16 16:29:14 2013 +++ new/src/share/vm/prims/nativeLookup.cpp Thu May 16 16:29:13 2013 @@ -381,10 +381,7 @@ address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) { if (!method->has_native_function()) { - address entry = - method->intrinsic_id() == vmIntrinsics::_invokeGeneric ? - SharedRuntime::native_method_throw_unsupported_operation_exception_entry() : - lookup_base(method, in_base_library, CHECK_NULL); + address entry = lookup_base(method, in_base_library, CHECK_NULL); method->set_native_function(entry, methodOopDesc::native_bind_event_is_interesting); // -verbose:jni printing --- old/src/share/vm/runtime/globals.hpp Thu May 16 16:29:16 2013 +++ new/src/share/vm/runtime/globals.hpp Thu May 16 16:29:15 2013 @@ -3634,7 +3634,9 @@ "Include GC cause in GC logging") \ \ product(bool, EnableTracing, false, \ - "Enable event-based tracing") + "Enable event-based tracing") \ + product(bool, UseLockedTracing, false, \ + "Use locked-tracing when doing event-based tracing") /* * Macros for factoring of globals --- old/src/share/vm/runtime/init.cpp Thu May 16 16:29:18 2013 +++ new/src/share/vm/runtime/init.cpp Thu May 16 16:29:18 2013 @@ -128,15 +128,6 @@ javaClasses_init(); // must happen after vtable initialization stubRoutines_init2(); // note: StubRoutines need 2-phase init - // Although we'd like to, we can't easily do a heap verify - // here because the main thread isn't yet a JavaThread, so - // its TLAB may not be made parseable from the usual interfaces. - if (VerifyBeforeGC && !UseTLAB && - Universe::heap()->total_collections() >= VerifyGCStartAt) { - Universe::heap()->prepare_for_verify(); - Universe::verify(); // make sure we're starting with a clean slate - } - // All the flags that get adjusted by VM_Version_init and os::init_2 // have been set so dump the flags now. if (PrintFlagsFinal) { --- old/src/share/vm/runtime/mutexLocker.cpp Thu May 16 16:29:20 2013 +++ new/src/share/vm/runtime/mutexLocker.cpp Thu May 16 16:29:20 2013 @@ -280,9 +280,9 @@ def(Debug3_lock , Mutex , nonleaf+4, true ); def(CompileThread_lock , Monitor, nonleaf+5, false ); - def(JfrMsg_lock , Monitor, nonleaf+2, true); - def(JfrBuffer_lock , Mutex, nonleaf+4, true); - def(JfrStream_lock , Mutex, nonleaf+5, true); + def(JfrMsg_lock , Monitor, leaf, true); + def(JfrBuffer_lock , Mutex, nonleaf+1, true); + def(JfrStream_lock , Mutex, nonleaf+2, true); def(PeriodicTask_lock , Monitor, nonleaf+5, true); } --- old/src/share/vm/runtime/os.cpp Thu May 16 16:29:22 2013 +++ new/src/share/vm/runtime/os.cpp Thu May 16 16:29:21 2013 @@ -1403,6 +1403,18 @@ return result; } + +char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint, + MEMFLAGS flags) { + char* result = pd_reserve_memory(bytes, addr, alignment_hint); + if (result != NULL) { + MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC); + MemTracker::record_virtual_memory_type((address)result, flags); + } + + return result; +} + char* os::attempt_reserve_memory_at(size_t bytes, char* addr) { char* result = pd_attempt_reserve_memory_at(bytes, addr); if (result != NULL) { --- old/src/share/vm/runtime/os.hpp Thu May 16 16:29:24 2013 +++ new/src/share/vm/runtime/os.hpp Thu May 16 16:29:23 2013 @@ -255,6 +255,8 @@ static int vm_allocation_granularity(); static char* reserve_memory(size_t bytes, char* addr = 0, size_t alignment_hint = 0); + static char* reserve_memory(size_t bytes, char* addr, + size_t alignment_hint, MEMFLAGS flags); static char* reserve_memory_aligned(size_t size, size_t alignment); static char* attempt_reserve_memory_at(size_t bytes, char* addr); static void split_reserved_memory(char *base, size_t size, --- old/src/share/vm/runtime/sharedRuntime.cpp Thu May 16 16:29:26 2013 +++ new/src/share/vm/runtime/sharedRuntime.cpp Thu May 16 16:29:25 2013 @@ -880,26 +880,30 @@ } -JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...)) +/** + * Throws an java/lang/UnsatisfiedLinkError. The address of this method is + * installed in the native function entry of all native Java methods before + * they get linked to their actual native methods. + * + * \note + * This method actually never gets called! The reason is because + * the interpreter's native entries call NativeLookup::lookup() which + * throws the exception when the lookup fails. The exception is then + * caught and forwarded on the return from NativeLookup::lookup() call + * before the call to the native function. This might change in the future. + */ +JNI_ENTRY(void*, throw_unsatisfied_link_error(JNIEnv* env, ...)) { - THROW(vmSymbols::java_lang_UnsatisfiedLinkError()); + // We return a bad value here to make sure that the exception is + // forwarded before we look at the return value. + THROW_(vmSymbols::java_lang_UnsatisfiedLinkError(), (void*)badJNIHandle); } JNI_END -JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...)) -{ - THROW(vmSymbols::java_lang_UnsupportedOperationException()); -} -JNI_END - address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() { return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error); } -address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() { - return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception); -} - #ifndef PRODUCT JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2)) --- old/src/share/vm/runtime/thread.cpp Thu May 16 16:29:28 2013 +++ new/src/share/vm/runtime/thread.cpp Thu May 16 16:29:27 2013 @@ -3383,12 +3383,6 @@ // real raw monitor. VM is setup enough here for raw monitor enter. JvmtiExport::transition_pending_onload_raw_monitors(); - if (VerifyBeforeGC && - Universe::heap()->total_collections() >= VerifyGCStartAt) { - Universe::heap()->prepare_for_verify(); - Universe::verify(); // make sure we're starting with a clean slate - } - // Fully start NMT MemTracker::start(); @@ -3412,6 +3406,11 @@ } assert (Universe::is_fully_initialized(), "not initialized"); + if (VerifyBeforeGC && VerifyGCStartAt == 0) { + Universe::heap()->prepare_for_verify(); + Universe::verify(); // make sure we're starting with a clean slate + } + EXCEPTION_MARK; // At this point, the Universe is initialized, but we have not executed --- old/src/share/vm/services/memBaseline.cpp Thu May 16 16:29:30 2013 +++ new/src/share/vm/services/memBaseline.cpp Thu May 16 16:29:29 2013 @@ -23,9 +23,12 @@ */ #include "precompiled.hpp" #include "memory/allocation.hpp" +#include "runtime/safepoint.hpp" +#include "runtime/thread.hpp" #include "services/memBaseline.hpp" #include "services/memTracker.hpp" + MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = { {mtJavaHeap, "Java Heap"}, {mtClass, "Class"}, @@ -150,6 +153,15 @@ return true; } +// check if there is a safepoint in progress, if so, block the thread +// for the safepoint +void MemBaseline::check_safepoint(JavaThread* thr) { + if (SafepointSynchronize::is_synchronizing()) { + // grab and drop the SR_lock to honor the safepoint protocol + MutexLocker ml(thr->SR_lock()); + } +} + // baseline mmap'd memory records, generate overall summary and summaries by // memory types bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) { @@ -307,7 +319,7 @@ committed_rec->pc() != vm_ptr->pc()) { if (!_vm_map->append(vm_ptr)) { return false; - } + } committed_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1); } else { committed_rec->expand_region(vm_ptr->addr(), vm_ptr->size()); @@ -345,16 +357,27 @@ // baseline a snapshot. If summary_only = false, memory usages aggregated by // callsites are also baselined. +// The method call can be lengthy, especially when detail tracking info is +// requested. So the method checks for safepoint explicitly. bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) { - MutexLockerEx snapshot_locker(snapshot._lock, true); + Thread* THREAD = Thread::current(); + assert(THREAD->is_Java_thread(), "must be a JavaThread"); + MutexLocker snapshot_locker(snapshot._lock); reset(); - _baselined = baseline_malloc_summary(snapshot._alloc_ptrs) && - baseline_vm_summary(snapshot._vm_ptrs); + _baselined = baseline_malloc_summary(snapshot._alloc_ptrs); + if (_baselined) { + check_safepoint((JavaThread*)THREAD); + _baselined = baseline_vm_summary(snapshot._vm_ptrs); + } _number_of_classes = snapshot.number_of_classes(); if (!summary_only && MemTracker::track_callsite() && _baselined) { - _baselined = baseline_malloc_details(snapshot._alloc_ptrs) && - baseline_vm_details(snapshot._vm_ptrs); + check_safepoint((JavaThread*)THREAD); + _baselined = baseline_malloc_details(snapshot._alloc_ptrs); + if (_baselined) { + check_safepoint((JavaThread*)THREAD); + _baselined = baseline_vm_details(snapshot._vm_ptrs); + } } return _baselined; } --- old/src/share/vm/services/memBaseline.hpp Thu May 16 16:29:32 2013 +++ new/src/share/vm/services/memBaseline.hpp Thu May 16 16:29:31 2013 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -330,6 +330,9 @@ // should not use copy constructor MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); } + // check and block at a safepoint + static inline void check_safepoint(JavaThread* thr); + public: // create a memory baseline MemBaseline(); --- old/src/share/vm/services/memSnapshot.cpp Thu May 16 16:29:34 2013 +++ new/src/share/vm/services/memSnapshot.cpp Thu May 16 16:29:33 2013 @@ -262,13 +262,28 @@ assert(cur->is_reserved_region() && cur->contains_region(rec), "Sanity check"); if (rec->is_same_region(cur)) { - // release whole reserved region + + // In snapshot, the virtual memory records are sorted in following orders: + // 1. virtual memory's base address + // 2. virtual memory reservation record, followed by commit records within this reservation. + // The commit records are also in base address order. + // When a reserved region is released, we want to remove the reservation record and all + // commit records following it. #ifdef ASSERT - VMMemRegion* next_region = (VMMemRegion*)peek_next(); - // should not have any committed memory in this reserved region - assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check"); + address low_addr = cur->addr(); + address high_addr = low_addr + cur->size(); #endif + // remove virtual memory reservation record remove(); + // remove committed regions within above reservation + VMMemRegion* next_region = (VMMemRegion*)current(); + while (next_region != NULL && next_region->is_committed_region()) { + assert(next_region->addr() >= low_addr && + next_region->addr() + next_region->size() <= high_addr, + "Range check"); + remove(); + next_region = (VMMemRegion*)current(); + } } else if (rec->addr() == cur->addr() || rec->addr() + rec->size() == cur->addr() + cur->size()) { // released region is at either end of this region --- old/src/share/vm/services/memTracker.cpp Thu May 16 16:29:36 2013 +++ new/src/share/vm/services/memTracker.cpp Thu May 16 16:29:35 2013 @@ -573,7 +573,7 @@ // baseline current memory snapshot bool MemTracker::baseline() { - MutexLockerEx lock(_query_lock, true); + MutexLocker lock(_query_lock); MemSnapshot* snapshot = get_snapshot(); if (snapshot != NULL) { return _baseline.baseline(*snapshot, false); @@ -584,7 +584,7 @@ // print memory usage from current snapshot bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) { MemBaseline baseline; - MutexLockerEx lock(_query_lock, true); + MutexLocker lock(_query_lock); MemSnapshot* snapshot = get_snapshot(); if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) { BaselineReporter reporter(out, unit); @@ -597,7 +597,7 @@ // Whitebox API for blocking until the current generation of NMT data has been merged bool MemTracker::wbtest_wait_for_data_merge() { // NMT can't be shutdown while we're holding _query_lock - MutexLockerEx lock(_query_lock, true); + MutexLocker lock(_query_lock); assert(_worker_thread != NULL, "Invalid query"); // the generation at query time, so NMT will spin till this generation is processed unsigned long generation_at_query_time = SequenceGenerator::current_generation(); @@ -641,7 +641,7 @@ // compare memory usage between current snapshot and baseline bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) { - MutexLockerEx lock(_query_lock, true); + MutexLocker lock(_query_lock); if (_baseline.baselined()) { MemBaseline baseline; MemSnapshot* snapshot = get_snapshot(); --- old/src/share/vm/trace/traceEventClasses.xsl Thu May 16 16:29:38 2013 +++ new/src/share/vm/trace/traceEventClasses.xsl Thu May 16 16:29:37 2013 @@ -119,6 +119,13 @@ private: + void writeEventContent(void) { + TraceStream ts(*tty); + ts.print(": ["); + + ts.print("]\n"); + } + public: @@ -132,11 +139,14 @@ void writeEvent(void) { ResourceMark rm; HandleMark hm; - TraceStream ts(*tty); - ts.print(": ["); - - ts.print("]\n"); + if (UseLockedTracing) { + ttyLocker lock; + writeEventContent(); + } else { + writeEventContent(); + } } + }; --- old/test/TEST.ROOT Thu May 16 16:29:40 2013 +++ new/test/TEST.ROOT Thu May 16 16:29:39 2013 @@ -28,4 +28,4 @@ # DO NOT EDIT without first contacting hotspot-regtest@sun.com # The list of keywords supported in this test suite -keys=cte_test jcmd nmt regression +keys=cte_test jcmd nmt regression gc --- old/test/compiler/5091921/Test6890943.sh Thu May 16 16:29:42 2013 +++ new/test/compiler/5091921/Test6890943.sh Thu May 16 16:29:41 2013 @@ -22,27 +22,17 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + set -x cp ${TESTSRC}/Test6890943.java . @@ -50,7 +40,7 @@ cp ${TESTSRC}/output6890943.txt . cp ${TESTSRC}/Test6890943.sh . -${TESTJAVA}/bin/javac -d . Test6890943.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6890943.java ${TESTJAVA}/bin/java -XX:-PrintVMOptions -XX:+IgnoreUnrecognizedVMOptions ${TESTVMOPTS} Test6890943 < input6890943.txt > pretest.out 2>&1 --- old/test/compiler/5091921/Test7005594.sh Thu May 16 16:29:44 2013 +++ new/test/compiler/5091921/Test7005594.sh Thu May 16 16:29:43 2013 @@ -22,26 +22,15 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh # Amount of physical memory in megabytes MEM=0 @@ -87,7 +76,7 @@ cp ${TESTSRC}/Test7005594.java . cp ${TESTSRC}/Test7005594.sh . -${TESTJAVA}/bin/javac -d . Test7005594.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1 --- old/test/compiler/6431242/Test.java Thu May 16 16:29:46 2013 +++ new/test/compiler/6431242/Test.java Thu May 16 16:29:45 2013 @@ -25,7 +25,7 @@ /* * @test * @bug 6431242 - * @run main/othervm -server -XX:+PrintCompilation Test + * @run main Test */ public class Test{ --- old/test/compiler/6589834/Test_ia32.java Thu May 16 16:29:48 2013 +++ new/test/compiler/6589834/Test_ia32.java Thu May 16 16:29:47 2013 @@ -26,7 +26,7 @@ * @bug 6589834 * @summary deoptimization problem with -XX:+DeoptimizeALot * - * @run main/othervm -server Test_ia32 + * @run main Test_ia32 */ /*************************************************************************************** --- old/test/compiler/6636138/Test1.java Thu May 16 16:29:50 2013 +++ new/test/compiler/6636138/Test1.java Thu May 16 16:29:49 2013 @@ -26,7 +26,7 @@ * @bug 6636138 * @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation. * - * @run main/othervm -server -Xbatch -XX:CompileOnly=Test1.init Test1 + * @run main/othervm -Xbatch -XX:CompileOnly=Test1.init Test1 */ public class Test1 { --- old/test/compiler/6636138/Test2.java Thu May 16 16:29:52 2013 +++ new/test/compiler/6636138/Test2.java Thu May 16 16:29:51 2013 @@ -26,7 +26,7 @@ * @bug 6636138 * @summary SuperWord::co_locate_pack(Node_List* p) generates memory graph that leads to memory order violation. * - * @run main/othervm -server -Xbatch -XX:CompileOnly=Test2.shift Test2 + * @run main/othervm -Xbatch -XX:CompileOnly=Test2.shift Test2 */ public class Test2 { --- old/test/compiler/6795161/Test.java Thu May 16 16:29:54 2013 +++ new/test/compiler/6795161/Test.java Thu May 16 16:29:54 2013 @@ -26,7 +26,7 @@ * @test * @bug 6795161 * @summary Escape analysis leads to data corruption - * @run main/othervm -server -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=Test -XX:+DoEscapeAnalysis Test */ class Test_Class_1 { --- old/test/compiler/6857159/Test6857159.sh Thu May 16 16:29:56 2013 +++ new/test/compiler/6857159/Test6857159.sh Thu May 16 16:29:56 2013 @@ -22,26 +22,15 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh set -x @@ -48,7 +37,7 @@ cp ${TESTSRC}/Test6857159.java . cp ${TESTSRC}/Test6857159.sh . -${TESTJAVA}/bin/javac -d . Test6857159.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test6857159.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xbatch -XX:+PrintCompilation -XX:CompileOnly=Test6857159\$ct.run Test6857159 > test.out 2>&1 --- old/test/compiler/6946040/TestCharShortByteSwap.java Thu May 16 16:29:58 2013 +++ new/test/compiler/6946040/TestCharShortByteSwap.java Thu May 16 16:29:58 2013 @@ -26,7 +26,7 @@ * @test * @bug 6946040 * @summary Tests Character/Short.reverseBytes and their intrinsics implementation in the server compiler - * @run main/othervm -Xbatch -server -XX:CompileOnly=.testChar,.testShort TestCharShortByteSwap + * @run main/othervm -Xbatch -XX:CompileOnly=.testChar,.testShort TestCharShortByteSwap */ // This test must run without any command line arguments. --- old/test/compiler/7068051/Test7068051.sh Thu May 16 16:30:00 2013 +++ new/test/compiler/7068051/Test7068051.sh Thu May 16 16:30:00 2013 @@ -22,28 +22,24 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh set -x -${TESTJAVA}/bin/jar xf ${TESTJAVA}/jre/lib/javaws.jar -${TESTJAVA}/bin/jar cf foo.jar * +${COMPILEJAVA}/bin/jar xf ${COMPILEJAVA}/jre/lib/javaws.jar +${COMPILEJAVA}/bin/jar cf foo.jar * cp ${TESTSRC}/Test7068051.java ./ -${TESTJAVA}/bin/jar -uf0 foo.jar Test7068051.java +${COMPILEJAVA}/bin/jar -uf0 foo.jar Test7068051.java -${TESTJAVA}/bin/javac -d . Test7068051.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7068051.java -${TESTJAVA}/bin/java -showversion -Xbatch ${TESTVMOPTS} Test7068051 foo.jar +${TESTJAVA}/bin/java ${TESTVMOPTS} -showversion -Xbatch Test7068051 foo.jar --- old/test/compiler/7070134/Test7070134.sh Thu May 16 16:30:03 2013 +++ new/test/compiler/7070134/Test7070134.sh Thu May 16 16:30:02 2013 @@ -22,26 +22,15 @@ # questions. # # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh set -x @@ -48,7 +37,7 @@ cp ${TESTSRC}/Stemmer.java . cp ${TESTSRC}/words . -${TESTJAVA}/bin/javac -d . Stemmer.java +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Stemmer.java ${TESTJAVA}/bin/java ${TESTVMOPTS} -Xbatch Stemmer words > test.out 2>&1 --- old/test/compiler/7200264/Test7200264.sh Thu May 16 16:30:04 2013 +++ new/test/compiler/7200264/Test7200264.sh Thu May 16 16:30:04 2013 @@ -23,51 +23,16 @@ # # +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] then - echo "TESTSRC not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi echo "TESTSRC=${TESTSRC}" -if [ "${TESTJAVA}" = "" ] -then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTJAVA=${TESTJAVA}" -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi -echo "TESTCLASSES=${TESTCLASSES}" -echo "CLASSPATH=${CLASSPATH}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - - ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion | sed 's/amd64/x86/' | grep "x86" | grep "Server VM" | grep "debug" # Only test fastdebug Server VM on x86 @@ -88,7 +53,7 @@ fi cp ${TESTSRC}${FS}TestIntVect.java . -${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java +${COMPILEJAVA}${FS}bin${FS}javac ${TESTJAVACOPTS} -d . TestIntVect.java ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1 --- old/test/compiler/8000805/Test8000805.java Thu May 16 16:30:07 2013 +++ new/test/compiler/8000805/Test8000805.java Thu May 16 16:30:06 2013 @@ -26,7 +26,7 @@ * @bug 8000805 * @summary JMM issue: short loads are non-atomic * - * @run main/othervm -server -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805 + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805 */ public class Test8000805 { --- old/test/compiler/8009761/Test8009761.java Thu May 16 16:30:09 2013 +++ new/test/compiler/8009761/Test8009761.java Thu May 16 16:30:08 2013 @@ -25,7 +25,7 @@ * @test * @bug 8009761 * @summary Deoptimization on sparc doesn't set Llast_SP correctly in the interpreter frames it creates - * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation Test8009761 + * @run main/othervm -XX:CompileCommand=exclude,Test8009761::m2 -XX:-UseOnStackReplacement -XX:-BackgroundCompilation -Xss256K Test8009761 * */ @@ -249,7 +249,7 @@ System.out.println("Failed: init recursive calls: " + c1 + ". After deopt " + count); System.exit(97); } else { - System.out.println("PASSED"); + System.out.println("PASSED " + c1); } } } --- old/test/gc/6941923/test6941923.sh Thu May 16 16:30:11 2013 +++ new/test/gc/6941923/test6941923.sh Thu May 16 16:30:10 2013 @@ -5,38 +5,25 @@ ## @author yqi ## @run shell test6941923.sh ## +## some tests require path to find test source dir +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh ## skip on windows OS=`uname -s` case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; Windows_* | CYGWIN_* ) echo "Test skipped for Windows" exit 0 ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; esac -if [ "${JAVA_HOME}" = "" ] -then - echo "JAVA_HOME not set" - exit 0 -fi - -$JAVA_HOME/bin/java ${TESTVMOPTS} -version > $NULL 2>&1 - -if [ $? != 0 ]; then - echo "Wrong JAVA_HOME? JAVA_HOME: $JAVA_HOME" - exit $? -fi - # create a small test case testname="Test" if [ -e ${testname}.java ]; then @@ -96,10 +83,10 @@ msgfail="failed" gclogsize="16K" filesize=$((16*1024)) -$JAVA_HOME/bin/javac ${testname}.java > $NULL 2>&1 +${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${testname}.java > $NULL 2>&1 if [ $? != 0 ]; then - echo "$JAVA_HOME/bin/javac ${testname}.java $fail" + echo "${COMPILEJAVA}/bin/javac ${testname}.java $fail" exit -1 fi @@ -119,7 +106,7 @@ options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=$gclogsize" echo "Test gc log rotation in same file, wait for $tts minutes ...." -$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts +${TESTJAVA}/bin/java $options $testname $tts if [ $? != 0 ]; then echo "$msgfail" exit -1 @@ -148,7 +135,7 @@ numoffiles=3 options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=$numoffiles -XX:GCLogFileSize=$gclogsize" echo "Test gc log rotation in $numoffiles files, wait for $tts minutes ...." -$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts +${TESTJAVA}/bin/java $options $testname $tts if [ $? != 0 ]; then echo "$msgfail" exit -1 --- old/test/gc/7072527/TestFullGCCount.java Thu May 16 16:30:12 2013 +++ new/test/gc/7072527/TestFullGCCount.java Thu May 16 16:30:12 2013 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,71 +25,67 @@ * @test TestFullGCount.java * @bug 7072527 * @summary CMS: JMM GC counters overcount in some cases - * @run main/othervm -XX:+UseConcMarkSweepGC TestFullGCCount - * + * @run main/othervm -XX:+PrintGC TestFullGCCount */ import java.util.*; import java.lang.management.*; +/* + * Originally for a specific failure in CMS, this test now monitors all + * collectors for double-counting of collections. + */ public class TestFullGCCount { - public String collectorName = "ConcurrentMarkSweep"; + static List collectors = ManagementFactory.getGarbageCollectorMXBeans(); - public static void main(String [] args) { + public static void main(String[] args) { + int iterations = 20; + boolean failed = false; + String errorMessage = ""; + HashMap counts = new HashMap(); - TestFullGCCount t = null; - if (args.length==2) { - t = new TestFullGCCount(args[0], args[1]); - } else { - t = new TestFullGCCount(); + // Prime the collection of count lists for all collectors. + for (int i = 0; i < collectors.size(); i++) { + GarbageCollectorMXBean collector = collectors.get(i); + counts.put(collector.getName(), new ArrayList(iterations)); } - System.out.println("Monitoring collector: " + t.collectorName); - t.run(); - } - public TestFullGCCount(String pool, String collector) { - collectorName = collector; - } + // Perform some gc, record collector counts. + for (int i = 0; i < iterations; i++) { + System.gc(); + addCollectionCount(counts, i); + } - public TestFullGCCount() { - } + // Check the increments: + // Old gen collectors should increase by one, + // New collectors may or may not increase. + // Any increase >=2 is unexpected. + for (String collector : counts.keySet()) { + System.out.println("Checking: " + collector); - public void run() { - int count = 0; - int iterations = 20; - long counts[] = new long[iterations]; - boolean diffAlways2 = true; // assume we will fail - - for (int i=0; i0) { - if (counts[i] - counts[i-1] != 2) { - diffAlways2 = false; + for (int i = 0; i < iterations - 1; i++) { + List theseCounts = counts.get(collector); + long a = theseCounts.get(i); + long b = theseCounts.get(i + 1); + if (b - a >= 2) { + failed = true; + errorMessage += "Collector '" + collector + "' has increment " + (b - a) + + " at iteration " + i + "\n"; } } } - if (diffAlways2) { - throw new RuntimeException("FAILED: System.gc must be incrementing count twice."); + if (failed) { + System.err.println(errorMessage); + throw new RuntimeException("FAILED: System.gc collections miscounted."); } System.out.println("Passed."); } - private long getCollectionCount() { - long count = 0; - List pools = ManagementFactory.getMemoryPoolMXBeans(); - List collectors = ManagementFactory.getGarbageCollectorMXBeans(); - for (int i=0; i counts, int iteration) { + for (int i = 0; i < collectors.size(); i++) { GarbageCollectorMXBean collector = collectors.get(i); - String name = collector.getName(); - if (name.contains(collectorName)) { - System.out.println(name + ": collection count = " - + collector.getCollectionCount()); - count = collector.getCollectionCount(); - } + List thisList = counts.get(collector.getName()); + thisList.add(collector.getCollectionCount()); } - return count; } - } - --- old/test/runtime/6626217/Test6626217.sh Thu May 16 16:30:14 2013 +++ new/test/runtime/6626217/Test6626217.sh Thu May 16 16:30:14 2013 @@ -27,71 +27,22 @@ # @summary Loader-constraint table allows arrays instead of only the base-classes # @run shell Test6626217.sh # - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - RM=/bin/rm - CP=/bin/cp - MV=/bin/mv - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - RM=rm - CP=cp - MV=mv - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - RM=rm - CP=cp - MV=mv - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` - JAVA=${TESTJAVA}${FS}bin${FS}java -JAVAC=${TESTJAVA}${FS}bin${FS}javac +JAVAC=${COMPILEJAVA}${FS}bin${FS}javac -${JAVA} ${TESTVMOPTS} -version - # Current directory is scratch directory, copy all the test source there # (for the subsequent moves to work). -${CP} ${TESTSRC}${FS}* ${THIS_DIR} +${CP} ${TESTSRC}${FS}* ${THIS_DIR} # A Clean Compile: this line will probably fail within jtreg as have a clean dir: ${RM} -f *.class *.impl many_loader.java @@ -98,7 +49,7 @@ # Compile all the usual suspects, including the default 'many_loader' ${CP} many_loader1.java.foo many_loader.java -${JAVAC} -source 1.4 -target 1.4 -Xlint *.java +${JAVAC} ${TESTJAVACOPTS} -source 1.4 -target 1.4 -Xlint *.java # Rename the class files, so the custom loader (and not the system loader) will find it ${MV} from_loader2.class from_loader2.impl2 @@ -106,7 +57,7 @@ # Compile the next version of 'many_loader' ${MV} many_loader.class many_loader.impl1 ${CP} many_loader2.java.foo many_loader.java -${JAVAC} -source 1.4 -target 1.4 -Xlint many_loader.java +${JAVAC} ${TESTJAVACOPTS} -source 1.4 -target 1.4 -Xlint many_loader.java # Rename the class file, so the custom loader (and not the system loader) will find it ${MV} many_loader.class many_loader.impl2 --- old/test/runtime/6878713/Test6878713.sh Thu May 16 16:30:16 2013 +++ new/test/runtime/6878713/Test6878713.sh Thu May 16 16:30:16 2013 @@ -6,58 +6,18 @@ ## @summary Verifier heap corruption, relating to backward jsrs ## @run shell/timeout=120 Test6878713.sh ## - +## some tests require path to find test source dir if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi +${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version - -${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar - ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass1960_2 > test.out 2>&1 if [ -s core -o -s "hs_*.log" ] --- old/test/runtime/6929067/Test6929067.sh Thu May 16 16:30:18 2013 +++ new/test/runtime/6929067/Test6929067.sh Thu May 16 16:30:18 2013 @@ -4,20 +4,18 @@ ## @test Test6929067.sh ## @bug 6929067 ## @summary Stack guard pages should be removed when thread is detached +## @compile T.java ## @run shell Test6929067.sh ## - +set -x if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh # set platform-dependent variables OS=`uname -s` @@ -33,31 +31,98 @@ ;; esac -# Choose arch: i386 or amd64 (test is Linux-specific) +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1 + +# Bitness: # Cannot simply look at TESTVMOPTS as -d64 is not # passed if there is only a 64-bit JVM available. -${TESTJAVA}/bin/java ${TESTVMOPTS} -version 2>1 | grep "64-Bit" >/dev/null +grep "64-Bit" vm_version.out > ${NULL} if [ "$?" = "0" ] then - ARCH=amd64 + COMP_FLAG="-m64" else - ARCH=i386 + COMP_FLAG="-m32" fi -LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${ARCH}/client:/usr/openwin/lib:/usr/dt/lib:/usr/lib:$LD_LIBRARY_PATH -export LD_LIBRARY_PATH -THIS_DIR=`pwd` +# Architecture: +# Translate uname output to JVM directory name, but permit testing +# 32-bit x86 on an x64 platform. +ARCH=`uname -m` +case "$ARCH" in + x86_64) + if [ "$COMP_FLAG" = "-m32" ]; then + ARCH=i386 + else + ARCH=amd64 + fi + ;; + ppc64) + if [ "$COMP_FLAG" = "-m32" ]; then + ARCH=ppc + else + ARCH=ppc64 + fi + ;; + sparc64) + if [ "$COMP_FLAG" = "-m32" ]; then + ARCH=sparc + else + ARCH=sparc64 + fi + ;; + arm*) + # 32-bit ARM machine: compiler may not recognise -m32 + COMP_FLAG="" + ARCH=arm + ;; + aarch64) + # 64-bit arm machine, could be testing 32 or 64-bit: + if [ "$COMP_FLAG" = "-m32" ]; then + ARCH=arm + else + ARCH=aarch64 + fi + ;; + i586) + ARCH=i386 + ;; + i686) + ARCH=i386 + ;; + # Assuming other ARCH values need no translation +esac -cp ${TESTSRC}${FS}invoke.c ${THIS_DIR} -cp ${TESTSRC}${FS}T.java ${THIS_DIR} +# VM type: need to know server or client +VMTYPE=client +grep Server vm_version.out > ${NULL} +if [ "$?" = "0" ] +then + VMTYPE=server +fi -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion -${TESTJAVA}${FS}bin${FS}javac T.java +LD_LIBRARY_PATH=.:${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE}:/usr/lib:$LD_LIBRARY_PATH +export LD_LIBRARY_PATH -gcc -o invoke -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c ${TESTJAVA}/jre/lib/${ARCH}/client/libjvm.so +cp ${TESTSRC}${FS}invoke.c . + +# Copy the result of our @compile action: +cp ${TESTCLASSES}${FS}T.class . + +echo "Architecture: ${ARCH}" +echo "Compilation flag: ${COMP_FLAG}" +echo "VM type: ${VMTYPE}" +# Note pthread may not be found thus invoke creation will fail to be created. +# Check to ensure you have a /usr/lib/libpthread.so if you don't please look +# for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation. + +gcc -DLINUX ${COMP_FLAG} -o invoke \ + -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \ + -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \ + -ljvm -lpthread invoke.c + ./invoke exit $? --- old/test/runtime/7020373/Test7020373.sh Thu May 16 16:30:20 2013 +++ new/test/runtime/7020373/Test7020373.sh Thu May 16 16:30:20 2013 @@ -10,56 +10,16 @@ ## if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi +${COMPILEJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - NULL=/dev/null - PS=":" - FS="/" - ;; - Windows_* ) - NULL=NUL - PS=";" - FS="\\" - ;; - CYGWIN_* ) - NULL=/dev/null - PS=";" - FS="/" - ;; - * ) - echo "Unrecognized system!" - exit 1; - ;; -esac - -JEMMYPATH=${CPAPPEND} -CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH - -THIS_DIR=`pwd` - -${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version - -${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar - ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1 cat test.out --- old/test/runtime/7051189/Xchecksig.sh Thu May 16 16:30:22 2013 +++ new/test/runtime/7051189/Xchecksig.sh Thu May 16 16:30:22 2013 @@ -29,34 +29,22 @@ # if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - printf "TESTJAVA not set, selecting " ${TESTJAVA} - printf " If this is incorrect, try setting the variable manually.\n" + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh - OS=`uname -s` case "$OS" in - SunOS | Linux | Darwin ) - FS="/" - ;; Windows_* | CYGWIN_* ) printf "Not testing libjsig.so on Windows. PASSED.\n " exit 0 ;; - * ) - printf "Not testing libjsig.so on unrecognised system. PASSED.\n " - exit 0 - ;; esac - JAVA=${TESTJAVA}${FS}bin${FS}java # LD_PRELOAD arch needs to match the binary we run, so run the java @@ -97,7 +85,7 @@ ;; esac -LIBJSIG=${TESTJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so +LIBJSIG=${COMPILEJAVA}${FS}jre${FS}lib${FS}${ARCH}${FS}libjsig.so # If libjsig and binary do not match, skip test. --- old/test/runtime/7107135/Test7107135.sh Thu May 16 16:30:24 2013 +++ new/test/runtime/7107135/Test7107135.sh Thu May 16 16:30:24 2013 @@ -32,26 +32,19 @@ ## if [ "${TESTSRC}" = "" ] -then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -BIT_FLAG="" - # set platform-dependent variables OS=`uname -s` case "$OS" in Linux) - NULL=/dev/null - PS=":" - FS="/" + echo "Testing on Linux" ;; *) NULL=NUL @@ -64,7 +57,7 @@ ARCH=`uname -m` -THIS_DIR=`pwd` +THIS_DIR=. cp ${TESTSRC}${FS}*.java ${THIS_DIR} ${TESTJAVA}${FS}bin${FS}javac *.java --- old/test/runtime/7110720/Test7110720.sh Thu May 16 16:30:26 2013 +++ new/test/runtime/7110720/Test7110720.sh Thu May 16 16:30:26 2013 @@ -12,23 +12,14 @@ # if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - echo "TESTJAVA not set, selecting " ${TESTJAVA} - echo "If this is incorrect, try setting the variable manually." + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -if [ "${TESTCLASSES}" = "" ] -then - echo "TESTCLASSES not set. Test cannot execute. Failed." - exit 1 -fi - # Jtreg sets TESTVMOPTS which may include -d64 which is # required to test a 64-bit JVM on some platforms. # If another test harness still creates HOME/JDK64BIT, --- old/test/runtime/7158804/Test7158804.sh Thu May 16 16:30:28 2013 +++ new/test/runtime/7158804/Test7158804.sh Thu May 16 16:30:28 2013 @@ -10,13 +10,14 @@ ## @summary Improve config file parsing ## @run shell Test7158804.sh ## - -if [ "${TESTJAVA}" = "" ] +if [ "${TESTSRC}" = "" ] then - echo "TESTJAVA not set. Test cannot execute. Failed." - exit 1 + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi -echo "TESTJAVA=${TESTJAVA}" +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh rm -f .hotspotrc echo -XX:+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa >.hotspotrc --- old/test/runtime/7162488/Test7162488.sh Thu May 16 16:30:30 2013 +++ new/test/runtime/7162488/Test7162488.sh Thu May 16 16:30:30 2013 @@ -29,28 +29,14 @@ # if [ "${TESTSRC}" = "" ] - then TESTSRC=. -fi - -if [ "${TESTJAVA}" = "" ] then - PARENT=`dirname \`which java\`` - TESTJAVA=`dirname ${PARENT}` - printf "TESTJAVA not set, selecting " ${TESTJAVA} - printf " If this is incorrect, try setting the variable manually.\n" + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh -# set platform-dependent variables -OS=`uname -s` -case "$OS" in - Windows_* ) - FS="\\" - ;; - * ) - FS="/" - ;; -esac - JAVA=${TESTJAVA}${FS}bin${FS}java # --- /dev/null Thu May 16 16:30:32 2013 +++ new/test/gc/TestVerifyBeforeGCDuringStartup.java Thu May 16 16:30:32 2013 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test TestVerifyBeforeGCDuringStartup.java + * @key gc + * @bug 8010463 + * @summary Simple test run with -XX:+VerifyBeforeGC -XX:-UseTLAB to verify 8010463 + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; + +public class TestVerifyBeforeGCDuringStartup { + public static void main(String args[]) throws Exception { + ProcessBuilder pb = + ProcessTools.createJavaProcessBuilder(System.getProperty("test.vm.opts"), + "-XX:-UseTLAB", + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+VerifyBeforeGC", "-version"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.shouldContain("[Verifying"); + output.shouldHaveExitValue(0); + } +} --- /dev/null Thu May 16 16:30:34 2013 +++ new/test/gc/init/TestHandleExceedingProcessSizeLimitIn32BitBuilds.java Thu May 16 16:30:34 2013 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test TestHandleExceedingProcessSizeLimitIn32BitBuilds.java + * @key gc + * @bug 6761744 + * @summary Test run with "-Xmx3072m -XX:MaxPermSize=1024m" to correctly handle VM error (if any) + * @library /testlibrary + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; +import com.oracle.java.testlibrary.ProcessTools; +import java.util.ArrayList; +import java.util.Collections; + +public class TestHandleExceedingProcessSizeLimitIn32BitBuilds { + public static void main(String args[]) throws Exception { + ArrayList vmOpts = new ArrayList<>(); + String testVmOptsStr = System.getProperty("test.java.opts"); + if (!testVmOptsStr.isEmpty()) { + String[] testVmOpts = testVmOptsStr.split(" "); + Collections.addAll(vmOpts, testVmOpts); + } + Collections.addAll(vmOpts, new String[] {"-Xmx3072m", "-XX:MaxPermSize=1024m", "-version"}); + + ProcessBuilder pb + = ProcessTools.createJavaProcessBuilder(vmOpts.toArray(new String[vmOpts.size()])); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + + String dataModel = System.getProperty("sun.arch.data.model"); + if (dataModel.equals("32")) { + output.shouldContain("The size of the object heap + perm gen exceeds the maximum representable size"); + if (output.getExitValue() == 0) { + throw new RuntimeException("Not expected to get exit value 0"); + } + } + } +} --- /dev/null Thu May 16 16:30:36 2013 +++ new/test/runtime/NMT/ReleaseCommittedMemory.java Thu May 16 16:30:36 2013 @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8013120 + * @summary Release committed memory and make sure NMT handles it correctly + * @key nmt regression + * @library /testlibrary /testlibrary/whitebox + * @build ReleaseCommittedMemory + * @run main ClassFileInstaller sun.hotspot.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail ReleaseCommittedMemory + */ + +import sun.hotspot.WhiteBox; + +public class ReleaseCommittedMemory { + + public static void main(String args[]) throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + long reserveSize = 256 * 1024; + long addr; + + addr = wb.NMTReserveMemory(reserveSize); + wb.NMTCommitMemory(addr, 128*1024); + wb.NMTReleaseMemory(addr, reserveSize); + wb.NMTWaitForDataMerge(); + } +} + --- /dev/null Thu May 16 16:30:38 2013 +++ new/test/test_env.sh Thu May 16 16:30:38 2013 @@ -0,0 +1,193 @@ +#!/bin/sh +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# +# This Environment script was written to capture typically used environment +# setup for a given shell test. +# + +# TESTJAVA can be a JDK or JRE. If JRE you need to set COMPILEJAVA +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi +echo "TESTJAVA=${TESTJAVA}" + +# COMPILEJAVA requires a JDK, some shell test use javac,jar,etc +if [ "${COMPILEJAVA}" = "" ] +then + echo "COMPILEJAVA not set. Using TESTJAVA as default" + COMPILEJAVA=${TESTJAVA} +fi +echo "COMPILEJAVA=${COMPILEJAVA}" + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASES not set. Using "." as default" + TESTCLASSES=. +fi +echo "TESTCLASSES=${TESTCLASSES}" + +# set platform-dependent variables +OS=`uname -s` +case "$OS" in + SunOS | Linux | Darwin ) + NULL=/dev/null + PS=":" + FS="/" + RM=/bin/rm + CP=/bin/cp + MV=/bin/mv + ;; + Windows_* ) + NULL=NUL + PS=";" + FS="\\" + RM=rm + CP=cp + MV=mv + ;; + CYGWIN_* ) + NULL=/dev/null + PS=";" + FS="/" + RM=rm + CP=cp + MV=mv + ;; + * ) + echo "Unrecognized system!" + exit 1; + ;; +esac + +export NULL PS FS RM CP MV +echo "NULL =${NULL}" +echo "PS =${PS}" +echo "FS =${FS}" +echo "RM =${RM}" +echo "CP =${CP}" +echo "MV =${MV}" + +# jtreg -classpathappend: +JEMMYPATH=${CPAPPEND} +CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH +echo "CLASSPATH =${CLASSPATH}" + +# Current directory is scratch directory +THIS_DIR=. +echo "THIS_DIR=${THIS_DIR}" + +# Check to ensure the java defined actually works +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version +if [ $? != 0 ]; then + echo "Wrong TESTJAVA or TESTVMOPTS:" + echo $TESTJAVA TESTVMOPTS + exit 1 +fi + +${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion > vm_version.out 2>&1 + +VM_TYPE="unknown" +grep "Server" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_TYPE="server" +fi +grep "Client" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_TYPE="client" +fi + +VM_BITS="32" +grep "64-Bit" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_BITS="64" +fi + +VM_OS="unknown" +grep "solaris" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="solaris" +fi +grep "linux" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="linux" +fi +grep "windows" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="windows" +fi +grep "bsd" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_OS="bsd" +fi + +VM_CPU="unknown" +grep "sparc" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="sparc" + if [ $VM_BITS = "64" ] + then + VM_CPU="sparcv9" + fi +fi +grep "x86" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="i386" +fi +grep "amd64" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="amd64" +fi +grep "arm" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="arm" +fi +grep "ppc" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="ppc" +fi +grep "ia64" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="ia64" +fi +export VM_TYPE VM_BITS VM_OS VM_CPU +echo "VM_TYPE=${VM_TYPE}" +echo "VM_BITS=${VM_BITS}" +echo "VM_OS=${VM_OS}" +echo "VM_CPU=${VM_CPU}"