Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @ 10405:f2110083203d
8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
author | sla |
---|---|
date | Mon, 10 Jun 2013 11:30:51 +0200 |
parents | 47bdfb3d010f |
children | c49c7f835e8d |
comparison
equal
deleted
inserted
replaced
10404:d0add7016434 | 10405:f2110083203d |
---|---|
32 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" | 32 #include "gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp" |
33 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" | 33 #include "gc_implementation/parallelScavenge/psMarkSweep.hpp" |
34 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" | 34 #include "gc_implementation/parallelScavenge/psParallelCompact.hpp" |
35 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" | 35 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp" |
36 #include "gc_implementation/parallelScavenge/psTasks.hpp" | 36 #include "gc_implementation/parallelScavenge/psTasks.hpp" |
37 #include "gc_implementation/shared/gcHeapSummary.hpp" | |
38 #include "gc_implementation/shared/gcTimer.hpp" | |
39 #include "gc_implementation/shared/gcTrace.hpp" | |
40 #include "gc_implementation/shared/gcTraceTime.hpp" | |
37 #include "gc_implementation/shared/isGCActiveMark.hpp" | 41 #include "gc_implementation/shared/isGCActiveMark.hpp" |
38 #include "gc_implementation/shared/spaceDecorator.hpp" | 42 #include "gc_implementation/shared/spaceDecorator.hpp" |
39 #include "gc_interface/gcCause.hpp" | 43 #include "gc_interface/gcCause.hpp" |
40 #include "memory/collectorPolicy.hpp" | 44 #include "memory/collectorPolicy.hpp" |
41 #include "memory/gcLocker.inline.hpp" | 45 #include "memory/gcLocker.inline.hpp" |
61 bool PSScavenge::_survivor_overflow = false; | 65 bool PSScavenge::_survivor_overflow = false; |
62 uint PSScavenge::_tenuring_threshold = 0; | 66 uint PSScavenge::_tenuring_threshold = 0; |
63 HeapWord* PSScavenge::_young_generation_boundary = NULL; | 67 HeapWord* PSScavenge::_young_generation_boundary = NULL; |
64 uintptr_t PSScavenge::_young_generation_boundary_compressed = 0; | 68 uintptr_t PSScavenge::_young_generation_boundary_compressed = 0; |
65 elapsedTimer PSScavenge::_accumulated_time; | 69 elapsedTimer PSScavenge::_accumulated_time; |
70 STWGCTimer PSScavenge::_gc_timer; | |
71 ParallelScavengeTracer PSScavenge::_gc_tracer; | |
66 Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack; | 72 Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack; |
67 Stack<oop, mtGC> PSScavenge::_preserved_oop_stack; | 73 Stack<oop, mtGC> PSScavenge::_preserved_oop_stack; |
68 CollectorCounters* PSScavenge::_counters = NULL; | 74 CollectorCounters* PSScavenge::_counters = NULL; |
69 bool PSScavenge::_promotion_failed = false; | |
70 | 75 |
71 // Define before use | 76 // Define before use |
72 class PSIsAliveClosure: public BoolObjectClosure { | 77 class PSIsAliveClosure: public BoolObjectClosure { |
73 public: | 78 public: |
74 bool do_object_b(oop p) { | 79 bool do_object_b(oop p) { |
257 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); | 262 assert(Thread::current() == (Thread*)VMThread::vm_thread(), "should be in vm thread"); |
258 | 263 |
259 assert(_preserved_mark_stack.is_empty(), "should be empty"); | 264 assert(_preserved_mark_stack.is_empty(), "should be empty"); |
260 assert(_preserved_oop_stack.is_empty(), "should be empty"); | 265 assert(_preserved_oop_stack.is_empty(), "should be empty"); |
261 | 266 |
267 _gc_timer.register_gc_start(os::elapsed_counter()); | |
268 | |
262 TimeStamp scavenge_entry; | 269 TimeStamp scavenge_entry; |
263 TimeStamp scavenge_midpoint; | 270 TimeStamp scavenge_midpoint; |
264 TimeStamp scavenge_exit; | 271 TimeStamp scavenge_exit; |
265 | 272 |
266 scavenge_entry.update(); | 273 scavenge_entry.update(); |
276 // Check for potential problems. | 283 // Check for potential problems. |
277 if (!should_attempt_scavenge()) { | 284 if (!should_attempt_scavenge()) { |
278 return false; | 285 return false; |
279 } | 286 } |
280 | 287 |
288 _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start()); | |
289 | |
281 bool promotion_failure_occurred = false; | 290 bool promotion_failure_occurred = false; |
282 | 291 |
283 PSYoungGen* young_gen = heap->young_gen(); | 292 PSYoungGen* young_gen = heap->young_gen(); |
284 PSOldGen* old_gen = heap->old_gen(); | 293 PSOldGen* old_gen = heap->old_gen(); |
285 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); | 294 PSAdaptiveSizePolicy* size_policy = heap->size_policy(); |
295 | |
286 heap->increment_total_collections(); | 296 heap->increment_total_collections(); |
287 | 297 |
288 AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); | 298 AdaptiveSizePolicyOutput(size_policy, heap->total_collections()); |
289 | 299 |
290 if ((gc_cause != GCCause::_java_lang_system_gc) || | 300 if ((gc_cause != GCCause::_java_lang_system_gc) || |
297 // Save information needed to minimize mangling | 307 // Save information needed to minimize mangling |
298 heap->record_gen_tops_before_GC(); | 308 heap->record_gen_tops_before_GC(); |
299 } | 309 } |
300 | 310 |
301 heap->print_heap_before_gc(); | 311 heap->print_heap_before_gc(); |
312 heap->trace_heap_before_gc(&_gc_tracer); | |
302 | 313 |
303 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); | 314 assert(!NeverTenure || _tenuring_threshold == markOopDesc::max_age + 1, "Sanity"); |
304 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); | 315 assert(!AlwaysTenure || _tenuring_threshold == 0, "Sanity"); |
305 | 316 |
306 size_t prev_used = heap->used(); | 317 size_t prev_used = heap->used(); |
307 assert(promotion_failed() == false, "Sanity"); | |
308 | 318 |
309 // Fill in TLABs | 319 // Fill in TLABs |
310 heap->accumulate_statistics_all_tlabs(); | 320 heap->accumulate_statistics_all_tlabs(); |
311 heap->ensure_parsability(true); // retire TLABs | 321 heap->ensure_parsability(true); // retire TLABs |
312 | 322 |
319 ResourceMark rm; | 329 ResourceMark rm; |
320 HandleMark hm; | 330 HandleMark hm; |
321 | 331 |
322 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | 332 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
323 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | 333 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |
324 TraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty); | 334 GCTraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, NULL); |
325 TraceCollectorStats tcs(counters()); | 335 TraceCollectorStats tcs(counters()); |
326 TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); | 336 TraceMemoryManagerStats tms(false /* not full GC */,gc_cause); |
327 | 337 |
328 if (TraceGen0Time) accumulated_time()->start(); | 338 if (TraceGen0Time) accumulated_time()->start(); |
329 | 339 |
385 PSPromotionManager::pre_scavenge(); | 395 PSPromotionManager::pre_scavenge(); |
386 | 396 |
387 // We'll use the promotion manager again later. | 397 // We'll use the promotion manager again later. |
388 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); | 398 PSPromotionManager* promotion_manager = PSPromotionManager::vm_thread_promotion_manager(); |
389 { | 399 { |
390 // TraceTime("Roots"); | 400 GCTraceTime tm("Scavenge", false, false, &_gc_timer); |
391 ParallelScavengeHeap::ParStrongRootsScope psrs; | 401 ParallelScavengeHeap::ParStrongRootsScope psrs; |
392 | 402 |
393 GCTaskQueue* q = GCTaskQueue::create(); | 403 GCTaskQueue* q = GCTaskQueue::create(); |
394 | 404 |
395 if (!old_gen->object_space()->is_empty()) { | 405 if (!old_gen->object_space()->is_empty()) { |
427 | 437 |
428 scavenge_midpoint.update(); | 438 scavenge_midpoint.update(); |
429 | 439 |
430 // Process reference objects discovered during scavenge | 440 // Process reference objects discovered during scavenge |
431 { | 441 { |
442 GCTraceTime tm("References", false, false, &_gc_timer); | |
443 | |
432 reference_processor()->setup_policy(false); // not always_clear | 444 reference_processor()->setup_policy(false); // not always_clear |
433 reference_processor()->set_active_mt_degree(active_workers); | 445 reference_processor()->set_active_mt_degree(active_workers); |
434 PSKeepAliveClosure keep_alive(promotion_manager); | 446 PSKeepAliveClosure keep_alive(promotion_manager); |
435 PSEvacuateFollowersClosure evac_followers(promotion_manager); | 447 PSEvacuateFollowersClosure evac_followers(promotion_manager); |
448 ReferenceProcessorStats stats; | |
436 if (reference_processor()->processing_is_mt()) { | 449 if (reference_processor()->processing_is_mt()) { |
437 PSRefProcTaskExecutor task_executor; | 450 PSRefProcTaskExecutor task_executor; |
438 reference_processor()->process_discovered_references( | 451 stats = reference_processor()->process_discovered_references( |
439 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor); | 452 &_is_alive_closure, &keep_alive, &evac_followers, &task_executor, |
453 &_gc_timer); | |
440 } else { | 454 } else { |
441 reference_processor()->process_discovered_references( | 455 stats = reference_processor()->process_discovered_references( |
442 &_is_alive_closure, &keep_alive, &evac_followers, NULL); | 456 &_is_alive_closure, &keep_alive, &evac_followers, NULL, &_gc_timer); |
443 } | 457 } |
444 } | 458 |
445 | 459 _gc_tracer.report_gc_reference_stats(stats); |
446 // Enqueue reference objects discovered during scavenge. | 460 |
447 if (reference_processor()->processing_is_mt()) { | 461 // Enqueue reference objects discovered during scavenge. |
448 PSRefProcTaskExecutor task_executor; | 462 if (reference_processor()->processing_is_mt()) { |
449 reference_processor()->enqueue_discovered_references(&task_executor); | 463 PSRefProcTaskExecutor task_executor; |
450 } else { | 464 reference_processor()->enqueue_discovered_references(&task_executor); |
451 reference_processor()->enqueue_discovered_references(NULL); | 465 } else { |
452 } | 466 reference_processor()->enqueue_discovered_references(NULL); |
453 | 467 } |
468 } | |
469 | |
470 GCTraceTime tm("StringTable", false, false, &_gc_timer); | |
454 // Unlink any dead interned Strings and process the remaining live ones. | 471 // Unlink any dead interned Strings and process the remaining live ones. |
455 PSScavengeRootsClosure root_closure(promotion_manager); | 472 PSScavengeRootsClosure root_closure(promotion_manager); |
456 StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure); | 473 StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure); |
457 | 474 |
458 // Finally, flush the promotion_manager's labs, and deallocate its stacks. | 475 // Finally, flush the promotion_manager's labs, and deallocate its stacks. |
459 PSPromotionManager::post_scavenge(); | 476 promotion_failure_occurred = PSPromotionManager::post_scavenge(_gc_tracer); |
460 | |
461 promotion_failure_occurred = promotion_failed(); | |
462 if (promotion_failure_occurred) { | 477 if (promotion_failure_occurred) { |
463 clean_up_failed_promotion(); | 478 clean_up_failed_promotion(); |
464 if (PrintGC) { | 479 if (PrintGC) { |
465 gclog_or_tty->print("--"); | 480 gclog_or_tty->print("--"); |
466 } | 481 } |
471 // implicitly saying it's mutator time). | 486 // implicitly saying it's mutator time). |
472 size_policy->minor_collection_end(gc_cause); | 487 size_policy->minor_collection_end(gc_cause); |
473 | 488 |
474 if (!promotion_failure_occurred) { | 489 if (!promotion_failure_occurred) { |
475 // Swap the survivor spaces. | 490 // Swap the survivor spaces. |
476 | |
477 | |
478 young_gen->eden_space()->clear(SpaceDecorator::Mangle); | 491 young_gen->eden_space()->clear(SpaceDecorator::Mangle); |
479 young_gen->from_space()->clear(SpaceDecorator::Mangle); | 492 young_gen->from_space()->clear(SpaceDecorator::Mangle); |
480 young_gen->swap_spaces(); | 493 young_gen->swap_spaces(); |
481 | 494 |
482 size_t survived = young_gen->from_space()->used_in_bytes(); | 495 size_t survived = young_gen->from_space()->used_in_bytes(); |
610 | 623 |
611 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | 624 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); |
612 | 625 |
613 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); | 626 NOT_PRODUCT(reference_processor()->verify_no_references_recorded()); |
614 | 627 |
615 CodeCache::prune_scavenge_root_nmethods(); | 628 { |
629 GCTraceTime tm("Prune Scavenge Root Methods", false, false, &_gc_timer); | |
630 | |
631 CodeCache::prune_scavenge_root_nmethods(); | |
632 } | |
616 | 633 |
617 // Re-verify object start arrays | 634 // Re-verify object start arrays |
618 if (VerifyObjectStartArray && | 635 if (VerifyObjectStartArray && |
619 VerifyAfterGC) { | 636 VerifyAfterGC) { |
620 old_gen->verify_object_start_array(); | 637 old_gen->verify_object_start_array(); |
650 HandleMark hm; // Discard invalid handles created during verification | 667 HandleMark hm; // Discard invalid handles created during verification |
651 Universe::verify(" VerifyAfterGC:"); | 668 Universe::verify(" VerifyAfterGC:"); |
652 } | 669 } |
653 | 670 |
654 heap->print_heap_after_gc(); | 671 heap->print_heap_after_gc(); |
672 heap->trace_heap_after_gc(&_gc_tracer); | |
673 _gc_tracer.report_tenuring_threshold(tenuring_threshold()); | |
655 | 674 |
656 if (ZapUnusedHeapArea) { | 675 if (ZapUnusedHeapArea) { |
657 young_gen->eden_space()->check_mangled_unused_area_complete(); | 676 young_gen->eden_space()->check_mangled_unused_area_complete(); |
658 young_gen->from_space()->check_mangled_unused_area_complete(); | 677 young_gen->from_space()->check_mangled_unused_area_complete(); |
659 young_gen->to_space()->check_mangled_unused_area_complete(); | 678 young_gen->to_space()->check_mangled_unused_area_complete(); |
669 } | 688 } |
670 | 689 |
671 #ifdef TRACESPINNING | 690 #ifdef TRACESPINNING |
672 ParallelTaskTerminator::print_termination_counts(); | 691 ParallelTaskTerminator::print_termination_counts(); |
673 #endif | 692 #endif |
693 | |
694 | |
695 _gc_timer.register_gc_end(os::elapsed_counter()); | |
696 | |
697 _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions()); | |
674 | 698 |
675 return !promotion_failure_occurred; | 699 return !promotion_failure_occurred; |
676 } | 700 } |
677 | 701 |
678 // This method iterates over all objects in the young generation, | 702 // This method iterates over all objects in the young generation, |
679 // unforwarding markOops. It then restores any preserved mark oops, | 703 // unforwarding markOops. It then restores any preserved mark oops, |
680 // and clears the _preserved_mark_stack. | 704 // and clears the _preserved_mark_stack. |
681 void PSScavenge::clean_up_failed_promotion() { | 705 void PSScavenge::clean_up_failed_promotion() { |
682 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); | 706 ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); |
683 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); | 707 assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); |
684 assert(promotion_failed(), "Sanity"); | |
685 | 708 |
686 PSYoungGen* young_gen = heap->young_gen(); | 709 PSYoungGen* young_gen = heap->young_gen(); |
687 | 710 |
688 { | 711 { |
689 ResourceMark rm; | 712 ResourceMark rm; |
704 } | 727 } |
705 | 728 |
706 // Clear the preserved mark and oop stack caches. | 729 // Clear the preserved mark and oop stack caches. |
707 _preserved_mark_stack.clear(true); | 730 _preserved_mark_stack.clear(true); |
708 _preserved_oop_stack.clear(true); | 731 _preserved_oop_stack.clear(true); |
709 _promotion_failed = false; | |
710 } | 732 } |
711 | 733 |
712 // Reset the PromotionFailureALot counters. | 734 // Reset the PromotionFailureALot counters. |
713 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) | 735 NOT_PRODUCT(Universe::heap()->reset_promotion_should_fail();) |
714 } | 736 } |
715 | 737 |
716 // This method is called whenever an attempt to promote an object | 738 // This method is called whenever an attempt to promote an object |
717 // fails. Some markOops will need preservation, some will not. Note | 739 // fails. Some markOops will need preservation, some will not. Note |
718 // that the entire eden is traversed after a failed promotion, with | 740 // that the entire eden is traversed after a failed promotion, with |
719 // all forwarded headers replaced by the default markOop. This means | 741 // all forwarded headers replaced by the default markOop. This means |
720 // it is not neccessary to preserve most markOops. | 742 // it is not necessary to preserve most markOops. |
721 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { | 743 void PSScavenge::oop_promotion_failed(oop obj, markOop obj_mark) { |
722 _promotion_failed = true; | |
723 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { | 744 if (obj_mark->must_be_preserved_for_promotion_failure(obj)) { |
724 // Should use per-worker private stakcs hetre rather than | 745 // Should use per-worker private stacks here rather than |
725 // locking a common pair of stacks. | 746 // locking a common pair of stacks. |
726 ThreadCritical tc; | 747 ThreadCritical tc; |
727 _preserved_oop_stack.push(obj); | 748 _preserved_oop_stack.push(obj); |
728 _preserved_mark_stack.push(obj_mark); | 749 _preserved_mark_stack.push(obj_mark); |
729 } | 750 } |