--- old/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp 2013-06-05 10:56:29.000000000 +0200 +++ new/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp 2013-06-05 10:56:29.000000000 +0200 @@ -34,6 +34,10 @@ #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" #include "gc_implementation/parallelScavenge/psTasks.hpp" +#include "gc_implementation/shared/gcHeapSummary.hpp" +#include "gc_implementation/shared/gcTimer.hpp" +#include "gc_implementation/shared/gcTrace.hpp" +#include "gc_implementation/shared/gcTraceTime.hpp" #include "gc_implementation/shared/isGCActiveMark.hpp" #include "gc_implementation/shared/spaceDecorator.hpp" #include "gc_interface/gcCause.hpp" @@ -62,10 +66,11 @@ uint PSScavenge::_tenuring_threshold = 0; HeapWord* PSScavenge::_young_generation_boundary = NULL; elapsedTimer PSScavenge::_accumulated_time; +STWGCTimer PSScavenge::_gc_timer; +ParallelScavengeTracer PSScavenge::_gc_tracer; Stack PSScavenge::_preserved_mark_stack; Stack PSScavenge::_preserved_oop_stack; CollectorCounters* PSScavenge::_counters = NULL; -bool PSScavenge::_promotion_failed = false; // Define before use class PSIsAliveClosure: public BoolObjectClosure { @@ -258,6 +263,8 @@ assert(_preserved_mark_stack.is_empty(), "should be empty"); assert(_preserved_oop_stack.is_empty(), "should be empty"); + _gc_timer.register_gc_start(os::elapsed_counter()); + TimeStamp scavenge_entry; TimeStamp scavenge_midpoint; TimeStamp scavenge_exit; @@ -277,11 +284,14 @@ return false; } + _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start()); + bool promotion_failure_occurred = false; PSYoungGen* young_gen = heap->young_gen(); PSOldGen* old_gen = heap->old_gen(); PSAdaptiveSizePolicy* size_policy = heap->size_policy(); + heap->increment_total_collections(); AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); @@ -298,12 +308,12 @@ } heap->print_heap_before_gc(); + heap->trace_heap_before_gc(&_gc_tracer); assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); size_t prev_used = heap->used(); - assert(promotion_failed() == false, "Sanity"); // Fill in TLABs heap->accumulate_statistics_all_tlabs(); @@ -320,7 +330,7 @@ gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); - TraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty); + GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL); TraceCollectorStats tcs(counters()); TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); @@ -386,7 +396,7 @@ // We'll use the promotion manager again later. PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); { - // TraceTime("Roots"); + GCTraceTime tm("Scavenge", false, false, &_gc_timer); ParallelScavengeHeap::ParStrongRootsScope psrs; GCTaskQueue* q = GCTaskQueue::create(); @@ -428,36 +438,41 @@ // Process reference objects discovered during scavenge { + GCTraceTime tm("References", false, false, &_gc_timer); + reference_processor()->setup_policy(false); // not always_clear 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( - &_is_alive_closure, &keep_alive, &evac_followers, &task_executor); + stats = reference_processor()->process_discovered_references( + &_is_alive_closure, &keep_alive, &evac_followers, &task_executor, + &_gc_timer); } else { - reference_processor()->process_discovered_references( - &_is_alive_closure, &keep_alive, &evac_followers, NULL); + stats = reference_processor()->process_discovered_references( + &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer); } - } - // Enqueue reference objects discovered during scavenge. - if (reference_processor()->processing_is_mt()) { - PSRefProcTaskExecutor task_executor; - reference_processor()->enqueue_discovered_references(&task_executor); - } else { - reference_processor()->enqueue_discovered_references(NULL); + _gc_tracer.report_gc_reference_stats(stats); + + // Enqueue reference objects discovered during scavenge. + if (reference_processor()->processing_is_mt()) { + PSRefProcTaskExecutor task_executor; + reference_processor()->enqueue_discovered_references(&task_executor); + } else { + reference_processor()->enqueue_discovered_references(NULL); + } } + GCTraceTime tm("StringTable", false, false, &_gc_timer); // Unlink any dead interned Strings and process the remaining live ones. PSScavengeRootsClosure root_closure(promotion_manager); StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure); // Finally, flush the promotion_manager's labs, and deallocate its stacks. - PSPromotionManager::post_scavenge(); - - promotion_failure_occurred = promotion_failed(); + promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer); if (promotion_failure_occurred) { clean_up_failed_promotion(); if (PrintGC) { @@ -472,8 +487,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(); @@ -611,7 +624,11 @@ NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); - CodeCache::prune_scavenge_root_nmethods(); + { + GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer); + + CodeCache::prune_scavenge_root_nmethods(); + } // Re-verify object start arrays if (VerifyObjectStartArray && @@ -651,6 +668,8 @@ } heap->print_heap_after_gc(); + heap->trace_heap_after_gc(&_gc_tracer); + _gc_tracer.report_tenuring_threshold(tenuring_threshold()); if (ZapUnusedHeapArea) { young_gen->eden_space()->check_mangled_unused_area_complete(); @@ -671,6 +690,11 @@ ParallelTaskTerminator::print_termination_counts(); #endif + + _gc_timer.register_gc_end(os::elapsed_counter()); + + _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions()); + return !promotion_failure_occurred; } @@ -680,7 +704,6 @@ void PSScavenge::clean_up_failed_promotion() { ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); - assert(promotion_failed(), "Sanity"); PSYoungGen* young_gen = heap->young_gen(); @@ -705,7 +728,6 @@ // Clear the preserved mark and oop stack caches. _preserved_mark_stack.clear(true); _preserved_oop_stack.clear(true); - _promotion_failed = false; } // Reset the PromotionFailureALot counters. @@ -716,11 +738,10 @@ // fails. Some markOops will need preservation, some will not. Note // that the entire eden is traversed after a failed promotion, with // all forwarded headers replaced by the default markOop. This means -// it is not neccessary to preserve most markOops. +// it is not necessary to preserve most markOops. void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { - _promotion_failed = true; if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { - // Should use per-worker private stakcs hetre rather than + // Should use per-worker private stacks here rather than // locking a common pair of stacks. ThreadCritical tc; _preserved_oop_stack.push(obj);