Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 1656:4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
Summary: G1 was not handling explicit GCs correctly in many ways. It does now. See the CR for the list of improvements contained in this changeset.
Reviewed-by: iveresov, ysr, johnc
author | tonyp |
---|---|
date | Mon, 28 Jun 2010 14:13:17 -0400 |
parents | 215576b54709 |
children | 5cbac8938c4c |
comparison
equal
deleted
inserted
replaced
1655:e7ec8cd4dd8a | 1656:4e5661ba9d98 |
---|---|
807 _g1->heap_region_par_iterate_chunked(&rebuild_rs, i, | 807 _g1->heap_region_par_iterate_chunked(&rebuild_rs, i, |
808 HeapRegion::RebuildRSClaimValue); | 808 HeapRegion::RebuildRSClaimValue); |
809 } | 809 } |
810 }; | 810 }; |
811 | 811 |
812 void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs, | 812 void G1CollectedHeap::do_collection(bool explicit_gc, |
813 bool clear_all_soft_refs, | |
813 size_t word_size) { | 814 size_t word_size) { |
814 if (GC_locker::check_active_before_gc()) { | 815 if (GC_locker::check_active_before_gc()) { |
815 return; // GC is disabled (e.g. JNI GetXXXCritical operation) | 816 return; // GC is disabled (e.g. JNI GetXXXCritical operation) |
816 } | 817 } |
817 | 818 |
819 | 820 |
820 if (PrintHeapAtGC) { | 821 if (PrintHeapAtGC) { |
821 Universe::print_heap_before_gc(); | 822 Universe::print_heap_before_gc(); |
822 } | 823 } |
823 | 824 |
824 if (full && DisableExplicitGC) { | |
825 return; | |
826 } | |
827 | |
828 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | 825 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); |
829 assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread"); | 826 assert(Thread::current() == VMThread::vm_thread(), "should be in vm thread"); |
830 | 827 |
831 const bool do_clear_all_soft_refs = clear_all_soft_refs || | 828 const bool do_clear_all_soft_refs = clear_all_soft_refs || |
832 collector_policy()->should_clear_all_soft_refs(); | 829 collector_policy()->should_clear_all_soft_refs(); |
835 | 832 |
836 { | 833 { |
837 IsGCActiveMark x; | 834 IsGCActiveMark x; |
838 | 835 |
839 // Timing | 836 // Timing |
837 bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc); | |
838 assert(!system_gc || explicit_gc, "invariant"); | |
840 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | 839 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
841 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | 840 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |
842 TraceTime t(full ? "Full GC (System.gc())" : "Full GC", | 841 TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC", |
843 PrintGC, true, gclog_or_tty); | 842 PrintGC, true, gclog_or_tty); |
844 | 843 |
845 TraceMemoryManagerStats tms(true /* fullGC */); | 844 TraceMemoryManagerStats tms(true /* fullGC */); |
846 | 845 |
847 double start = os::elapsedTime(); | 846 double start = os::elapsedTime(); |
942 // sets. We will also reset the GC time stamps of the regions. | 941 // sets. We will also reset the GC time stamps of the regions. |
943 PostMCRemSetClearClosure rs_clear(mr_bs()); | 942 PostMCRemSetClearClosure rs_clear(mr_bs()); |
944 heap_region_iterate(&rs_clear); | 943 heap_region_iterate(&rs_clear); |
945 | 944 |
946 // Resize the heap if necessary. | 945 // Resize the heap if necessary. |
947 resize_if_necessary_after_full_collection(full ? 0 : word_size); | 946 resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); |
948 | 947 |
949 if (_cg1r->use_cache()) { | 948 if (_cg1r->use_cache()) { |
950 _cg1r->clear_and_record_card_counts(); | 949 _cg1r->clear_and_record_card_counts(); |
951 _cg1r->clear_hot_cache(); | 950 _cg1r->clear_hot_cache(); |
952 } | 951 } |
1007 // entire heap tagged as young. | 1006 // entire heap tagged as young. |
1008 assert( check_young_list_empty(true /* check_heap */), | 1007 assert( check_young_list_empty(true /* check_heap */), |
1009 "young list should be empty at this point"); | 1008 "young list should be empty at this point"); |
1010 } | 1009 } |
1011 | 1010 |
1011 // Update the number of full collections that have been completed. | |
1012 increment_full_collections_completed(false /* outer */); | |
1013 | |
1012 if (PrintHeapAtGC) { | 1014 if (PrintHeapAtGC) { |
1013 Universe::print_heap_after_gc(); | 1015 Universe::print_heap_after_gc(); |
1014 } | 1016 } |
1015 } | 1017 } |
1016 | 1018 |
1017 void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { | 1019 void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { |
1018 do_collection(true, clear_all_soft_refs, 0); | 1020 do_collection(true, /* explicit_gc */ |
1021 clear_all_soft_refs, | |
1022 0 /* word_size */); | |
1019 } | 1023 } |
1020 | 1024 |
1021 // This code is mostly copied from TenuredGeneration. | 1025 // This code is mostly copied from TenuredGeneration. |
1022 void | 1026 void |
1023 G1CollectedHeap:: | 1027 G1CollectedHeap:: |
1329 _unclean_region_list(), | 1333 _unclean_region_list(), |
1330 _unclean_regions_coming(false), | 1334 _unclean_regions_coming(false), |
1331 _young_list(new YoungList(this)), | 1335 _young_list(new YoungList(this)), |
1332 _gc_time_stamp(0), | 1336 _gc_time_stamp(0), |
1333 _surviving_young_words(NULL), | 1337 _surviving_young_words(NULL), |
1338 _full_collections_completed(0), | |
1334 _in_cset_fast_test(NULL), | 1339 _in_cset_fast_test(NULL), |
1335 _in_cset_fast_test_base(NULL), | 1340 _in_cset_fast_test_base(NULL), |
1336 _dirty_cards_region_list(NULL) { | 1341 _dirty_cards_region_list(NULL) { |
1337 _g1h = this; // To catch bugs. | 1342 _g1h = this; // To catch bugs. |
1338 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { | 1343 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { |
1687 return 0; | 1692 return 0; |
1688 } | 1693 } |
1689 return car->free(); | 1694 return car->free(); |
1690 } | 1695 } |
1691 | 1696 |
1697 bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { | |
1698 return | |
1699 ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || | |
1700 (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); | |
1701 } | |
1702 | |
1703 void G1CollectedHeap::increment_full_collections_completed(bool outer) { | |
1704 MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); | |
1705 | |
1706 // We have already incremented _total_full_collections at the start | |
1707 // of the GC, so total_full_collections() represents how many full | |
1708 // collections have been started. | |
1709 unsigned int full_collections_started = total_full_collections(); | |
1710 | |
1711 // Given that this method is called at the end of a Full GC or of a | |
1712 // concurrent cycle, and those can be nested (i.e., a Full GC can | |
1713 // interrupt a concurrent cycle), the number of full collections | |
1714 // completed should be either one (in the case where there was no | |
1715 // nesting) or two (when a Full GC interrupted a concurrent cycle) | |
1716 // behind the number of full collections started. | |
1717 | |
1718 // This is the case for the inner caller, i.e. a Full GC. | |
1719 assert(outer || | |
1720 (full_collections_started == _full_collections_completed + 1) || | |
1721 (full_collections_started == _full_collections_completed + 2), | |
1722 err_msg("for inner caller: full_collections_started = %u " | |
1723 "is inconsistent with _full_collections_completed = %u", | |
1724 full_collections_started, _full_collections_completed)); | |
1725 | |
1726 // This is the case for the outer caller, i.e. the concurrent cycle. | |
1727 assert(!outer || | |
1728 (full_collections_started == _full_collections_completed + 1), | |
1729 err_msg("for outer caller: full_collections_started = %u " | |
1730 "is inconsistent with _full_collections_completed = %u", | |
1731 full_collections_started, _full_collections_completed)); | |
1732 | |
1733 _full_collections_completed += 1; | |
1734 | |
1735 // This notify_all() will ensure that a thread that called | |
1736 // System.gc() with (with ExplicitGCInvokesConcurrent set or not) | |
1737 // and it's waiting for a full GC to finish will be woken up. It is | |
1738 // waiting in VM_G1IncCollectionPause::doit_epilogue(). | |
1739 FullGCCount_lock->notify_all(); | |
1740 } | |
1741 | |
1692 void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { | 1742 void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { |
1693 assert(Thread::current()->is_VM_thread(), "Precondition#1"); | 1743 assert(Thread::current()->is_VM_thread(), "Precondition#1"); |
1694 assert(Heap_lock->is_locked(), "Precondition#2"); | 1744 assert(Heap_lock->is_locked(), "Precondition#2"); |
1695 GCCauseSetter gcs(this, cause); | 1745 GCCauseSetter gcs(this, cause); |
1696 switch (cause) { | 1746 switch (cause) { |
1707 | 1757 |
1708 void G1CollectedHeap::collect(GCCause::Cause cause) { | 1758 void G1CollectedHeap::collect(GCCause::Cause cause) { |
1709 // The caller doesn't have the Heap_lock | 1759 // The caller doesn't have the Heap_lock |
1710 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); | 1760 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); |
1711 | 1761 |
1712 int gc_count_before; | 1762 unsigned int gc_count_before; |
1763 unsigned int full_gc_count_before; | |
1713 { | 1764 { |
1714 MutexLocker ml(Heap_lock); | 1765 MutexLocker ml(Heap_lock); |
1715 // Read the GC count while holding the Heap_lock | 1766 // Read the GC count while holding the Heap_lock |
1716 gc_count_before = SharedHeap::heap()->total_collections(); | 1767 gc_count_before = SharedHeap::heap()->total_collections(); |
1768 full_gc_count_before = SharedHeap::heap()->total_full_collections(); | |
1717 | 1769 |
1718 // Don't want to do a GC until cleanup is completed. | 1770 // Don't want to do a GC until cleanup is completed. |
1719 wait_for_cleanup_complete(); | 1771 wait_for_cleanup_complete(); |
1720 } // We give up heap lock; VMThread::execute gets it back below | 1772 |
1721 switch (cause) { | 1773 // We give up heap lock; VMThread::execute gets it back below |
1722 case GCCause::_scavenge_alot: { | 1774 } |
1723 // Do an incremental pause, which might sometimes be abandoned. | 1775 |
1724 VM_G1IncCollectionPause op(gc_count_before, cause); | 1776 if (should_do_concurrent_full_gc(cause)) { |
1777 // Schedule an initial-mark evacuation pause that will start a | |
1778 // concurrent cycle. | |
1779 VM_G1IncCollectionPause op(gc_count_before, | |
1780 true, /* should_initiate_conc_mark */ | |
1781 g1_policy()->max_pause_time_ms(), | |
1782 cause); | |
1783 VMThread::execute(&op); | |
1784 } else { | |
1785 if (cause == GCCause::_gc_locker | |
1786 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { | |
1787 | |
1788 // Schedule a standard evacuation pause. | |
1789 VM_G1IncCollectionPause op(gc_count_before, | |
1790 false, /* should_initiate_conc_mark */ | |
1791 g1_policy()->max_pause_time_ms(), | |
1792 cause); | |
1725 VMThread::execute(&op); | 1793 VMThread::execute(&op); |
1726 break; | 1794 } else { |
1727 } | 1795 // Schedule a Full GC. |
1728 default: { | 1796 VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause); |
1729 // In all other cases, we currently do a full gc. | |
1730 VM_G1CollectFull op(gc_count_before, cause); | |
1731 VMThread::execute(&op); | 1797 VMThread::execute(&op); |
1732 } | 1798 } |
1733 } | 1799 } |
1734 } | 1800 } |
1735 | 1801 |
1987 } | 2053 } |
1988 } | 2054 } |
1989 | 2055 |
1990 void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, | 2056 void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, |
1991 HeapRegionClosure *cl) { | 2057 HeapRegionClosure *cl) { |
2058 if (r == NULL) { | |
2059 // The CSet is empty so there's nothing to do. | |
2060 return; | |
2061 } | |
2062 | |
1992 assert(r->in_collection_set(), | 2063 assert(r->in_collection_set(), |
1993 "Start region must be a member of the collection set."); | 2064 "Start region must be a member of the collection set."); |
1994 HeapRegion* cur = r; | 2065 HeapRegion* cur = r; |
1995 while (cur != NULL) { | 2066 while (cur != NULL) { |
1996 HeapRegion* next = cur->next_in_collection_set(); | 2067 HeapRegion* next = cur->next_in_collection_set(); |
2479 "derived pointer present")); | 2550 "derived pointer present")); |
2480 // always_do_update_barrier = true; | 2551 // always_do_update_barrier = true; |
2481 } | 2552 } |
2482 | 2553 |
2483 void G1CollectedHeap::do_collection_pause() { | 2554 void G1CollectedHeap::do_collection_pause() { |
2555 assert(Heap_lock->owned_by_self(), "we assume we'reholding the Heap_lock"); | |
2556 | |
2484 // Read the GC count while holding the Heap_lock | 2557 // Read the GC count while holding the Heap_lock |
2485 // we need to do this _before_ wait_for_cleanup_complete(), to | 2558 // we need to do this _before_ wait_for_cleanup_complete(), to |
2486 // ensure that we do not give up the heap lock and potentially | 2559 // ensure that we do not give up the heap lock and potentially |
2487 // pick up the wrong count | 2560 // pick up the wrong count |
2488 int gc_count_before = SharedHeap::heap()->total_collections(); | 2561 unsigned int gc_count_before = SharedHeap::heap()->total_collections(); |
2489 | 2562 |
2490 // Don't want to do a GC pause while cleanup is being completed! | 2563 // Don't want to do a GC pause while cleanup is being completed! |
2491 wait_for_cleanup_complete(); | 2564 wait_for_cleanup_complete(); |
2492 | 2565 |
2493 g1_policy()->record_stop_world_start(); | 2566 g1_policy()->record_stop_world_start(); |
2494 { | 2567 { |
2495 MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back | 2568 MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back |
2496 VM_G1IncCollectionPause op(gc_count_before); | 2569 VM_G1IncCollectionPause op(gc_count_before, |
2570 false, /* should_initiate_conc_mark */ | |
2571 g1_policy()->max_pause_time_ms(), | |
2572 GCCause::_g1_inc_collection_pause); | |
2497 VMThread::execute(&op); | 2573 VMThread::execute(&op); |
2498 } | 2574 } |
2499 } | 2575 } |
2500 | 2576 |
2501 void | 2577 void |
2610 return false; | 2686 return false; |
2611 } | 2687 } |
2612 }; | 2688 }; |
2613 | 2689 |
2614 void | 2690 void |
2615 G1CollectedHeap::do_collection_pause_at_safepoint() { | 2691 G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { |
2616 if (GC_locker::check_active_before_gc()) { | 2692 if (GC_locker::check_active_before_gc()) { |
2617 return; // GC is disabled (e.g. JNI GetXXXCritical operation) | 2693 return; // GC is disabled (e.g. JNI GetXXXCritical operation) |
2618 } | 2694 } |
2619 | 2695 |
2620 if (PrintHeapAtGC) { | 2696 if (PrintHeapAtGC) { |
2635 if (g1_policy()->full_young_gcs()) | 2711 if (g1_policy()->full_young_gcs()) |
2636 strcat(verbose_str, "(young)"); | 2712 strcat(verbose_str, "(young)"); |
2637 else | 2713 else |
2638 strcat(verbose_str, "(partial)"); | 2714 strcat(verbose_str, "(partial)"); |
2639 } | 2715 } |
2640 if (g1_policy()->during_initial_mark_pause()) | 2716 if (g1_policy()->during_initial_mark_pause()) { |
2641 strcat(verbose_str, " (initial-mark)"); | 2717 strcat(verbose_str, " (initial-mark)"); |
2718 // We are about to start a marking cycle, so we increment the | |
2719 // full collection counter. | |
2720 increment_total_full_collections(); | |
2721 } | |
2642 | 2722 |
2643 // if PrintGCDetails is on, we'll print long statistics information | 2723 // if PrintGCDetails is on, we'll print long statistics information |
2644 // in the collector policy code, so let's not print this as the output | 2724 // in the collector policy code, so let's not print this as the output |
2645 // is messy if we do. | 2725 // is messy if we do. |
2646 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | 2726 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
2659 if (g1_policy()->in_young_gc_mode()) { | 2739 if (g1_policy()->in_young_gc_mode()) { |
2660 assert(check_young_list_well_formed(), | 2740 assert(check_young_list_well_formed(), |
2661 "young list should be well formed"); | 2741 "young list should be well formed"); |
2662 } | 2742 } |
2663 | 2743 |
2664 bool abandoned = false; | |
2665 { // Call to jvmpi::post_class_unload_events must occur outside of active GC | 2744 { // Call to jvmpi::post_class_unload_events must occur outside of active GC |
2666 IsGCActiveMark x; | 2745 IsGCActiveMark x; |
2667 | 2746 |
2668 gc_prologue(false); | 2747 gc_prologue(false); |
2669 increment_total_collections(false /* full gc */); | 2748 increment_total_collections(false /* full gc */); |
2741 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); | 2820 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
2742 #endif // YOUNG_LIST_VERBOSE | 2821 #endif // YOUNG_LIST_VERBOSE |
2743 | 2822 |
2744 // Now choose the CS. We may abandon a pause if we find no | 2823 // Now choose the CS. We may abandon a pause if we find no |
2745 // region that will fit in the MMU pause. | 2824 // region that will fit in the MMU pause. |
2746 bool abandoned = g1_policy()->choose_collection_set(); | 2825 bool abandoned = g1_policy()->choose_collection_set(target_pause_time_ms); |
2747 | 2826 |
2748 // Nothing to do if we were unable to choose a collection set. | 2827 // Nothing to do if we were unable to choose a collection set. |
2749 if (!abandoned) { | 2828 if (!abandoned) { |
2750 #if G1_REM_SET_LOGGING | 2829 #if G1_REM_SET_LOGGING |
2751 gclog_or_tty->print_cr("\nAfter pause, heap:"); | 2830 gclog_or_tty->print_cr("\nAfter pause, heap:"); |