Mercurial > hg > graal-jvmci-8
changeset 21143:e13c65f874e5
Make G1 and Graal be friends in JDK9
author | iveresov |
---|---|
date | Tue, 28 Apr 2015 17:08:47 -0700 |
parents | 0b221b4ad707 |
children | b7f05f4ca66e |
files | graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java src/share/vm/code/nmethod.cpp src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp src/share/vm/memory/barrierSet.hpp |
diffstat | 6 files changed, 133 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Tue Apr 28 12:58:40 2015 -0700 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java Tue Apr 28 17:08:47 2015 -0700 @@ -427,7 +427,7 @@ } public static BytecodePosition processSimpleInfopoint(Invoke invoke, SimpleInfopointNode infopointNode, BytecodePosition incomingPos) { - BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter()).getCaller(), invoke.asNode().graph().method(), invoke.bci()); + BytecodePosition pos = incomingPos != null ? incomingPos : new BytecodePosition(toBytecodePosition(invoke.stateAfter().outerFrameState()), invoke.asNode().graph().method(), invoke.bci()); infopointNode.addCaller(pos); return pos; }
--- a/src/share/vm/code/nmethod.cpp Tue Apr 28 12:58:40 2015 -0700 +++ b/src/share/vm/code/nmethod.cpp Tue Apr 28 17:08:47 2015 -0700 @@ -1463,16 +1463,6 @@ _method = NULL; // Clear the method of this dead nmethod } -#ifdef GRAAL - // The method can only be unloaded after the pointer to the installed code - // Java wrapper is no longer alive. Here we need to clear out this weak - // reference to the dead object. - if (_graal_installed_code != NULL) { - InstalledCode::set_address(_graal_installed_code, 0); - _graal_installed_code = NULL; - } -#endif - // Make the class unloaded - i.e., change state and notify sweeper assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); if (is_in_use()) { @@ -1485,6 +1475,18 @@ // Unregister must be done before the state change Universe::heap()->unregister_nmethod(this); +#ifdef GRAAL + // The method can only be unloaded after the pointer to the installed code + // Java wrapper is no longer alive. Here we need to clear out this weak + // reference to the dead object. Nulling out the reference has to happen + // after the method is unregistered since the original value may be still + // tracked by the rset. + if (_graal_installed_code != NULL) { + InstalledCode::set_address(_graal_installed_code, 0); + _graal_installed_code = NULL; + } +#endif + _state = unloaded; // Log the unloading. @@ -1916,27 +1918,6 @@ unloading_occurred = true; } -#ifdef GRAAL - // Follow Graal method - if (_graal_installed_code != NULL) { - if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) { - if (!is_alive->do_object_b(_graal_installed_code)) { - _graal_installed_code = NULL; - } - } else { - if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { - return; - } - } - } - - if (_speculation_log != NULL) { - if (!is_alive->do_object_b(_speculation_log)) { - _speculation_log = NULL; - } - } -#endif - // Exception cache clean_exception_cache(is_alive); @@ -1983,6 +1964,33 @@ } } +#ifdef GRAAL + // Follow Graal method + BarrierSet* bs = Universe::heap()->barrier_set(); + if (_graal_installed_code != NULL) { + if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) { + if (!is_alive->do_object_b(_graal_installed_code)) { + bs->write_ref_nmethod_pre(&_graal_installed_code, this); + _graal_installed_code = NULL; + bs->write_ref_nmethod_post(&_graal_installed_code, this); + } + } else { + if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { + return; + } + } + } + + if (_speculation_log != NULL) { + if (!is_alive->do_object_b(_speculation_log)) { + bs->write_ref_nmethod_pre(&_speculation_log, this); + _speculation_log = NULL; + bs->write_ref_nmethod_post(&_speculation_log, this); + } + } +#endif + + // Ensure that all metadata is still alive verify_metadata_loaders(low_boundary, is_alive); } @@ -2182,6 +2190,32 @@ return postponed; } +#ifdef GRAAL + // Follow Graal method + BarrierSet* bs = Universe::heap()->barrier_set(); + if (_graal_installed_code != NULL) { + if (_graal_installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(_graal_installed_code)) { + if (!is_alive->do_object_b(_graal_installed_code)) { + bs->write_ref_nmethod_pre(&_graal_installed_code, this); + _graal_installed_code = NULL; + bs->write_ref_nmethod_post(&_graal_installed_code, this); + } + } else { + if (can_unload(is_alive, (oop*)&_graal_installed_code, unloading_occurred)) { + is_unloaded = true; + } + } + } + + if (_speculation_log != NULL) { + if (!is_alive->do_object_b(_speculation_log)) { + bs->write_ref_nmethod_pre(&_speculation_log, this); + _speculation_log = NULL; + bs->write_ref_nmethod_post(&_speculation_log, this); + } + } +#endif + // Ensure that all metadata is still alive verify_metadata_loaders(low_boundary, is_alive);
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Apr 28 12:58:40 2015 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Apr 28 17:08:47 2015 -0700 @@ -4830,11 +4830,14 @@ bool during_im = _g1h->g1_policy()->during_initial_mark_pause(); bool trace_metadata = during_im && ClassUnloadingWithConcurrentMark; + // Without eager nmethod unloading, we need to treat all oops in code cache as strong during the initial mark + bool trace_codecache = during_im && !ClassUnloadingWithConcurrentMark; + BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots); process_roots(false, // no scoping; this is parallel code - SharedHeap::SO_None, + trace_codecache ? SharedHeap::SO_AllCodeCache : SharedHeap::SO_None, &buf_scan_non_heap_roots, &buf_scan_non_heap_weak_roots, scan_strong_clds,
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Tue Apr 28 12:58:40 2015 -0700 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.cpp Tue Apr 28 17:08:47 2015 -0700 @@ -255,3 +255,60 @@ } } } + +void G1SATBCardTableModRefBS::write_ref_nmethod_pre(oop* dst, nmethod* nm) { + oop obj = oopDesc::load_heap_oop(dst); + if (obj != NULL) { + G1CollectedHeap* g1h = (G1CollectedHeap*)Universe::heap(); + HeapRegion* hr = g1h->heap_region_containing(obj); + assert(!hr->continuesHumongous(), + err_msg("trying to add code root "INTPTR_FORMAT" in continuation of humongous region "HR_FORMAT + " starting at "HR_FORMAT, + (intptr_t)nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); + hr->add_strong_code_root(nm); + } +} + +class G1EnsureLastRefToRegion : public OopClosure { + G1CollectedHeap* _g1h; + HeapRegion* _hr; + oop* _dst; + + bool _value; +public: + G1EnsureLastRefToRegion(G1CollectedHeap* g1h, HeapRegion* hr, oop* dst) : + _g1h(g1h), _hr(hr), _dst(dst), _value(true) {} + + void do_oop(oop* p) { + if (_value && p != _dst) { + oop obj = oopDesc::load_heap_oop(p); + if (obj != NULL) { + HeapRegion* hr = _g1h->heap_region_containing(obj); + if (hr == _hr) { + // Another reference to the same region. + _value = false; + } + } + } + } + void do_oop(narrowOop* p) { ShouldNotReachHere(); } + bool value() const { return _value; } +}; + +void G1SATBCardTableModRefBS::write_ref_nmethod_post(oop* dst, nmethod* nm) { + oop obj = oopDesc::load_heap_oop(dst); + if (obj != NULL) { + G1CollectedHeap* g1h = (G1CollectedHeap*)Universe::heap(); + HeapRegion* hr = g1h->heap_region_containing(obj); + assert(!hr->continuesHumongous(), + err_msg("trying to remove code root "INTPTR_FORMAT" in continuation of humongous region "HR_FORMAT + " starting at "HR_FORMAT, + (intptr_t)nm, HR_FORMAT_PARAMS(hr), HR_FORMAT_PARAMS(hr->humongous_start_region()))); + G1EnsureLastRefToRegion ensure_last_ref(g1h, hr, dst); + nm->oops_do(&ensure_last_ref); + if (ensure_last_ref.value()) { + // Last reference to this region, remove the nmethod from the rset. + hr->remove_strong_code_root(nm); + } + } +}
--- a/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Tue Apr 28 12:58:40 2015 -0700 +++ b/src/share/vm/gc_implementation/g1/g1SATBCardTableModRefBS.hpp Tue Apr 28 17:08:47 2015 -0700 @@ -126,6 +126,9 @@ jbyte val = _byte_map[card_index]; return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val(); } + void write_ref_nmethod_pre(oop* dst, nmethod* nm); + void write_ref_nmethod_post(oop* dst, nmethod* nm); + }; class G1SATBCardTableLoggingModRefBSChangedListener : public G1MappingChangedListener {
--- a/src/share/vm/memory/barrierSet.hpp Tue Apr 28 12:58:40 2015 -0700 +++ b/src/share/vm/memory/barrierSet.hpp Tue Apr 28 17:08:47 2015 -0700 @@ -145,6 +145,9 @@ static void static_write_ref_array_pre(HeapWord* start, size_t count); static void static_write_ref_array_post(HeapWord* start, size_t count); + virtual void write_ref_nmethod_pre(oop* dst, nmethod* nm) {} + virtual void write_ref_nmethod_post(oop* dst, nmethod* nm) {} + protected: virtual void write_ref_array_work(MemRegion mr) = 0; public: