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 } |
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()) { |