< prev index next >
src/hotspot/share/gc/shenandoah/shenandoahNMethod.cpp
Print this page
rev 58162 : 8239926: Shenandoah: Shenandoah needs to mark nmethod's metadata
*** 110,131 ****
assert_same_oops();
}
void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) {
for (int c = 0; c < _oops_count; c ++) {
! oops->do_oop(_oops[c]);
}
oop* const begin = _nm->oops_begin();
oop* const end = _nm->oops_end();
for (oop* p = begin; p < end; p++) {
if (*p != Universe::non_oop_word()) {
oops->do_oop(p);
}
}
! if (fix_relocations && _has_non_immed_oops) {
_nm->fix_oop_relocations();
}
}
void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& has_non_immed_oops) {
--- 110,134 ----
assert_same_oops();
}
void ShenandoahNMethod::oops_do(OopClosure* oops, bool fix_relocations) {
for (int c = 0; c < _oops_count; c ++) {
! oop* p = _oops[c];
! if (*p != Universe::non_oop_word()) {
! oops->do_oop(p);
! }
}
oop* const begin = _nm->oops_begin();
oop* const end = _nm->oops_end();
for (oop* p = begin; p < end; p++) {
if (*p != Universe::non_oop_word()) {
oops->do_oop(p);
}
}
! if (_has_non_immed_oops) {
_nm->fix_oop_relocations();
}
}
void ShenandoahNMethod::detect_reloc_oops(nmethod* nm, GrowableArray<oop*>& oops, bool& has_non_immed_oops) {
*** 184,193 ****
--- 187,229 ----
ShenandoahEvacOOMScope evac_scope;
ShenandoahEvacuateUpdateRootsClosure<> cl;
data->oops_do(&cl, true /*fix relocation*/);
}
+ class ShenandoahKeepNMethodMetadataAliveClosure : public OopClosure {
+ private:
+ ShenandoahBarrierSet* const _bs;
+ const bool has_forwarded_objects;
+ public:
+ ShenandoahKeepNMethodMetadataAliveClosure() :
+ _bs(static_cast<ShenandoahBarrierSet*>(BarrierSet::barrier_set())),
+ has_forwarded_objects(ShenandoahHeap::heap()->has_forwarded_objects()) {
+ }
+
+ virtual void do_oop(oop* p) {
+ oop obj = RawAccess<>::oop_load(p);
+ if (!CompressedOops::is_null(obj)) {
+ if (has_forwarded_objects) {
+ obj = ShenandoahBarrierSet::resolve_forwarded_not_null(obj);
+ }
+ _bs->enqueue(obj);
+ }
+ }
+
+ virtual void do_oop(narrowOop* p) {
+ ShouldNotReachHere();
+ }
+ };
+
+ void ShenandoahNMethod::keep_metadata_alive(nmethod* nm) {
+ assert(ShenandoahHeap::heap()->is_concurrent_mark_in_progress(), "Only for marking");
+ ShenandoahNMethod* data = ShenandoahNMethod::gc_data(nm);
+ assert(data != NULL, "Must be");
+ ShenandoahKeepNMethodMetadataAliveClosure cl;
+ data->oops_do(&cl);
+ }
+
#ifdef ASSERT
void ShenandoahNMethod::assert_alive_and_correct() {
assert(_nm->is_alive(), "only alive nmethods here");
ShenandoahHeap* heap = ShenandoahHeap::heap();
for (int c = 0; c < _oops_count; c++) {
< prev index next >