Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3772:6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
Summary: Perform a heap verification after the first phase of G1's full GC using objects' mark words to determine liveness. The third parameter of the heap verification routines, which was used in G1 to determine which marking bitmap to use in liveness calculations, has been changed from a boolean to an enum with values defined for using the mark word, and the 'prev' and 'next' bitmaps.
Reviewed-by: tonyp, ysr
author | johnc |
---|---|
date | Tue, 14 Jun 2011 11:01:10 -0700 |
parents | c3f1170908be |
children | c9ca3f51cf41 |
comparison
equal
deleted
inserted
replaced
3771:842b840e67db | 3772:6747fd0512e0 |
---|---|
1209 | 1209 |
1210 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { | 1210 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { |
1211 HandleMark hm; // Discard invalid handles created during verification | 1211 HandleMark hm; // Discard invalid handles created during verification |
1212 gclog_or_tty->print(" VerifyBeforeGC:"); | 1212 gclog_or_tty->print(" VerifyBeforeGC:"); |
1213 prepare_for_verify(); | 1213 prepare_for_verify(); |
1214 Universe::verify(true); | 1214 Universe::verify(/* allow dirty */ true, |
1215 /* silent */ false, | |
1216 /* option */ VerifyOption_G1UsePrevMarking); | |
1217 | |
1215 } | 1218 } |
1216 | 1219 |
1217 COMPILER2_PRESENT(DerivedPointerTable::clear()); | 1220 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
1218 | 1221 |
1219 // We want to discover references, but not process them yet. | 1222 // We want to discover references, but not process them yet. |
1261 // Temporarily clear _is_alive_non_header | 1264 // Temporarily clear _is_alive_non_header |
1262 ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL); | 1265 ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL); |
1263 | 1266 |
1264 ref_processor()->enable_discovery(); | 1267 ref_processor()->enable_discovery(); |
1265 ref_processor()->setup_policy(do_clear_all_soft_refs); | 1268 ref_processor()->setup_policy(do_clear_all_soft_refs); |
1266 | |
1267 // Do collection work | 1269 // Do collection work |
1268 { | 1270 { |
1269 HandleMark hm; // Discard invalid handles created during gc | 1271 HandleMark hm; // Discard invalid handles created during gc |
1270 G1MarkSweep::invoke_at_safepoint(ref_processor(), do_clear_all_soft_refs); | 1272 G1MarkSweep::invoke_at_safepoint(ref_processor(), do_clear_all_soft_refs); |
1271 } | 1273 } |
1282 | 1284 |
1283 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { | 1285 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
1284 HandleMark hm; // Discard invalid handles created during verification | 1286 HandleMark hm; // Discard invalid handles created during verification |
1285 gclog_or_tty->print(" VerifyAfterGC:"); | 1287 gclog_or_tty->print(" VerifyAfterGC:"); |
1286 prepare_for_verify(); | 1288 prepare_for_verify(); |
1287 Universe::verify(false); | 1289 Universe::verify(/* allow dirty */ false, |
1290 /* silent */ false, | |
1291 /* option */ VerifyOption_G1UsePrevMarking); | |
1292 | |
1288 } | 1293 } |
1289 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); | 1294 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); |
1290 | 1295 |
1291 reset_gc_time_stamp(); | 1296 reset_gc_time_stamp(); |
1292 // Since everything potentially moved, we will clear all remembered | 1297 // Since everything potentially moved, we will clear all remembered |
2637 } | 2642 } |
2638 g1_rem_set()->prepare_for_verify(); | 2643 g1_rem_set()->prepare_for_verify(); |
2639 } | 2644 } |
2640 | 2645 |
2641 class VerifyLivenessOopClosure: public OopClosure { | 2646 class VerifyLivenessOopClosure: public OopClosure { |
2642 G1CollectedHeap* g1h; | 2647 G1CollectedHeap* _g1h; |
2648 VerifyOption _vo; | |
2643 public: | 2649 public: |
2644 VerifyLivenessOopClosure(G1CollectedHeap* _g1h) { | 2650 VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo): |
2645 g1h = _g1h; | 2651 _g1h(g1h), _vo(vo) |
2646 } | 2652 { } |
2647 void do_oop(narrowOop *p) { do_oop_work(p); } | 2653 void do_oop(narrowOop *p) { do_oop_work(p); } |
2648 void do_oop( oop *p) { do_oop_work(p); } | 2654 void do_oop( oop *p) { do_oop_work(p); } |
2649 | 2655 |
2650 template <class T> void do_oop_work(T *p) { | 2656 template <class T> void do_oop_work(T *p) { |
2651 oop obj = oopDesc::load_decode_heap_oop(p); | 2657 oop obj = oopDesc::load_decode_heap_oop(p); |
2652 guarantee(obj == NULL || !g1h->is_obj_dead(obj), | 2658 guarantee(obj == NULL || !_g1h->is_obj_dead_cond(obj, _vo), |
2653 "Dead object referenced by a not dead object"); | 2659 "Dead object referenced by a not dead object"); |
2654 } | 2660 } |
2655 }; | 2661 }; |
2656 | 2662 |
2657 class VerifyObjsInRegionClosure: public ObjectClosure { | 2663 class VerifyObjsInRegionClosure: public ObjectClosure { |
2658 private: | 2664 private: |
2659 G1CollectedHeap* _g1h; | 2665 G1CollectedHeap* _g1h; |
2660 size_t _live_bytes; | 2666 size_t _live_bytes; |
2661 HeapRegion *_hr; | 2667 HeapRegion *_hr; |
2662 bool _use_prev_marking; | 2668 VerifyOption _vo; |
2663 public: | 2669 public: |
2664 // use_prev_marking == true -> use "prev" marking information, | 2670 // _vo == UsePrevMarking -> use "prev" marking information, |
2665 // use_prev_marking == false -> use "next" marking information | 2671 // _vo == UseNextMarking -> use "next" marking information, |
2666 VerifyObjsInRegionClosure(HeapRegion *hr, bool use_prev_marking) | 2672 // _vo == UseMarkWord -> use mark word from object header. |
2667 : _live_bytes(0), _hr(hr), _use_prev_marking(use_prev_marking) { | 2673 VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo) |
2674 : _live_bytes(0), _hr(hr), _vo(vo) { | |
2668 _g1h = G1CollectedHeap::heap(); | 2675 _g1h = G1CollectedHeap::heap(); |
2669 } | 2676 } |
2670 void do_object(oop o) { | 2677 void do_object(oop o) { |
2671 VerifyLivenessOopClosure isLive(_g1h); | 2678 VerifyLivenessOopClosure isLive(_g1h, _vo); |
2672 assert(o != NULL, "Huh?"); | 2679 assert(o != NULL, "Huh?"); |
2673 if (!_g1h->is_obj_dead_cond(o, _use_prev_marking)) { | 2680 if (!_g1h->is_obj_dead_cond(o, _vo)) { |
2681 // If the object is alive according to the mark word, | |
2682 // then verify that the marking information agrees. | |
2683 // Note we can't verify the contra-positive of the | |
2684 // above: if the object is dead (according to the mark | |
2685 // word), it may not be marked, or may have been marked | |
2686 // but has since became dead, or may have been allocated | |
2687 // since the last marking. | |
2688 if (_vo == VerifyOption_G1UseMarkWord) { | |
2689 guarantee(!_g1h->is_obj_dead(o), "mark word and concurrent mark mismatch"); | |
2690 } | |
2691 | |
2674 o->oop_iterate(&isLive); | 2692 o->oop_iterate(&isLive); |
2675 if (!_hr->obj_allocated_since_prev_marking(o)) { | 2693 if (!_hr->obj_allocated_since_prev_marking(o)) { |
2676 size_t obj_size = o->size(); // Make sure we don't overflow | 2694 size_t obj_size = o->size(); // Make sure we don't overflow |
2677 _live_bytes += (obj_size * HeapWordSize); | 2695 _live_bytes += (obj_size * HeapWordSize); |
2678 } | 2696 } |
2710 } | 2728 } |
2711 }; | 2729 }; |
2712 | 2730 |
2713 class VerifyRegionClosure: public HeapRegionClosure { | 2731 class VerifyRegionClosure: public HeapRegionClosure { |
2714 private: | 2732 private: |
2715 bool _allow_dirty; | 2733 bool _allow_dirty; |
2716 bool _par; | 2734 bool _par; |
2717 bool _use_prev_marking; | 2735 VerifyOption _vo; |
2718 bool _failures; | 2736 bool _failures; |
2719 public: | 2737 public: |
2720 // use_prev_marking == true -> use "prev" marking information, | 2738 // _vo == UsePrevMarking -> use "prev" marking information, |
2721 // use_prev_marking == false -> use "next" marking information | 2739 // _vo == UseNextMarking -> use "next" marking information, |
2722 VerifyRegionClosure(bool allow_dirty, bool par, bool use_prev_marking) | 2740 // _vo == UseMarkWord -> use mark word from object header. |
2741 VerifyRegionClosure(bool allow_dirty, bool par, VerifyOption vo) | |
2723 : _allow_dirty(allow_dirty), | 2742 : _allow_dirty(allow_dirty), |
2724 _par(par), | 2743 _par(par), |
2725 _use_prev_marking(use_prev_marking), | 2744 _vo(vo), |
2726 _failures(false) {} | 2745 _failures(false) {} |
2727 | 2746 |
2728 bool failures() { | 2747 bool failures() { |
2729 return _failures; | 2748 return _failures; |
2730 } | 2749 } |
2732 bool doHeapRegion(HeapRegion* r) { | 2751 bool doHeapRegion(HeapRegion* r) { |
2733 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, | 2752 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, |
2734 "Should be unclaimed at verify points."); | 2753 "Should be unclaimed at verify points."); |
2735 if (!r->continuesHumongous()) { | 2754 if (!r->continuesHumongous()) { |
2736 bool failures = false; | 2755 bool failures = false; |
2737 r->verify(_allow_dirty, _use_prev_marking, &failures); | 2756 r->verify(_allow_dirty, _vo, &failures); |
2738 if (failures) { | 2757 if (failures) { |
2739 _failures = true; | 2758 _failures = true; |
2740 } else { | 2759 } else { |
2741 VerifyObjsInRegionClosure not_dead_yet_cl(r, _use_prev_marking); | 2760 VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); |
2742 r->object_iterate(¬_dead_yet_cl); | 2761 r->object_iterate(¬_dead_yet_cl); |
2743 if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { | 2762 if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { |
2744 gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " | 2763 gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " |
2745 "max_live_bytes "SIZE_FORMAT" " | 2764 "max_live_bytes "SIZE_FORMAT" " |
2746 "< calculated "SIZE_FORMAT, | 2765 "< calculated "SIZE_FORMAT, |
2756 }; | 2775 }; |
2757 | 2776 |
2758 class VerifyRootsClosure: public OopsInGenClosure { | 2777 class VerifyRootsClosure: public OopsInGenClosure { |
2759 private: | 2778 private: |
2760 G1CollectedHeap* _g1h; | 2779 G1CollectedHeap* _g1h; |
2761 bool _use_prev_marking; | 2780 VerifyOption _vo; |
2762 bool _failures; | 2781 bool _failures; |
2763 public: | 2782 public: |
2764 // use_prev_marking == true -> use "prev" marking information, | 2783 // _vo == UsePrevMarking -> use "prev" marking information, |
2765 // use_prev_marking == false -> use "next" marking information | 2784 // _vo == UseNextMarking -> use "next" marking information, |
2766 VerifyRootsClosure(bool use_prev_marking) : | 2785 // _vo == UseMarkWord -> use mark word from object header. |
2786 VerifyRootsClosure(VerifyOption vo) : | |
2767 _g1h(G1CollectedHeap::heap()), | 2787 _g1h(G1CollectedHeap::heap()), |
2768 _use_prev_marking(use_prev_marking), | 2788 _vo(vo), |
2769 _failures(false) { } | 2789 _failures(false) { } |
2770 | 2790 |
2771 bool failures() { return _failures; } | 2791 bool failures() { return _failures; } |
2772 | 2792 |
2773 template <class T> void do_oop_nv(T* p) { | 2793 template <class T> void do_oop_nv(T* p) { |
2774 T heap_oop = oopDesc::load_heap_oop(p); | 2794 T heap_oop = oopDesc::load_heap_oop(p); |
2775 if (!oopDesc::is_null(heap_oop)) { | 2795 if (!oopDesc::is_null(heap_oop)) { |
2776 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | 2796 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
2777 if (_g1h->is_obj_dead_cond(obj, _use_prev_marking)) { | 2797 if (_g1h->is_obj_dead_cond(obj, _vo)) { |
2778 gclog_or_tty->print_cr("Root location "PTR_FORMAT" " | 2798 gclog_or_tty->print_cr("Root location "PTR_FORMAT" " |
2779 "points to dead obj "PTR_FORMAT, p, (void*) obj); | 2799 "points to dead obj "PTR_FORMAT, p, (void*) obj); |
2800 if (_vo == VerifyOption_G1UseMarkWord) { | |
2801 gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark())); | |
2802 } | |
2780 obj->print_on(gclog_or_tty); | 2803 obj->print_on(gclog_or_tty); |
2781 _failures = true; | 2804 _failures = true; |
2782 } | 2805 } |
2783 } | 2806 } |
2784 } | 2807 } |
2790 // This is the task used for parallel heap verification. | 2813 // This is the task used for parallel heap verification. |
2791 | 2814 |
2792 class G1ParVerifyTask: public AbstractGangTask { | 2815 class G1ParVerifyTask: public AbstractGangTask { |
2793 private: | 2816 private: |
2794 G1CollectedHeap* _g1h; | 2817 G1CollectedHeap* _g1h; |
2795 bool _allow_dirty; | 2818 bool _allow_dirty; |
2796 bool _use_prev_marking; | 2819 VerifyOption _vo; |
2797 bool _failures; | 2820 bool _failures; |
2798 | 2821 |
2799 public: | 2822 public: |
2800 // use_prev_marking == true -> use "prev" marking information, | 2823 // _vo == UsePrevMarking -> use "prev" marking information, |
2801 // use_prev_marking == false -> use "next" marking information | 2824 // _vo == UseNextMarking -> use "next" marking information, |
2802 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, | 2825 // _vo == UseMarkWord -> use mark word from object header. |
2803 bool use_prev_marking) : | 2826 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, VerifyOption vo) : |
2804 AbstractGangTask("Parallel verify task"), | 2827 AbstractGangTask("Parallel verify task"), |
2805 _g1h(g1h), | 2828 _g1h(g1h), |
2806 _allow_dirty(allow_dirty), | 2829 _allow_dirty(allow_dirty), |
2807 _use_prev_marking(use_prev_marking), | 2830 _vo(vo), |
2808 _failures(false) { } | 2831 _failures(false) { } |
2809 | 2832 |
2810 bool failures() { | 2833 bool failures() { |
2811 return _failures; | 2834 return _failures; |
2812 } | 2835 } |
2813 | 2836 |
2814 void work(int worker_i) { | 2837 void work(int worker_i) { |
2815 HandleMark hm; | 2838 HandleMark hm; |
2816 VerifyRegionClosure blk(_allow_dirty, true, _use_prev_marking); | 2839 VerifyRegionClosure blk(_allow_dirty, true, _vo); |
2817 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, | 2840 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, |
2818 HeapRegion::ParVerifyClaimValue); | 2841 HeapRegion::ParVerifyClaimValue); |
2819 if (blk.failures()) { | 2842 if (blk.failures()) { |
2820 _failures = true; | 2843 _failures = true; |
2821 } | 2844 } |
2822 } | 2845 } |
2823 }; | 2846 }; |
2824 | 2847 |
2825 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { | 2848 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { |
2826 verify(allow_dirty, silent, /* use_prev_marking */ true); | 2849 verify(allow_dirty, silent, VerifyOption_G1UsePrevMarking); |
2827 } | 2850 } |
2828 | 2851 |
2829 void G1CollectedHeap::verify(bool allow_dirty, | 2852 void G1CollectedHeap::verify(bool allow_dirty, |
2830 bool silent, | 2853 bool silent, |
2831 bool use_prev_marking) { | 2854 VerifyOption vo) { |
2832 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { | 2855 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { |
2833 if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } | 2856 if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } |
2834 VerifyRootsClosure rootsCl(use_prev_marking); | 2857 VerifyRootsClosure rootsCl(vo); |
2835 CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); | 2858 CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); |
2859 | |
2836 // We apply the relevant closures to all the oops in the | 2860 // We apply the relevant closures to all the oops in the |
2837 // system dictionary, the string table and the code cache. | 2861 // system dictionary, the string table and the code cache. |
2838 const int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; | 2862 const int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; |
2863 | |
2839 process_strong_roots(true, // activate StrongRootsScope | 2864 process_strong_roots(true, // activate StrongRootsScope |
2840 true, // we set "collecting perm gen" to true, | 2865 true, // we set "collecting perm gen" to true, |
2841 // so we don't reset the dirty cards in the perm gen. | 2866 // so we don't reset the dirty cards in the perm gen. |
2842 SharedHeap::ScanningOption(so), // roots scanning options | 2867 SharedHeap::ScanningOption(so), // roots scanning options |
2843 &rootsCl, | 2868 &rootsCl, |
2844 &blobsCl, | 2869 &blobsCl, |
2845 &rootsCl); | 2870 &rootsCl); |
2846 // Since we used "collecting_perm_gen" == true above, we will not have | 2871 |
2847 // checked the refs from perm into the G1-collected heap. We check those | 2872 // If we're verifying after the marking phase of a Full GC then we can't |
2848 // references explicitly below. Whether the relevant cards are dirty | 2873 // treat the perm gen as roots into the G1 heap. Some of the objects in |
2849 // is checked further below in the rem set verification. | 2874 // the perm gen may be dead and hence not marked. If one of these dead |
2850 if (!silent) { gclog_or_tty->print("Permgen roots "); } | 2875 // objects is considered to be a root then we may end up with a false |
2851 perm_gen()->oop_iterate(&rootsCl); | 2876 // "Root location <x> points to dead ob <y>" failure. |
2877 if (vo != VerifyOption_G1UseMarkWord) { | |
2878 // Since we used "collecting_perm_gen" == true above, we will not have | |
2879 // checked the refs from perm into the G1-collected heap. We check those | |
2880 // references explicitly below. Whether the relevant cards are dirty | |
2881 // is checked further below in the rem set verification. | |
2882 if (!silent) { gclog_or_tty->print("Permgen roots "); } | |
2883 perm_gen()->oop_iterate(&rootsCl); | |
2884 } | |
2852 bool failures = rootsCl.failures(); | 2885 bool failures = rootsCl.failures(); |
2853 if (!silent) { gclog_or_tty->print("HeapRegionSets "); } | 2886 |
2854 verify_region_sets(); | 2887 if (vo != VerifyOption_G1UseMarkWord) { |
2888 // If we're verifying during a full GC then the region sets | |
2889 // will have been torn down at the start of the GC. Therefore | |
2890 // verifying the region sets will fail. So we only verify | |
2891 // the region sets when not in a full GC. | |
2892 if (!silent) { gclog_or_tty->print("HeapRegionSets "); } | |
2893 verify_region_sets(); | |
2894 } | |
2895 | |
2855 if (!silent) { gclog_or_tty->print("HeapRegions "); } | 2896 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
2856 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { | 2897 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
2857 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | 2898 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
2858 "sanity check"); | 2899 "sanity check"); |
2859 | 2900 |
2860 G1ParVerifyTask task(this, allow_dirty, use_prev_marking); | 2901 G1ParVerifyTask task(this, allow_dirty, vo); |
2861 int n_workers = workers()->total_workers(); | 2902 int n_workers = workers()->total_workers(); |
2862 set_par_threads(n_workers); | 2903 set_par_threads(n_workers); |
2863 workers()->run_task(&task); | 2904 workers()->run_task(&task); |
2864 set_par_threads(0); | 2905 set_par_threads(0); |
2865 if (task.failures()) { | 2906 if (task.failures()) { |
2872 reset_heap_region_claim_values(); | 2913 reset_heap_region_claim_values(); |
2873 | 2914 |
2874 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | 2915 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), |
2875 "sanity check"); | 2916 "sanity check"); |
2876 } else { | 2917 } else { |
2877 VerifyRegionClosure blk(allow_dirty, false, use_prev_marking); | 2918 VerifyRegionClosure blk(allow_dirty, false, vo); |
2878 heap_region_iterate(&blk); | 2919 heap_region_iterate(&blk); |
2879 if (blk.failures()) { | 2920 if (blk.failures()) { |
2880 failures = true; | 2921 failures = true; |
2881 } | 2922 } |
2882 } | 2923 } |
2888 print_on(gclog_or_tty, true /* extended */); | 2929 print_on(gclog_or_tty, true /* extended */); |
2889 gclog_or_tty->print_cr(""); | 2930 gclog_or_tty->print_cr(""); |
2890 #ifndef PRODUCT | 2931 #ifndef PRODUCT |
2891 if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { | 2932 if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { |
2892 concurrent_mark()->print_reachable("at-verification-failure", | 2933 concurrent_mark()->print_reachable("at-verification-failure", |
2893 use_prev_marking, false /* all */); | 2934 vo, false /* all */); |
2894 } | 2935 } |
2895 #endif | 2936 #endif |
2896 gclog_or_tty->flush(); | 2937 gclog_or_tty->flush(); |
2897 } | 2938 } |
2898 guarantee(!failures, "there should not have been any failures"); | 2939 guarantee(!failures, "there should not have been any failures"); |
3036 _cmThread->set_started(); | 3077 _cmThread->set_started(); |
3037 CGC_lock->notify(); | 3078 CGC_lock->notify(); |
3038 } | 3079 } |
3039 } | 3080 } |
3040 | 3081 |
3041 class VerifyMarkedObjsClosure: public ObjectClosure { | |
3042 G1CollectedHeap* _g1h; | |
3043 public: | |
3044 VerifyMarkedObjsClosure(G1CollectedHeap* g1h) : _g1h(g1h) {} | |
3045 void do_object(oop obj) { | |
3046 assert(obj->mark()->is_marked() ? !_g1h->is_obj_dead(obj) : true, | |
3047 "markandsweep mark should agree with concurrent deadness"); | |
3048 } | |
3049 }; | |
3050 | |
3051 void | |
3052 G1CollectedHeap::checkConcurrentMark() { | |
3053 VerifyMarkedObjsClosure verifycl(this); | |
3054 // MutexLockerEx x(getMarkBitMapLock(), | |
3055 // Mutex::_no_safepoint_check_flag); | |
3056 object_iterate(&verifycl, false); | |
3057 } | |
3058 | |
3059 void G1CollectedHeap::do_sync_mark() { | 3082 void G1CollectedHeap::do_sync_mark() { |
3060 _cm->checkpointRootsInitial(); | 3083 _cm->checkpointRootsInitial(); |
3061 _cm->markFromRoots(); | 3084 _cm->markFromRoots(); |
3062 _cm->checkpointRootsFinal(false); | 3085 _cm->checkpointRootsFinal(false); |
3063 } | 3086 } |
3250 | 3273 |
3251 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { | 3274 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { |
3252 HandleMark hm; // Discard invalid handles created during verification | 3275 HandleMark hm; // Discard invalid handles created during verification |
3253 gclog_or_tty->print(" VerifyBeforeGC:"); | 3276 gclog_or_tty->print(" VerifyBeforeGC:"); |
3254 prepare_for_verify(); | 3277 prepare_for_verify(); |
3255 Universe::verify(false); | 3278 Universe::verify(/* allow dirty */ false, |
3279 /* silent */ false, | |
3280 /* option */ VerifyOption_G1UsePrevMarking); | |
3281 | |
3256 } | 3282 } |
3257 | 3283 |
3258 COMPILER2_PRESENT(DerivedPointerTable::clear()); | 3284 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
3259 | 3285 |
3260 // Please see comment in G1CollectedHeap::ref_processing_init() | 3286 // Please see comment in G1CollectedHeap::ref_processing_init() |
3422 | 3448 |
3423 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { | 3449 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
3424 HandleMark hm; // Discard invalid handles created during verification | 3450 HandleMark hm; // Discard invalid handles created during verification |
3425 gclog_or_tty->print(" VerifyAfterGC:"); | 3451 gclog_or_tty->print(" VerifyAfterGC:"); |
3426 prepare_for_verify(); | 3452 prepare_for_verify(); |
3427 Universe::verify(false); | 3453 Universe::verify(/* allow dirty */ true, |
3454 /* silent */ false, | |
3455 /* option */ VerifyOption_G1UsePrevMarking); | |
3428 } | 3456 } |
3429 | 3457 |
3430 if (was_enabled) ref_processor()->enable_discovery(); | 3458 if (was_enabled) ref_processor()->enable_discovery(); |
3431 | 3459 |
3432 { | 3460 { |