# HG changeset patch # User tschatzl # Parent f4f92b3e910aef6e65679bbd110c6abcc149556e diff -r f4f92b3e910a src/hotspot/share/gc/g1/g1CollectedHeap.cpp --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Thu Jul 09 16:22:23 2020 +0200 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp Fri Jul 10 12:55:51 2020 +0200 @@ -3034,6 +3034,8 @@ evacuate_optional_collection_set(&per_thread_states); } post_evacuate_collection_set(evacuation_info, &rdcqs, &per_thread_states); + log_debug(gc)("after"); + verify_eden_objects(); start_new_collection_set(); @@ -3834,7 +3836,60 @@ { } }; +class G1VerifyEdenTask : public AbstractGangTask { + HeapRegionClaimer _hrclaimer; + class G1VerifyEdenClosure : public HeapRegionClosure { + class G1VerifyEdenObjClosure : public BasicOopIterateClosure { + public: + virtual void do_oop(narrowOop* p) { do_oop_work(p); } + virtual void do_oop( oop* p) { do_oop_work(p); } + template void do_oop_work(T* p) { + T heap_oop = RawAccess<>::oop_load(p); + if (CompressedOops::is_null(heap_oop)) { + return; + } + + oop o = CompressedOops::decode_not_null(heap_oop); + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + assert(g1h->is_in(o), "must be r %u oop " PTR_FORMAT, g1h->heap_region_containing(o)->hrm_index(), p2i(o)); + + assert(oopDesc::is_oop(o), "must be r %u oop " PTR_FORMAT, g1h->heap_region_containing(o)->hrm_index(), p2i(o)); + Klass* k = o->klass(); + assert(k->is_klass(), "must be r %u klass " PTR_FORMAT " " PTR_FORMAT, g1h->heap_region_containing(o)->hrm_index(), p2i(o), p2i(k)); + assert(k->id() <= ObjArrayKlassID, "must be r %u objarrayklassid " PTR_FORMAT " " PTR_FORMAT " id %d", g1h->heap_region_containing(o)->hrm_index(), p2i(o), p2i(k), k->id()); + } + } cl; + public: + bool do_heap_region(HeapRegion* r) { + if (!r->is_young()) { return false; } + for (HeapWord* cur = r->bottom(); cur < r->top(); ) { + oop o = (oop)cur; + assert(oopDesc::is_oop(o), "must be r %u oop " PTR_FORMAT, r->hrm_index(), p2i(o)); + Klass* k = o->klass(); + assert(k->is_klass(), "must be r %u klass " PTR_FORMAT " " PTR_FORMAT, r->hrm_index(), p2i(o), p2i(k)); + assert(k->id() <= ObjArrayKlassID, "must be r %u objarrayklassid " PTR_FORMAT " " PTR_FORMAT " id %d", r->hrm_index(), p2i(o), p2i(k), k->id()); + o->oop_iterate(&cl); + cur += o->size(); + } + return false; + } + }; +public: + G1VerifyEdenTask(uint num_workers) : AbstractGangTask("verify eden"), _hrclaimer(num_workers) {} + void work(uint worker_id) { + G1VerifyEdenClosure cl; + G1CollectedHeap::heap()->heap_region_par_iterate_from_start(&cl, &_hrclaimer); + } +}; + +void G1CollectedHeap::verify_eden_objects() { + G1VerifyEdenTask cl(_workers->active_workers()); + run_task(&cl); +} + void G1CollectedHeap::evacuate_initial_collection_set(G1ParScanThreadStateSet* per_thread_states) { + log_debug(gc)("before"); + verify_eden_objects(); G1GCPhaseTimes* p = phase_times(); { diff -r f4f92b3e910a src/hotspot/share/gc/g1/g1CollectedHeap.hpp --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Thu Jul 09 16:22:23 2020 +0200 +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp Fri Jul 10 12:55:51 2020 +0200 @@ -776,6 +776,7 @@ void calculate_collection_set(G1EvacuationInfo& evacuation_info, double target_pause_time_ms); + void verify_eden_objects(); // Actually do the work of evacuating the parts of the collection set. void evacuate_initial_collection_set(G1ParScanThreadStateSet* per_thread_states); void evacuate_optional_collection_set(G1ParScanThreadStateSet* per_thread_states); diff -r f4f92b3e910a src/hotspot/share/gc/g1/g1ParScanThreadState.cpp --- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Thu Jul 09 16:22:23 2020 +0200 +++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp Fri Jul 10 12:55:51 2020 +0200 @@ -119,12 +119,41 @@ } #ifdef ASSERT + +class IsObjClosure : public OopIterateClosure { +public: + void do_oop(oop* p) { + oop o = RawAccess<>::oop_load(p); + if (o == NULL) { return ; } + assert(G1CollectedHeap::heap()->is_in_g1_reserved(o), + "p=" PTR_FORMAT " o=" PTR_FORMAT, p2i(p), p2i(o)); + assert(oopDesc::is_oop(o), "must be"); + } + + void do_oop(narrowOop* p) { + oop o = RawAccess<>::oop_load(p); + if (o == NULL) { return ; } + assert(G1CollectedHeap::heap()->is_in_g1_reserved(o), + "p=" PTR_FORMAT " o=" PTR_FORMAT, p2i(p), p2i(o)); + assert(oopDesc::is_oop(o), "must be"); + } + + virtual bool do_metadata() { return false; } + virtual void do_klass(Klass* k) { } + virtual void do_cld(ClassLoaderData* cld) { } + +}; + void G1ParScanThreadState::verify_task(narrowOop* task) const { assert(task != NULL, "invariant"); assert(UseCompressedOops, "sanity"); oop p = RawAccess<>::oop_load(task); assert(_g1h->is_in_g1_reserved(p), "task=" PTR_FORMAT " p=" PTR_FORMAT, p2i(task), p2i(p)); + assert(oopDesc::is_oop(p), "must be"); + + IsObjClosure cl; + p->oop_iterate(&cl); } void G1ParScanThreadState::verify_task(oop* task) const { @@ -132,6 +161,10 @@ oop p = RawAccess<>::oop_load(task); assert(_g1h->is_in_g1_reserved(p), "task=" PTR_FORMAT " p=" PTR_FORMAT, p2i(task), p2i(p)); + assert(oopDesc::is_oop(p), "must be"); + + IsObjClosure cl; + p->oop_iterate(&cl); } void G1ParScanThreadState::verify_task(PartialArrayScanTask task) const { diff -r f4f92b3e910a src/hotspot/share/gc/g1/heapRegion.cpp --- a/src/hotspot/share/gc/g1/heapRegion.cpp Thu Jul 09 16:22:23 2020 +0200 +++ b/src/hotspot/share/gc/g1/heapRegion.cpp Fri Jul 10 12:55:51 2020 +0200 @@ -526,6 +526,13 @@ virtual void do_oop(narrowOop* p) { do_oop_work(p); } virtual void do_oop(oop* p) { do_oop_work(p); } + virtual bool do_metadata() { return true; } + virtual void do_cld(ClassLoaderData* cld) { return; } + virtual void do_klass(Klass* k) { + assert(k->id() <= ObjArrayKlassID, "klass id for " PTR_FORMAT" is %d", p2i(k), k->id()); + assert(k->super() == NULL || Metaspace::contains(k->super()), "klass super for " PTR_FORMAT" is " PTR_FORMAT, p2i(k), p2i(k->super())); + } + template void do_oop_work(T* p) { assert(_containing_obj != NULL, "Precondition"); diff -r f4f92b3e910a src/hotspot/share/prims/stackwalk.cpp --- a/src/hotspot/share/prims/stackwalk.cpp Thu Jul 09 16:22:23 2020 +0200 +++ b/src/hotspot/share/prims/stackwalk.cpp Fri Jul 10 12:55:51 2020 +0200 @@ -28,6 +28,7 @@ #include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" +#include "memory/iterator.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.hpp" #include "oops/oop.inline.hpp" @@ -40,8 +41,28 @@ #include "runtime/vframe.inline.hpp" #include "utilities/globalDefinitions.hpp" + class ObjClosure : public BasicOopIterateClosure { + public: + void do_oop(narrowOop* o) { + // nothing to do + assert(Universe::heap()->is_in(o), "must be"); + } + void do_oop(oop* o) { + // nothing do + assert(Universe::heap()->is_in(o), "must be"); + } + } ; + +static void check_obj(oop obj) { + assert(oopDesc::is_oop_or_null(obj), "must be"); + if (obj == NULL) { return ; } + ObjClosure cl; + obj->oop_iterate(&cl); +} + // setup and cleanup actions void BaseFrameStream::setup_magic_on_entry(objArrayHandle frames_array) { + check_obj(_thread->threadObj()); frames_array->obj_at_put(magic_pos, _thread->threadObj()); _anchor = address_value(); assert(check_magic(frames_array), "invalid magic"); @@ -178,6 +199,7 @@ Handle stackFrame(THREAD, frames_array->obj_at(index)); fill_stackframe(stackFrame, method, CHECK); } else { + check_obj(method->method_holder()->java_mirror()); frames_array->obj_at_put(index, method->method_holder()->java_mirror()); } } @@ -260,6 +282,7 @@ #endif oop obj = create_primitive_slot_instance(values, index, type, CHECK_(empty)); if (obj != NULL) { + check_obj(obj); array_h->obj_at_put(i, obj); } } @@ -273,6 +296,7 @@ objArrayHandle array_h(THREAD, array_oop); for (int i = 0; i < length; i++) { MonitorInfo* monitor = monitors->at(i); + check_obj(monitor->owner()); array_h->obj_at_put(i, monitor->owner()); } return array_h;