--- a/src/hotspot/share/code/compiledMethod.cpp Mon Nov 05 12:53:55 2018 +0100
+++ b/src/hotspot/share/code/compiledMethod.cpp Mon Nov 05 12:36:23 2018 +0100
@@ -293,6 +293,20 @@
// first few bytes. If an oop in the old code was there, that oop
// should not get GC'd. Skip the first few bytes of oops on
// not-entrant methods.
+ if (frame_complete_offset() != CodeOffsets::frame_never_safe &&
+ code_begin() + frame_complete_offset() >
+ verified_entry_point() + NativeJump::instruction_size)
+ {
+ // If we have a frame_complete_offset after the native jump, then there
+ // is no point trying to look for oops before that. This is a requirement
+ // for being allowed to scan oops concurrently.
+ return code_begin() + frame_complete_offset();
+ }
+
+ // It is not safe to read oops concurrently using entry barriers, if their
+ // location depend on whether the nmethod is entrant or not.
+ assert(BarrierSet::barrier_set()->barrier_set_nmethod() == NULL, "Not safe oop scan");
+
address low_boundary = verified_entry_point();
if (!is_in_use() && is_nmethod()) {
low_boundary += NativeJump::instruction_size;
--- a/src/hotspot/share/gc/z/zNMethodTable.cpp Mon Nov 05 12:53:55 2018 +0100
+++ b/src/hotspot/share/gc/z/zNMethodTable.cpp Mon Nov 05 12:36:23 2018 +0100
@@ -51,7 +51,6 @@
nmethod* method() const;
size_t immediate_oops_count() const;
oop** immediate_oops_begin() const;
- oop** immediate_oops_begin_safe() const;
oop** immediate_oops_end() const;
};
@@ -95,24 +94,6 @@
return (oop**)((uintptr_t)this + header_size());
}
-oop** ZNMethodWithImmediateOops::immediate_oops_begin_safe() const {
- // Non-entrant nmethods have a jump instruction patched into the beginning
- // of the verified entry point, which could have overwritten an immediate
- // oop. If so, make sure we skip over that oop.
- if (_nm->is_not_entrant()) {
- oop* const first_immediate_oop = *immediate_oops_begin();
- oop* const safe_begin = (oop*)(_nm->verified_entry_point() + NativeJump::instruction_size);
- if (first_immediate_oop < safe_begin) {
- // First immediate oop overwritten, skip it
- return immediate_oops_begin() + 1;
- }
- }
-
- // First immediate oop not overwritten
- return immediate_oops_begin();
-}
-
-
oop** ZNMethodWithImmediateOops::immediate_oops_end() const {
return immediate_oops_begin() + immediate_oops_count();
}
@@ -429,7 +410,7 @@
if (entry.immediate_oops()) {
// Process immediate oops
const ZNMethodWithImmediateOops* const nmi = entry.method_with_immediate_oops();
- oop** const begin = nmi->immediate_oops_begin_safe();
+ oop** const begin = nmi->immediate_oops_begin();
oop** const end = nmi->immediate_oops_end();
for (oop** p = begin; p < end; p++) {
cl->do_oop(*p);