Mercurial > hg > openjdk > jdk7u > hotspot
changeset 4305:c5c01d4cd7d9 hs24-b37
Merge
author | amurillo |
---|---|
date | Thu, 21 Mar 2013 11:12:14 -0700 |
parents | 06db2de2922a (current diff) 5bcfc2ed94a5 (diff) |
children | 72e4bc0bcbd2 |
files | |
diffstat | 30 files changed, 318 insertions(+), 209 deletions(-) [+] |
line wrap: on
line diff
--- a/make/hotspot_version Wed Mar 20 14:47:35 2013 -0700 +++ b/make/hotspot_version Thu Mar 21 11:12:14 2013 -0700 @@ -35,7 +35,7 @@ HS_MAJOR_VER=24 HS_MINOR_VER=0 -HS_BUILD_NUMBER=36 +HS_BUILD_NUMBER=37 JDK_MAJOR_VER=1 JDK_MINOR_VER=7
--- a/src/os/bsd/vm/os_bsd.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/os/bsd/vm/os_bsd.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -55,6 +55,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "services/attachListener.hpp" +#include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "thread_bsd.inline.hpp" #include "utilities/decoder.hpp" @@ -3315,13 +3316,25 @@ return NULL; } + // The memory is committed + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc); + MemTracker::record_virtual_memory_commit((address)addr, bytes, pc); + return addr; } bool os::release_memory_special(char* base, size_t bytes) { // detaching the SHM segment will also delete it, see reserve_memory_special() int rslt = shmdt(base); - return rslt == 0; + if (rslt == 0) { + MemTracker::record_virtual_memory_uncommit((address)base, bytes); + MemTracker::record_virtual_memory_release((address)base, bytes); + return true; + } else { + return false; + } + } size_t os::large_page_size() {
--- a/src/os/linux/vm/os_linux.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/os/linux/vm/os_linux.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -55,6 +55,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "services/attachListener.hpp" +#include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "thread_linux.inline.hpp" #include "utilities/decoder.hpp" @@ -3116,13 +3117,24 @@ numa_make_global(addr, bytes); } + // The memory is committed + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc); + MemTracker::record_virtual_memory_commit((address)addr, bytes, pc); + return addr; } bool os::release_memory_special(char* base, size_t bytes) { // detaching the SHM segment will also delete it, see reserve_memory_special() int rslt = shmdt(base); - return rslt == 0; + if (rslt == 0) { + MemTracker::record_virtual_memory_uncommit((address)base, bytes); + MemTracker::record_virtual_memory_release((address)base, bytes); + return true; + } else { + return false; + } } size_t os::large_page_size() {
--- a/src/os/solaris/vm/os_solaris.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/os/solaris/vm/os_solaris.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -3426,13 +3426,25 @@ if ((retAddr != NULL) && UseNUMAInterleaving) { numa_make_global(retAddr, size); } + + // The memory is committed + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)retAddr, size, pc); + MemTracker::record_virtual_memory_commit((address)retAddr, size, pc); + return retAddr; } bool os::release_memory_special(char* base, size_t bytes) { // detaching the SHM segment will also delete it, see reserve_memory_special() int rslt = shmdt(base); - return rslt == 0; + if (rslt == 0) { + MemTracker::record_virtual_memory_uncommit((address)base, bytes); + MemTracker::record_virtual_memory_release((address)base, bytes); + return true; + } else { + return false; + } } size_t os::large_page_size() {
--- a/src/os/windows/vm/os_windows.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/os/windows/vm/os_windows.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -58,6 +58,7 @@ #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" #include "services/attachListener.hpp" +#include "services/memTracker.hpp" #include "services/runtimeService.hpp" #include "thread_windows.inline.hpp" #include "utilities/decoder.hpp" @@ -2808,7 +2809,7 @@ PAGE_READWRITE); // If reservation failed, return NULL if (p_buf == NULL) return NULL; - + MemTracker::record_virtual_memory_reserve((address)p_buf, size_of_reserve, CALLER_PC); os::release_memory(p_buf, bytes + chunk_size); // we still need to round up to a page boundary (in case we are using large pages) @@ -2870,6 +2871,11 @@ if (next_alloc_addr > p_buf) { // Some memory was committed so release it. size_t bytes_to_release = bytes - bytes_remaining; + // NMT has yet to record any individual blocks, so it + // need to create a dummy 'reserve' record to match + // the release. + MemTracker::record_virtual_memory_reserve((address)p_buf, + bytes_to_release, CALLER_PC); os::release_memory(p_buf, bytes_to_release); } #ifdef ASSERT @@ -2881,10 +2887,19 @@ #endif return NULL; } + bytes_remaining -= bytes_to_rq; next_alloc_addr += bytes_to_rq; count++; } + // Although the memory is allocated individually, it is returned as one. + // NMT records it as one block. + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)p_buf, bytes, pc); + if ((flags & MEM_COMMIT) != 0) { + MemTracker::record_virtual_memory_commit((address)p_buf, bytes, pc); + } + // made it this far, success return p_buf; } @@ -3071,11 +3086,20 @@ // normal policy just allocate it all at once DWORD flag = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES; char * res = (char *)VirtualAlloc(NULL, bytes, flag, prot); + if (res != NULL) { + address pc = CALLER_PC; + MemTracker::record_virtual_memory_reserve((address)res, bytes, pc); + MemTracker::record_virtual_memory_commit((address)res, bytes, pc); + } + return res; } } bool os::release_memory_special(char* base, size_t bytes) { + assert(base != NULL, "Sanity check"); + // Memory allocated via reserve_memory_special() is committed + MemTracker::record_virtual_memory_uncommit((address)base, bytes); return release_memory(base, bytes); }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -5903,6 +5903,8 @@ &cmsKeepAliveClosure, false /* !preclean */); { GCTraceTime t("weak refs processing", PrintGCDetails, false, _gc_timer_cm); + + 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 @@ -5921,18 +5923,20 @@ } rp->set_active_mt_degree(active_workers); CMSRefProcTaskExecutor task_executor(*this); - rp->process_discovered_references(&_is_alive_closure, + stats = rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, &task_executor, _gc_timer_cm); } else { - rp->process_discovered_references(&_is_alive_closure, + stats = rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, NULL, _gc_timer_cm); } + _gc_tracer_cm->report_gc_reference_stats(stats); + verify_work_stacks_empty(); }
--- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -37,6 +37,7 @@ #include "gc_implementation/g1/heapRegionSeq.inline.hpp" #include "gc_implementation/shared/vmGCOperations.hpp" #include "gc_implementation/shared/gcTimer.hpp" +#include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/gcTraceTime.hpp" #include "memory/genOopClosures.inline.hpp" #include "memory/referencePolicy.hpp" @@ -2325,6 +2326,7 @@ G1CMRefProcTaskExecutor par_task_executor(g1h, this, g1h->workers(), active_workers); + 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 @@ -2333,7 +2335,7 @@ // balance_all_queues() and balance_queues()). rp->set_active_mt_degree(active_workers); - rp->process_discovered_references(&g1_is_alive, + stats = rp->process_discovered_references(&g1_is_alive, &g1_keep_alive, &g1_drain_mark_stack, &par_task_executor, @@ -2343,13 +2345,15 @@ // will set the has_overflown flag if we overflow the global marking // stack. } else { - rp->process_discovered_references(&g1_is_alive, + stats = rp->process_discovered_references(&g1_is_alive, &g1_keep_alive, &g1_drain_mark_stack, NULL, g1h->gc_timer_cm()); } + 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()) {
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -5584,22 +5584,28 @@ // Setup the soft refs policy... rp->setup_policy(false); + ReferenceProcessorStats stats; if (!rp->processing_is_mt()) { // Serial reference processing... - rp->process_discovered_references(&is_alive, - &keep_alive, - &drain_queue, - NULL, - _gc_timer_stw); + stats = rp->process_discovered_references(&is_alive, + &keep_alive, + &drain_queue, + NULL, + _gc_timer_stw); } else { // Parallel reference processing assert(rp->num_q() == no_of_gc_workers, "sanity"); assert(no_of_gc_workers <= rp->max_num_q(), "sanity"); G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers); - rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor, _gc_timer_stw); - } - + stats = rp->process_discovered_references(&is_alive, + &keep_alive, + &drain_queue, + &par_task_executor, + _gc_timer_stw); + } + + _gc_tracer_stw->report_gc_reference_stats(stats); // We have completed copying any necessary live referent objects // (that were not copied during the actual pause) so we can // retire any active alloc buffers
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -1178,6 +1178,7 @@ ReferenceProcessor* ref_processor_cm() const { return _ref_processor_cm; } ConcurrentGCTimer* gc_timer_cm() const { return _gc_timer_cm; } + G1OldTracer* gc_tracer_cm() const { return _gc_tracer_cm; } virtual size_t capacity() const; virtual size_t used() const;
--- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -148,11 +148,13 @@ assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity"); rp->setup_policy(clear_all_softrefs); - rp->process_discovered_references(&GenMarkSweep::is_alive, - &GenMarkSweep::keep_alive, - &GenMarkSweep::follow_stack_closure, - NULL, - gc_timer()); + const ReferenceProcessorStats& stats = + rp->process_discovered_references(&GenMarkSweep::is_alive, + &GenMarkSweep::keep_alive, + &GenMarkSweep::follow_stack_closure, + NULL, + gc_timer()); + gc_tracer()->report_gc_reference_stats(stats); // Follow system dictionary roots and unload classes bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive);
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -33,6 +33,7 @@ #include "gc_implementation/shared/gcTimer.hpp" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/gcTraceTime.hpp" +#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "memory/defNewGeneration.inline.hpp" #include "memory/genCollectedHeap.hpp" @@ -79,7 +80,6 @@ work_queue_set_, &term_), _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this), _keep_alive_closure(&_scan_weak_ref_closure), - _promotion_failure_size(0), _strong_roots_time(0.0), _term_time(0.0) { #if TASKQUEUE_STATS @@ -283,13 +283,10 @@ } } -void ParScanThreadState::print_and_clear_promotion_failure_size() { - if (_promotion_failure_size != 0) { - if (PrintPromotionFailure) { - gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ", - _thread_num, _promotion_failure_size); - } - _promotion_failure_size = 0; +void ParScanThreadState::print_promotion_failure_size() { + if (_promotion_failed_info.promotion_failed() && PrintPromotionFailure) { + gclog_or_tty->print(" (%d: promotion failure size = " SIZE_FORMAT ") ", + _thread_num, _promotion_failed_info.first_size()); } } @@ -309,6 +306,7 @@ inline ParScanThreadState& thread_state(int i); + void trace_promotion_failed(YoungGCTracer& gc_tracer); void reset(int active_workers, bool promotion_failed); void flush(); @@ -357,13 +355,21 @@ return ((ParScanThreadState*)_data)[i]; } +void ParScanThreadStateSet::trace_promotion_failed(YoungGCTracer& gc_tracer) { + for (int i = 0; i < length(); ++i) { + if (thread_state(i).promotion_failed()) { + gc_tracer.report_promotion_failed(thread_state(i).promotion_failed_info()); + thread_state(i).promotion_failed_info().reset(); + } + } +} void ParScanThreadStateSet::reset(int active_threads, bool promotion_failed) { _term.reset_for_reuse(active_threads); if (promotion_failed) { for (int i = 0; i < length(); ++i) { - thread_state(i).print_and_clear_promotion_failure_size(); + thread_state(i).print_promotion_failure_size(); } } } @@ -874,6 +880,8 @@ } +// A Generation that does parallel young-gen collection. + bool ParNewGeneration::_avoid_promotion_undo = false; void ParNewGeneration::adjust_desired_tenuring_threshold() { @@ -882,7 +890,30 @@ age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize); } -// A Generation that does parallel young-gen collection. +void ParNewGeneration::handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer) { + assert(_promo_failure_scan_stack.is_empty(), "post condition"); + _promo_failure_scan_stack.clear(true); // Clear cached segments. + + remove_forwarding_pointers(); + if (PrintGCDetails) { + gclog_or_tty->print(" (promotion failed)"); + } + // All the spaces are in play for mark-sweep. + swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. + from()->set_next_compaction_space(to()); + gch->set_incremental_collection_failed(); + // Inform the next generation that a promotion failure occurred. + _next_gen->promotion_failure_occurred(); + + // Trace promotion failure in the parallel GC threads + thread_state_set.trace_promotion_failed(gc_tracer); + // Single threaded code may have reported promotion failure to the global state + if (_promotion_failed_info.promotion_failed()) { + gc_tracer.report_promotion_failed(_promotion_failed_info); + } + // Reset the PromotionFailureALot counters. + NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) +} void ParNewGeneration::collect(bool full, bool clear_all_soft_refs, @@ -914,7 +945,7 @@ set_avoid_promotion_undo(true); } - // If the next generation is too full to accomodate worst-case promotion + // If the next generation is too full to accommodate worst-case promotion // from this generation, pass on collection; let the next generation // do it. if (!collection_attempt_is_safe()) { @@ -987,19 +1018,21 @@ rp->setup_policy(clear_all_soft_refs); // Can the mt_degree be set later (at run_task() time would be best)? rp->set_active_mt_degree(active_workers); + ReferenceProcessorStats stats; if (rp->processing_is_mt()) { ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); - rp->process_discovered_references(&is_alive, &keep_alive, - &evacuate_followers, &task_executor, - _gc_timer); + stats = rp->process_discovered_references(&is_alive, &keep_alive, + &evacuate_followers, &task_executor, + _gc_timer); } else { thread_state_set.flush(); gch->set_par_threads(0); // 0 ==> non-parallel. gch->save_marks(); - rp->process_discovered_references(&is_alive, &keep_alive, - &evacuate_followers, NULL, - _gc_timer); + stats = rp->process_discovered_references(&is_alive, &keep_alive, + &evacuate_followers, NULL, + _gc_timer); } + gc_tracer.report_gc_reference_stats(stats); if (!promotion_failed()) { // Swap the survivor spaces. eden()->clear(SpaceDecorator::Mangle); @@ -1022,22 +1055,7 @@ assert(to()->is_empty(), "to space should be empty now"); } else { - assert(_promo_failure_scan_stack.is_empty(), "post condition"); - _promo_failure_scan_stack.clear(true); // Clear cached segments. - - remove_forwarding_pointers(); - if (PrintGCDetails) { - gclog_or_tty->print(" (promotion failed)"); - } - // All the spaces are in play for mark-sweep. - swap_spaces(); // Make life simpler for CMS || rescan; see 6483690. - from()->set_next_compaction_space(to()); - gch->set_incremental_collection_failed(); - // Inform the next generation that a promotion failure occurred. - _next_gen->promotion_failure_occurred(); - - // Reset the PromotionFailureALot counters. - NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) + handle_promotion_failed(gch, thread_state_set, gc_tracer); } // set new iteration safe limit for the survivor spaces from()->set_concurrent_iteration_safe_limit(from()->top()); @@ -1193,8 +1211,7 @@ new_obj = old; preserve_mark_if_necessary(old, m); - // Log the size of the maiden promotion failure - par_scan_state->log_promotion_failure(sz); + par_scan_state->register_promotion_failure(sz); } old->forward_to(new_obj); @@ -1309,8 +1326,7 @@ failed_to_promote = true; preserve_mark_if_necessary(old, m); - // Log the size of the maiden promotion failure - par_scan_state->log_promotion_failure(sz); + par_scan_state->register_promotion_failure(sz); } } else { // Is in to-space; do copying ourselves.
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -25,7 +25,9 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP +#include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/parGCAllocBuffer.hpp" +#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "memory/defNewGeneration.hpp" #include "utilities/taskqueue.hpp" @@ -105,7 +107,7 @@ #endif // TASKQUEUE_STATS // Stats for promotion failure - size_t _promotion_failure_size; + PromotionFailedInfo _promotion_failed_info; // Timing numbers. double _start; @@ -180,13 +182,16 @@ void undo_alloc_in_to_space(HeapWord* obj, size_t word_sz); // Promotion failure stats - size_t promotion_failure_size() { return promotion_failure_size(); } - void log_promotion_failure(size_t sz) { - if (_promotion_failure_size == 0) { - _promotion_failure_size = sz; - } + void register_promotion_failure(size_t sz) { + _promotion_failed_info.register_promotion_failed(sz); } - void print_and_clear_promotion_failure_size(); + PromotionFailedInfo& promotion_failed_info() { + return _promotion_failed_info; + } + bool promotion_failed() { + return _promotion_failed_info.promotion_failed(); + } + void print_promotion_failure_size(); #if TASKQUEUE_STATS TaskQueueStats & taskqueue_stats() const { return _work_queue->stats; } @@ -337,6 +342,8 @@ // word being overwritten with a self-forwarding-pointer. void preserve_mark_if_necessary(oop obj, markOop m); + void handle_promotion_failed(GenCollectedHeap* gch, ParScanThreadStateSet& thread_state_set, ParNewTracer& gc_tracer); + protected: bool _survivor_overflow;
--- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -538,8 +538,10 @@ // Process reference objects found during marking { ref_processor()->setup_policy(clear_all_softrefs); - ref_processor()->process_discovered_references( - is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer); + const ReferenceProcessorStats& stats = + ref_processor()->process_discovered_references( + is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL, _gc_timer); + gc_tracer()->report_gc_reference_stats(stats); } // Follow system dictionary roots and unload classes
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -2086,7 +2086,7 @@ bool marked_for_unloading = false; marking_start.update(); - marking_phase(vmthread_cm, maximum_heap_compaction, &_gc_tracer); + marking_phase(vmthread_cm, maximum_heap_compaction); #ifndef PRODUCT if (TraceParallelOldGCMarkingPhase) { @@ -2361,9 +2361,7 @@ return ParallelScavengeHeap::gc_task_manager(); } -void PSParallelCompact::marking_phase(ParCompactionManager* cm, - bool maximum_heap_compaction, - ParallelOldTracer *gc_tracer) { +void PSParallelCompact::marking_phase(ParCompactionManager* cm, bool maximum_heap_compaction) { // Recursively traverse all live objects and mark them GCTraceTime tm("marking phase", print_phases(), true, &_gc_timer); @@ -2407,18 +2405,19 @@ { GCTraceTime tm_r("reference processing", print_phases(), true, &_gc_timer); + ReferenceProcessorStats stats; if (ref_processor()->processing_is_mt()) { RefProcTaskExecutor task_executor; - ref_processor()->process_discovered_references( + stats = ref_processor()->process_discovered_references( is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, &task_executor, &_gc_timer); } else { - ref_processor()->process_discovered_references( + stats = ref_processor()->process_discovered_references( is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL, &_gc_timer); } - gc_tracer->report_gc_reference_processing(ref_processor()->collect_statistics()); + _gc_tracer.report_gc_reference_stats(stats); } GCTraceTime tm_c("class unloading", print_phases(), true, &_gc_timer);
--- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -890,9 +890,7 @@ static void post_compact(); // Mark live objects - static void marking_phase(ParCompactionManager* cm, - bool maximum_heap_compaction, - ParallelOldTracer *gc_tracer); + static void marking_phase(ParCompactionManager* cm, bool maximum_heap_compaction); static void follow_weak_klass_links(); static void follow_mdo_weak_refs();
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -27,8 +27,8 @@ #include "gc_implementation/parallelScavenge/psOldGen.hpp" #include "gc_implementation/parallelScavenge/psPromotionManager.inline.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" +#include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/mutableSpace.hpp" -#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "memory/memRegion.hpp" #include "oops/oop.inline.hpp" #include "oops/oop.psgc.inline.hpp" @@ -87,24 +87,20 @@ } } -PromotionFailedInfo PSPromotionManager::post_scavenge() { - size_t promotion_failed_size = 0; - uint promotion_failed_count = 0; - PromotionFailedInfo pfi; +bool PSPromotionManager::post_scavenge(YoungGCTracer& gc_tracer) { + bool promotion_failure_occurred = false; TASKQUEUE_STATS_ONLY(if (PrintGCDetails && ParallelGCVerbose) print_stats()); for (uint i = 0; i < ParallelGCThreads + 1; i++) { PSPromotionManager* manager = manager_array(i); assert(manager->claimed_stack_depth()->is_empty(), "should be empty"); if (manager->_promotion_failed_info.promotion_failed()) { - promotion_failed_size += manager->_promotion_failed_info.promotion_failed_size(); - promotion_failed_count += manager->_promotion_failed_info.promotion_failed_count(); + gc_tracer.report_promotion_failed(manager->_promotion_failed_info); + promotion_failure_occurred = true; } manager->flush_labs(); } - - pfi.set_promotion_failed(promotion_failed_size, promotion_failed_count); - return pfi; + return promotion_failure_occurred; } #if TASKQUEUE_STATS
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_HPP #include "gc_implementation/parallelScavenge/psPromotionLAB.hpp" +#include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/promotionFailedInfo.hpp" #include "memory/allocation.hpp" #include "utilities/taskqueue.hpp" @@ -152,7 +153,7 @@ static void initialize(); static void pre_scavenge(); - static PromotionFailedInfo post_scavenge(); + static bool post_scavenge(YoungGCTracer& gc_tracer); static PSPromotionManager* gc_thread_promotion_manager(int index); static PSPromotionManager* vm_thread_promotion_manager();
--- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -332,7 +332,6 @@ { ResourceMark rm; HandleMark hm; - PromotionFailedInfo promotion_failed_info; gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); @@ -449,17 +448,18 @@ reference_processor()->set_active_mt_degree(active_workers); PSKeepAliveClosure keep_alive(promotion_manager); PSEvacuateFollowersClosure evac_followers(promotion_manager); + ReferenceProcessorStats stats; if (reference_processor()->processing_is_mt()) { PSRefProcTaskExecutor task_executor; - reference_processor()->process_discovered_references( + stats = reference_processor()->process_discovered_references( &_is_alive_closure, &keep_alive, &evac_followers, &task_executor, &_gc_timer); } else { - reference_processor()->process_discovered_references( + stats = reference_processor()->process_discovered_references( &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer); } - _gc_tracer.report_gc_reference_processing(reference_processor()->collect_statistics()); + _gc_tracer.report_gc_reference_stats(stats); // Enqueue reference objects discovered during scavenge. if (reference_processor()->processing_is_mt()) { @@ -480,12 +480,8 @@ } // Finally, flush the promotion_manager's labs, and deallocate its stacks. - promotion_failed_info = PSPromotionManager::post_scavenge(); - - promotion_failure_occurred = promotion_failed_info.promotion_failed(); + promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer); if (promotion_failure_occurred) { - _gc_tracer.report_promotion_failed(promotion_failed_info.promotion_failed_size(), - promotion_failed_info.promotion_failed_count()); clean_up_failed_promotion(); if (PrintGC) { gclog_or_tty->print("--"); @@ -499,8 +495,6 @@ if (!promotion_failure_occurred) { // Swap the survivor spaces. - - young_gen->eden_space()->clear(SpaceDecorator::Mangle); young_gen->from_space()->clear(SpaceDecorator::Mangle); young_gen->swap_spaces();
--- a/src/share/vm/gc_implementation/shared/gcTrace.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -26,6 +26,7 @@ #include "gc_implementation/shared/gcHeapSummary.hpp" #include "gc_implementation/shared/gcTimer.hpp" #include "gc_implementation/shared/gcTrace.hpp" +#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "memory/referenceProcessorStats.hpp" #include "utilities/globalDefinitions.hpp" @@ -75,13 +76,13 @@ _shared_gc_info.set_id(SharedGCInfo::UNSET_GCID); } -void GCTracer::report_gc_reference_processing(const ReferenceProcessorStats& rps) const { +void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) const { assert_set_gc_id(); - send_reference_processing_event(REF_SOFT, rps.soft_count()); - send_reference_processing_event(REF_WEAK, rps.weak_count()); - send_reference_processing_event(REF_FINAL, rps.final_count()); - send_reference_processing_event(REF_PHANTOM, rps.phantom_count()); + send_reference_stats_event(REF_SOFT, rps.soft_count()); + send_reference_stats_event(REF_WEAK, rps.weak_count()); + send_reference_stats_event(REF_FINAL, rps.final_count()); + send_reference_stats_event(REF_PHANTOM, rps.phantom_count()); } void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const PermGenSummary& perm_gen_summary) const { @@ -98,11 +99,10 @@ send_young_gc_event(); } -void YoungGCTracer::report_promotion_failed(size_t size, uint count) { +void YoungGCTracer::report_promotion_failed(const PromotionFailedInfo& pf_info) { assert_set_gc_id(); - young_gc_info().register_promotion_failed(); - send_promotion_failed_event(size, count); + send_promotion_failed_event(pf_info); }
--- a/src/share/vm/gc_implementation/shared/gcTrace.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -28,6 +28,7 @@ #include "gc_interface/gcCause.hpp" #include "gc_interface/gcName.hpp" #include "gc_implementation/shared/gcWhen.hpp" +#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "memory/allocation.hpp" #include "memory/referenceType.hpp" #ifndef SERIALGC @@ -93,16 +94,6 @@ void* dense_prefix() const { return _dense_prefix; } }; -class YoungGCInfo VALUE_OBJ_CLASS_SPEC { - bool _promotion_failed; - public: - YoungGCInfo() : _promotion_failed(false) {} - void register_promotion_failed() { - _promotion_failed = true; - } - bool promotion_failed() const { return _promotion_failed; } -}; - #ifndef SERIALGC class G1YoungGCInfo VALUE_OBJ_CLASS_SPEC { @@ -125,7 +116,7 @@ void report_gc_start(GCCause::Cause cause, jlong timestamp); void report_gc_end(jlong timestamp, TimePartitions* time_partitions); void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const PermGenSummary& perm_gen_summary) const; - void report_gc_reference_processing(const ReferenceProcessorStats& rp) const; + void report_gc_reference_stats(const ReferenceProcessorStats& rp) const; bool has_reported_gc_start() const; @@ -138,26 +129,23 @@ void send_garbage_collection_event() const; void send_gc_heap_summary_event(GCWhen::Type when, const GCHeapSummary& heap_summary) const; void send_perm_gen_summary_event(GCWhen::Type when, const PermGenSummary& perm_gen_summary) const; - void send_reference_processing_event(ReferenceType type, size_t count) const; + void send_reference_stats_event(ReferenceType type, size_t count) const; void send_phase_events(TimePartitions* time_partitions) const; }; class YoungGCTracer : public GCTracer { - YoungGCInfo _young_gc_info; - protected: YoungGCTracer(GCName name) : GCTracer(name) {} - virtual YoungGCInfo& young_gc_info() { return _young_gc_info; } public: - virtual void report_promotion_failed(size_t size, uint count); + virtual void report_promotion_failed(const PromotionFailedInfo& pf_info); protected: virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); private: void send_young_gc_event() const; - void send_promotion_failed_event(size_t size, uint count) const; + void send_promotion_failed_event(const PromotionFailedInfo& pf_info) const; }; class OldGCTracer : public GCTracer {
--- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -27,6 +27,7 @@ #include "gc_implementation/shared/gcTimer.hpp" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/gcWhen.hpp" +#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "trace/tracing.hpp" #ifndef SERIALGC #include "gc_implementation/g1/g1YCTypes.hpp" @@ -50,8 +51,8 @@ } } -void GCTracer::send_reference_processing_event(ReferenceType type, size_t count) const { - EventGCReferenceProcessing e; +void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const { + EventGCReferenceStatistics e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_type((u1)type); @@ -75,7 +76,6 @@ EventGCYoungGarbageCollection e(UNTIMED); if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); - e.set_promotionFailed(_young_gc_info.promotion_failed()); e.set_starttime(_shared_gc_info.start_timestamp()); e.set_endtime(_shared_gc_info.end_timestamp()); e.commit(); @@ -92,12 +92,15 @@ } } -void YoungGCTracer::send_promotion_failed_event(size_t size, uint count) const { +void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const { EventPromotionFailed e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); - e.set_objectCount(count); - e.set_totalSize(size); + e.set_objectCount(pf_info.promotion_failed_count()); + e.set_firstSize(pf_info.first_size()); + e.set_smallestSize(pf_info.smallest_size()); + e.set_totalSize(pf_info.total_size()); + e.set_thread(pf_info.thread()->thread_id()); e.commit(); } }
--- a/src/share/vm/gc_implementation/shared/promotionFailedInfo.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/gc_implementation/shared/promotionFailedInfo.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -25,34 +25,46 @@ #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_PROMOTIONFAILEDINFO_HPP #define SHARE_VM_GC_IMPLEMENTATION_SHARED_PROMOTIONFAILEDINFO_HPP +#include "runtime/thread.hpp" #include "utilities/globalDefinitions.hpp" class PromotionFailedInfo VALUE_OBJ_CLASS_SPEC { - uint _promotion_failed_count; - size_t _promotion_failed_size; + size_t _first_size; + size_t _smallest_size; + size_t _total_size; + uint _count; + OSThread* _thread; + public: - PromotionFailedInfo() : _promotion_failed_count(0), _promotion_failed_size(0) {} + PromotionFailedInfo() : _first_size(0), _smallest_size(0), _total_size(0), _count(0), _thread(NULL) {} void register_promotion_failed(size_t size) { - _promotion_failed_size += size; - _promotion_failed_count++; - } - - void set_promotion_failed(size_t size, uint count) { - _promotion_failed_size = size; - _promotion_failed_count = count; + if (_first_size == 0) { + _first_size = size; + _smallest_size = size; + _thread = Thread::current()->osthread(); + } else if (size < _smallest_size) { + _smallest_size = size; + } + _total_size += size; + _count++; + assert(_thread == Thread::current()->osthread(), "The PromotionFailedInfo should be thread local."); } void reset() { - _promotion_failed_size = 0; - _promotion_failed_count = 0; + _first_size = 0; + _smallest_size = 0; + _total_size = 0; + _count = 0; + _thread = NULL; } - bool promotion_failed() const { return _promotion_failed_size > 0; } - size_t promotion_failed_size() const { return _promotion_failed_size; } - uint promotion_failed_count() const { return _promotion_failed_count; } + bool promotion_failed() const { return _count != 0; } + size_t first_size() const { return _first_size; } + size_t smallest_size() const { return _smallest_size; } + size_t total_size() const { return _total_size; } + uint promotion_failed_count() const { return _count; } + OSThread* thread() const { return _thread; } }; - #endif /* SHARE_VM_GC_IMPLEMENTATION_SHARED_PROMOTIONFAILEDINFO_HPP */ -
--- a/src/share/vm/memory/defNewGeneration.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/memory/defNewGeneration.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -546,7 +546,7 @@ assert(_next_gen != NULL, "This must be the youngest gen, and not the only gen"); - // If the next generation is too full to accomodate promotion + // If the next generation is too full to accommodate promotion // from this generation, pass on collection; let the next generation // do it. if (!collection_attempt_is_safe()) { @@ -610,9 +610,11 @@ FastKeepAliveClosure keep_alive(this, &scan_weak_ref); ReferenceProcessor* rp = ref_processor(); rp->setup_policy(clear_all_soft_refs); - rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers, - NULL, _gc_timer); - if (!promotion_failed()) { + const ReferenceProcessorStats& stats = + rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers, + NULL, _gc_timer); + gc_tracer.report_gc_reference_stats(stats); + if (!_promotion_failed) { // Swap the survivor spaces. eden()->clear(SpaceDecorator::Mangle); from()->clear(SpaceDecorator::Mangle); @@ -661,6 +663,7 @@ // Inform the next generation that a promotion failure occurred. _next_gen->promotion_failure_occurred(); + gc_tracer.report_promotion_failed(_promotion_failed_info); // Reset the PromotionFailureALot counters. NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) @@ -670,7 +673,7 @@ to()->set_concurrent_iteration_safe_limit(to()->top()); SpecializationStats::print(); - // We need to use a monotonically non-deccreasing time in ms + // We need to use a monotonically non-decreasing time in ms // or we will see time-warp warnings and os::javaTimeMillis() // does not guarantee monotonicity. jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC; @@ -692,6 +695,7 @@ void DefNewGeneration::init_assuming_no_promotion_failure() { _promotion_failed = false; + _promotion_failed_info.reset(); from()->set_next_compaction_space(NULL); } @@ -713,7 +717,7 @@ } void DefNewGeneration::preserve_mark(oop obj, markOop m) { - assert(promotion_failed() && m->must_be_preserved_for_promotion_failure(obj), + assert(_promotion_failed && m->must_be_preserved_for_promotion_failure(obj), "Oversaving!"); _objs_with_preserved_marks.push(obj); _preserved_marks_of_objs.push(m); @@ -731,6 +735,7 @@ old->size()); } _promotion_failed = true; + _promotion_failed_info.register_promotion_failed(old->size()); preserve_mark_if_necessary(old, old->mark()); // forward to self old->forward_to(old);
--- a/src/share/vm/memory/defNewGeneration.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/memory/defNewGeneration.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -28,6 +28,7 @@ #include "gc_implementation/shared/ageTable.hpp" #include "gc_implementation/shared/cSpaceCounters.hpp" #include "gc_implementation/shared/generationCounters.hpp" +#include "gc_implementation/shared/promotionFailedInfo.hpp" #include "memory/generation.inline.hpp" #include "utilities/stack.hpp" @@ -47,15 +48,17 @@ int _tenuring_threshold; // Tenuring threshold for next collection. ageTable _age_table; // Size of object to pretenure in words; command line provides bytes - size_t _pretenure_size_threshold_words; + size_t _pretenure_size_threshold_words; ageTable* age_table() { return &_age_table; } + // Initialize state to optimistically assume no promotion failure will // happen. void init_assuming_no_promotion_failure(); // True iff a promotion has failed in the current collection. bool _promotion_failed; bool promotion_failed() { return _promotion_failed; } + PromotionFailedInfo _promotion_failed_info; // Handling promotion failure. A young generation collection // can fail if a live object cannot be copied out of its
--- a/src/share/vm/memory/genMarkSweep.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/memory/genMarkSweep.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -291,8 +291,10 @@ // Process reference objects found during marking { ref_processor()->setup_policy(clear_all_softrefs); - ref_processor()->process_discovered_references( - &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer); + const ReferenceProcessorStats& stats = + ref_processor()->process_discovered_references( + &is_alive, &keep_alive, &follow_stack_closure, NULL, _gc_timer); + gc_tracer()->report_gc_reference_stats(stats); } // Follow system dictionary roots and unload classes
--- a/src/share/vm/memory/referenceProcessor.cpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/memory/referenceProcessor.cpp Thu Mar 21 11:12:14 2013 -0700 @@ -102,8 +102,7 @@ _discovered_list_needs_barrier(discovered_list_needs_barrier), _bs(NULL), _processing_is_mt(mt_processing), - _next_id(0), - _stats() + _next_id(0) { _span = span; _discovery_is_atomic = atomic_discovery; @@ -191,14 +190,7 @@ return total; } -void ReferenceProcessor::save_discovered_list_stats() { - _stats._soft_count = total_count(_discoveredSoftRefs); - _stats._weak_count = total_count(_discoveredWeakRefs); - _stats._final_count = total_count(_discoveredFinalRefs); - _stats._phantom_count = total_count(_discoveredPhantomRefs); -} - -void ReferenceProcessor::process_discovered_references( +ReferenceProcessorStats ReferenceProcessor::process_discovered_references( BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, @@ -220,37 +212,44 @@ _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); - save_discovered_list_stats(); + bool trace_time = PrintGCDetails && PrintReferenceGC; - bool trace_time = PrintGCDetails && PrintReferenceGC; // Soft references + size_t soft_count = 0; { GCTraceTime tt("SoftReference", trace_time, false, gc_timer); - process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, - is_alive, keep_alive, complete_gc, task_executor); + soft_count = + process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, + is_alive, keep_alive, complete_gc, task_executor); } update_soft_ref_master_clock(); // Weak references + size_t weak_count = 0; { GCTraceTime tt("WeakReference", trace_time, false, gc_timer); - process_discovered_reflist(_discoveredWeakRefs, NULL, true, - is_alive, keep_alive, complete_gc, task_executor); + weak_count = + process_discovered_reflist(_discoveredWeakRefs, NULL, true, + is_alive, keep_alive, complete_gc, task_executor); } // Final references + size_t final_count = 0; { GCTraceTime tt("FinalReference", trace_time, false, gc_timer); - process_discovered_reflist(_discoveredFinalRefs, NULL, false, - is_alive, keep_alive, complete_gc, task_executor); + final_count = + process_discovered_reflist(_discoveredFinalRefs, NULL, false, + is_alive, keep_alive, complete_gc, task_executor); } // Phantom references + size_t phantom_count = 0; { GCTraceTime tt("PhantomReference", trace_time, false, gc_timer); - process_discovered_reflist(_discoveredPhantomRefs, NULL, false, - is_alive, keep_alive, complete_gc, task_executor); + phantom_count = + process_discovered_reflist(_discoveredPhantomRefs, NULL, false, + is_alive, keep_alive, complete_gc, task_executor); } // Weak global JNI references. It would make more sense (semantically) to @@ -265,6 +264,8 @@ } process_phaseJNI(is_alive, keep_alive, complete_gc); } + + return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count); } #ifndef PRODUCT @@ -900,7 +901,7 @@ balance_queues(_discoveredPhantomRefs); } -void +size_t ReferenceProcessor::process_discovered_reflist( DiscoveredList refs_lists[], ReferencePolicy* policy, @@ -923,8 +924,11 @@ must_balance) { balance_queues(refs_lists); } + + size_t total_list_count = total_count(refs_lists); + if (PrintReferenceGC && PrintGCDetails) { - gclog_or_tty->print(", %u refs", total_count(refs_lists)); + gclog_or_tty->print(", %u refs", total_list_count); } // Phase 1 (soft refs only): @@ -969,6 +973,8 @@ is_alive, keep_alive, complete_gc); } } + + return total_list_count; } void ReferenceProcessor::clean_up_discovered_references() {
--- a/src/share/vm/memory/referenceProcessor.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/memory/referenceProcessor.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -210,10 +210,7 @@ class ReferenceProcessor : public CHeapObj<mtGC> { private: - ReferenceProcessorStats _stats; - size_t total_count(DiscoveredList lists[]); - void save_discovered_list_stats(); protected: // Compatibility with pre-4965777 JDK's @@ -293,13 +290,13 @@ } // Process references with a certain reachability level. - void process_discovered_reflist(DiscoveredList refs_lists[], - ReferencePolicy* policy, - bool clear_referent, - BoolObjectClosure* is_alive, - OopClosure* keep_alive, - VoidClosure* complete_gc, - AbstractRefProcTaskExecutor* task_executor); + size_t process_discovered_reflist(DiscoveredList refs_lists[], + ReferencePolicy* policy, + bool clear_referent, + BoolObjectClosure* is_alive, + OopClosure* keep_alive, + VoidClosure* complete_gc, + AbstractRefProcTaskExecutor* task_executor); void process_phaseJNI(BoolObjectClosure* is_alive, OopClosure* keep_alive, @@ -384,12 +381,6 @@ void enqueue_discovered_reflists(HeapWord* pending_list_addr, AbstractRefProcTaskExecutor* task_executor); - // Returns statistics from the last time the reference where processed via - // an invocation of process_discovered_references. - const ReferenceProcessorStats& collect_statistics() const { - return _stats; - } - protected: // Set the 'discovered' field of the given reference to // the given value - emitting barriers depending upon @@ -447,8 +438,7 @@ _num_q(0), _max_num_q(0), _processing_is_mt(false), - _next_id(0), - _stats() + _next_id(0) { } // Default parameters give you a vanilla reference processor. @@ -520,11 +510,12 @@ bool discover_reference(oop obj, ReferenceType rt); // Process references found during GC (called by the garbage collector) - void process_discovered_references(BoolObjectClosure* is_alive, - OopClosure* keep_alive, - VoidClosure* complete_gc, - AbstractRefProcTaskExecutor* task_executor, - GCTimer *gc_timer); + ReferenceProcessorStats + process_discovered_references(BoolObjectClosure* is_alive, + OopClosure* keep_alive, + VoidClosure* complete_gc, + AbstractRefProcTaskExecutor* task_executor, + GCTimer *gc_timer); // Enqueue references at end of GC (called by the garbage collector) bool enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor = NULL);
--- a/src/share/vm/memory/referenceProcessorStats.hpp Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/memory/referenceProcessorStats.hpp Thu Mar 21 11:12:14 2013 -0700 @@ -32,9 +32,6 @@ // ReferenceProcessorStats contains statistics about how many references that // have been traversed when processing references during garbage collection. class ReferenceProcessorStats { - friend class ReferenceProcessor; - - private: size_t _soft_count; size_t _weak_count; size_t _final_count; @@ -47,6 +44,16 @@ _final_count(0), _phantom_count(0) {} + ReferenceProcessorStats(size_t soft_count, + size_t weak_count, + size_t final_count, + size_t phantom_count) : + _soft_count(soft_count), + _weak_count(weak_count), + _final_count(final_count), + _phantom_count(phantom_count) + {} + size_t soft_count() const { return _soft_count; }
--- a/src/share/vm/trace/trace.xml Wed Mar 20 14:47:35 2013 -0700 +++ b/src/share/vm/trace/trace.xml Thu Mar 21 11:12:14 2013 -0700 @@ -168,8 +168,6 @@ <event id="GCYoungGarbageCollection" path="vm/gc/collector/young_garbage_collection" label="Young Garbage Collection" description="Extra information specific to Young Garbage Collections"> <value type="ULONG" field="gcId" label="GC ID" relation="GC_ID" /> - <!-- This information can also be found by looking for PromotionFailed events. It's here for convenience. --> - <value type="BOOLEAN" field="promotionFailed" label="Promotion Failed" description="Tells if we failed to promote some objects to the old gen" /> </event> <event id="GCOldGarbageCollection" path="vm/gc/collector/old_garbage_collection" label="Old Garbage Collection" @@ -183,7 +181,7 @@ <value type="G1YCTYPE" field="type" label="Type" /> </event> - <event id="GCReferenceProcessing" path="vm/gc/reference/statistics" + <event id="GCReferenceStatistics" path="vm/gc/reference/statistics" label="GC Reference Processing" is_instant="true" description="Total count of processed references during GC"> <value type="ULONG" field="gcId" label="GC ID" relation="GC_ID"/> @@ -195,7 +193,10 @@ description="Promotion of an object failed"> <value type="ULONG" field="gcId" label="GC ID" relation="GC_ID"/> <value type="BYTES64" field="objectCount" label="Object Count"/> + <value type="BYTES64" field="firstSize" label="First Failed Object Size"/> + <value type="BYTES64" field="smallestSize" label="Smallest Failed Object Size"/> <value type="BYTES64" field="totalSize" label="Total Object Size"/> + <value type="OSTHREAD" field="thread" label="Running thread"/> </event> <event id="GCPhasePause" path="vm/gc/phases/pause" label="GC Phase Pause">
--- a/test/runtime/NMT/BaselineWithParameter.java Wed Mar 20 14:47:35 2013 -0700 +++ b/test/runtime/NMT/BaselineWithParameter.java Thu Mar 21 11:12:14 2013 -0700 @@ -43,7 +43,7 @@ // Run 'jcmd <pid> VM.native_memory baseline=false' pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "baseline=false"}); - pb.start(); + pb.start().waitFor(); // Run 'jcmd <pid> VM.native_memory summary=false' pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary=false"});