8205559: Remove IN_CONCURRENT_ROOT Access decorator
Summary: Removed decorator and made all NativeAccess use barriers.
Reviewed-by: pliden, stefank
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -2127,8 +2127,7 @@
bind(not_weak);
// Resolve (untagged) jobject.
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT, value, Address(value, 0), tmp,
- thread);
+ access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, 0), tmp, thread);
verify_oop(value);
bind(done);
}
@@ -3643,8 +3642,7 @@
// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
// OopHandle::resolve is an indirection.
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
- result, Address(result, 0), tmp, noreg);
+ access_load_at(T_OBJECT, IN_NATIVE, result, Address(result, 0), tmp, noreg);
}
void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
--- a/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/arm/gc/g1/g1BarrierSetAssembler_arm.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -321,9 +321,10 @@
void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address obj, Register new_val, Register tmp1, Register tmp2, Register tmp3, bool is_null) {
bool in_heap = (decorators & IN_HEAP) != 0;
- bool in_concurrent_root = (decorators & IN_CONCURRENT_ROOT) != 0;
+ bool as_normal = (decorators & AS_NORMAL) != 0;
+ assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
- bool needs_pre_barrier = in_heap || in_concurrent_root;
+ bool needs_pre_barrier = as_normal;
bool needs_post_barrier = (new_val != noreg) && in_heap;
// flatten object address if needed
@@ -360,7 +361,7 @@
g1_write_barrier_post(masm, store_addr, new_val, tmp1, tmp2, tmp3);
}
}
-};
+}
#ifdef COMPILER1
--- a/src/hotspot/cpu/arm/macroAssembler_arm.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/arm/macroAssembler_arm.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -2140,7 +2140,7 @@
b(done);
bind(not_weak);
// Resolve (untagged) jobject.
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
+ access_load_at(T_OBJECT, IN_NATIVE,
Address(value, 0), value, tmp1, tmp2, noreg);
verify_oop(value);
bind(done);
--- a/src/hotspot/cpu/sparc/gc/g1/g1BarrierSetAssembler_sparc.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/sparc/gc/g1/g1BarrierSetAssembler_sparc.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -400,9 +400,10 @@
void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register val, Address dst, Register tmp) {
bool in_heap = (decorators & IN_HEAP) != 0;
- bool in_concurrent_root = (decorators & IN_CONCURRENT_ROOT) != 0;
+ bool as_normal = (decorators & AS_NORMAL) != 0;
+ assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
- bool needs_pre_barrier = in_heap || in_concurrent_root;
+ bool needs_pre_barrier = as_normal;
// No need for post barrier if storing NULL
bool needs_post_barrier = val != G0 && in_heap;
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -182,8 +182,7 @@
br (Assembler::always, true, Assembler::pt, done);
delayed()->nop();
bind(not_weak);
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
- Address(value, 0), value, tmp);
+ access_load_at(T_OBJECT, IN_NATIVE, Address(value, 0), value, tmp);
verify_oop(value);
bind(done);
}
@@ -3402,8 +3401,7 @@
// ((OopHandle)result).resolve();
void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
// OopHandle::resolve is an indirection.
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
- Address(result, 0), result, tmp);
+ access_load_at(T_OBJECT, IN_NATIVE, Address(result, 0), result, tmp);
}
void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
--- a/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/x86/gc/g1/g1BarrierSetAssembler_x86.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -349,9 +349,10 @@
void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Address dst, Register val, Register tmp1, Register tmp2) {
bool in_heap = (decorators & IN_HEAP) != 0;
- bool in_concurrent_root = (decorators & IN_CONCURRENT_ROOT) != 0;
+ bool as_normal = (decorators & AS_NORMAL) != 0;
+ assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
- bool needs_pre_barrier = in_heap || in_concurrent_root;
+ bool needs_pre_barrier = as_normal;
bool needs_post_barrier = val != noreg && in_heap;
Register tmp3 = LP64_ONLY(r8) NOT_LP64(rsi);
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -5238,8 +5238,7 @@
jmp(done);
bind(not_weak);
// Resolve (untagged) jobject.
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
- value, Address(value, 0), tmp, thread);
+ access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, 0), tmp, thread);
verify_oop(value);
bind(done);
}
@@ -6216,7 +6215,7 @@
// Only 64 bit platforms support GCs that require a tmp register
// Only IN_HEAP loads require a thread_tmp register
// OopHandle::resolve is an indirection like jobject.
- access_load_at(T_OBJECT, IN_CONCURRENT_ROOT,
+ access_load_at(T_OBJECT, IN_NATIVE,
result, Address(result, 0), tmp, /*tmp_thread*/noreg);
}
--- a/src/hotspot/share/classfile/classLoaderData.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/classfile/classLoaderData.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -832,9 +832,7 @@
oop* ptr = h.ptr_raw();
if (ptr != NULL) {
assert(_handles.owner_of(ptr), "Got unexpected handle " PTR_FORMAT, p2i(ptr));
- // This root is not walked in safepoints, and hence requires an appropriate
- // decorator that e.g. maintains the SATB invariant in SATB collectors.
- NativeAccess<IN_CONCURRENT_ROOT>::oop_store(ptr, oop(NULL));
+ NativeAccess<>::oop_store(ptr, oop(NULL));
}
}
--- a/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/gc/g1/c1/g1BarrierSetC1.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -52,11 +52,6 @@
LIR_Opr pre_val, CodeEmitInfo* info) {
LIRGenerator* gen = access.gen();
DecoratorSet decorators = access.decorators();
- bool in_heap = (decorators & IN_HEAP) != 0;
- bool in_conc_root = (decorators & IN_CONCURRENT_ROOT) != 0;
- if (!in_heap && !in_conc_root) {
- return;
- }
// First we test whether marking is in progress.
BasicType flag_type;
--- a/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/gc/g1/g1BarrierSet.inline.hpp Tue Jun 26 16:59:38 2018 -0400
@@ -98,12 +98,10 @@
template <typename T>
inline void G1BarrierSet::AccessBarrier<decorators, BarrierSetT>::
oop_store_not_in_heap(T* addr, oop new_value) {
- if (HasDecorator<decorators, IN_CONCURRENT_ROOT>::value) {
- // For roots not scanned in a safepoint, we have to apply SATB barriers
- // even for roots.
- G1BarrierSet *bs = barrier_set_cast<G1BarrierSet>(BarrierSet::barrier_set());
- bs->write_ref_field_pre<decorators>(addr);
- }
+ // Apply SATB barriers for all non-heap references, to allow
+ // concurrent scanning of such references.
+ G1BarrierSet *bs = barrier_set_cast<G1BarrierSet>(BarrierSet::barrier_set());
+ bs->write_ref_field_pre<decorators>(addr);
Raw::oop_store(addr, new_value);
}
--- a/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/gc/shared/stringdedup/stringDedupTable.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -281,13 +281,11 @@
StringDedupEntry** list, uintx &count) {
for (StringDedupEntry* entry = *list; entry != NULL; entry = entry->next()) {
if (entry->hash() == hash && entry->latin1() == latin1) {
- typeArrayOop existing_value = entry->obj();
- if (equals(value, existing_value)) {
- // Apply proper barrier to make sure it is kept alive. Concurrent mark might
- // otherwise declare it dead if there are no other strong references to this object.
- oop* obj_addr = (oop*)entry->obj_addr();
- oop obj = NativeAccess<IN_CONCURRENT_ROOT | ON_WEAK_OOP_REF>::oop_load(obj_addr);
- return typeArrayOop(obj);
+ oop* obj_addr = (oop*)entry->obj_addr();
+ oop obj = NativeAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(obj_addr);
+ if (equals(value, static_cast<typeArrayOop>(obj))) {
+ obj = NativeAccess<ON_PHANTOM_OOP_REF>::oop_load(obj_addr);
+ return static_cast<typeArrayOop>(obj);
}
}
count++;
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -653,7 +653,6 @@
return p;
}
- bool conc_root = (access.decorators() & IN_CONCURRENT_ROOT) != 0;
bool weak = (access.decorators() & ON_WEAK_OOP_REF) != 0;
GraphKit* kit = access.kit();
--- a/src/hotspot/share/gc/z/zBarrierSet.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/gc/z/zBarrierSet.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -48,12 +48,9 @@
//assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Unexpected decorator");
if (type == T_OBJECT || type == T_ARRAY) {
- if (((decorators & IN_HEAP) != 0) ||
- ((decorators & IN_CONCURRENT_ROOT) != 0) ||
- ((decorators & ON_PHANTOM_OOP_REF) != 0)) {
- // Barrier needed
- return true;
- }
+ assert((decorators & (IN_HEAP | IN_NATIVE)) != 0, "Where is reference?");
+ // Barrier needed even when IN_NATIVE, to allow concurrent scanning.
+ return true;
}
// Barrier not neeed
--- a/src/hotspot/share/oops/access.hpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/oops/access.hpp Tue Jun 26 16:59:38 2018 -0400
@@ -375,8 +375,7 @@
const DecoratorSet location_decorators = decorators & IN_DECORATOR_MASK;
STATIC_ASSERT(location_decorators == 0 || ( // make sure location decorators are disjoint if set
(location_decorators ^ IN_NATIVE) == 0 ||
- (location_decorators ^ IN_HEAP) == 0 ||
- (location_decorators ^ (IN_NATIVE | IN_CONCURRENT_ROOT)) == 0
+ (location_decorators ^ IN_HEAP) == 0
));
}
--- a/src/hotspot/share/oops/accessDecorators.hpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/oops/accessDecorators.hpp Tue Jun 26 16:59:38 2018 -0400
@@ -153,8 +153,8 @@
// Note that primitive accesses will only be resolved on the barrier set if the appropriate build-time
// decorator for enabling primitive barriers is enabled for the build.
const DecoratorSet AS_RAW = UCONST64(1) << 12;
-const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 14;
-const DecoratorSet AS_NORMAL = UCONST64(1) << 15;
+const DecoratorSet AS_NO_KEEPALIVE = UCONST64(1) << 13;
+const DecoratorSet AS_NORMAL = UCONST64(1) << 14;
const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_NO_KEEPALIVE | AS_NORMAL;
// === Reference Strength Decorators ===
@@ -166,10 +166,10 @@
// * ON_UNKNOWN_OOP_REF: The memory access is performed on a reference of unknown strength.
// This could for example come from the unsafe API.
// * Default (no explicit reference strength specified): ON_STRONG_OOP_REF
-const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 16;
-const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 17;
-const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 18;
-const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 19;
+const DecoratorSet ON_STRONG_OOP_REF = UCONST64(1) << 15;
+const DecoratorSet ON_WEAK_OOP_REF = UCONST64(1) << 16;
+const DecoratorSet ON_PHANTOM_OOP_REF = UCONST64(1) << 17;
+const DecoratorSet ON_UNKNOWN_OOP_REF = UCONST64(1) << 18;
const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
ON_PHANTOM_OOP_REF | ON_UNKNOWN_OOP_REF;
@@ -179,13 +179,9 @@
// * IN_HEAP: The access is performed in the heap. Many barriers such as card marking will
// be omitted if this decorator is not set.
// * IN_NATIVE: The access is performed in an off-heap data structure pointing into the Java heap.
-// * IN_CONCURRENT_ROOT: The access is performed in an off-heap data structure pointing into the Java heap,
-// but is notably not scanned during safepoints. This is sometimes a special case for some GCs and
-// implies that it is also an IN_NATIVE.
-const DecoratorSet IN_HEAP = UCONST64(1) << 20;
-const DecoratorSet IN_NATIVE = UCONST64(1) << 22;
-const DecoratorSet IN_CONCURRENT_ROOT = UCONST64(1) << 23;
-const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE | IN_CONCURRENT_ROOT;
+const DecoratorSet IN_HEAP = UCONST64(1) << 19;
+const DecoratorSet IN_NATIVE = UCONST64(1) << 20;
+const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE;
// == Boolean Flag Decorators ==
// * IS_ARRAY: The access is performed on a heap allocated array. This is sometimes a special case
@@ -194,8 +190,8 @@
// marking that the previous value is uninitialized nonsense rather than a real value.
// * IS_NOT_NULL: This property can make certain barriers faster such as compressing oops.
const DecoratorSet IS_ARRAY = UCONST64(1) << 21;
-const DecoratorSet IS_DEST_UNINITIALIZED = UCONST64(1) << 13;
-const DecoratorSet IS_NOT_NULL = UCONST64(1) << 25;
+const DecoratorSet IS_DEST_UNINITIALIZED = UCONST64(1) << 22;
+const DecoratorSet IS_NOT_NULL = UCONST64(1) << 23;
// == Arraycopy Decorators ==
// * ARRAYCOPY_CHECKCAST: This property means that the class of the objects in source
@@ -207,17 +203,17 @@
// * ARRAYCOPY_ARRAYOF: The copy is in the arrayof form.
// * ARRAYCOPY_ATOMIC: The accesses have to be atomic over the size of its elements.
// * ARRAYCOPY_ALIGNED: The accesses have to be aligned on a HeapWord.
-const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 26;
-const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 27;
-const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 28;
-const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 29;
-const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 30;
+const DecoratorSet ARRAYCOPY_CHECKCAST = UCONST64(1) << 24;
+const DecoratorSet ARRAYCOPY_DISJOINT = UCONST64(1) << 25;
+const DecoratorSet ARRAYCOPY_ARRAYOF = UCONST64(1) << 26;
+const DecoratorSet ARRAYCOPY_ATOMIC = UCONST64(1) << 27;
+const DecoratorSet ARRAYCOPY_ALIGNED = UCONST64(1) << 28;
const DecoratorSet ARRAYCOPY_DECORATOR_MASK = ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT |
ARRAYCOPY_DISJOINT | ARRAYCOPY_ARRAYOF |
ARRAYCOPY_ATOMIC | ARRAYCOPY_ALIGNED;
// Keep track of the last decorator.
-const DecoratorSet DECORATOR_LAST = UCONST64(1) << 30;
+const DecoratorSet DECORATOR_LAST = UCONST64(1) << 28;
namespace AccessInternal {
// This class adds implied decorators that follow according to decorator rules.
@@ -235,9 +231,7 @@
// If no barrier strength has been picked, normal will be used
static const DecoratorSet barrier_strength_default = memory_ordering_default |
((AS_DECORATOR_MASK & memory_ordering_default) == 0 ? AS_NORMAL : INTERNAL_EMPTY);
- static const DecoratorSet conc_root_is_root = barrier_strength_default |
- ((IN_CONCURRENT_ROOT & barrier_strength_default) != 0 ? IN_NATIVE : INTERNAL_EMPTY);
- static const DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
+ static const DecoratorSet value = barrier_strength_default | BT_BUILDTIME_DECORATORS;
};
// This function implements the above DecoratorFixup rules, but without meta
@@ -253,9 +247,7 @@
// If no barrier strength has been picked, normal will be used
DecoratorSet barrier_strength_default = memory_ordering_default |
((AS_DECORATOR_MASK & memory_ordering_default) == 0 ? AS_NORMAL : INTERNAL_EMPTY);
- DecoratorSet conc_root_is_root = barrier_strength_default |
- ((IN_CONCURRENT_ROOT & barrier_strength_default) != 0 ? IN_NATIVE : INTERNAL_EMPTY);
- DecoratorSet value = conc_root_is_root | BT_BUILDTIME_DECORATORS;
+ DecoratorSet value = barrier_strength_default | BT_BUILDTIME_DECORATORS;
return value;
}
}
--- a/src/hotspot/share/oops/oopHandle.inline.hpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/oops/oopHandle.inline.hpp Tue Jun 26 16:59:38 2018 -0400
@@ -29,7 +29,7 @@
#include "oops/oopHandle.hpp"
inline oop OopHandle::resolve() const {
- return (_obj == NULL) ? (oop)NULL : NativeAccess<IN_CONCURRENT_ROOT>::oop_load(_obj);
+ return (_obj == NULL) ? (oop)NULL : NativeAccess<>::oop_load(_obj);
}
#endif // SHARE_VM_OOPS_OOPHANDLE_INLINE_HPP
--- a/src/hotspot/share/runtime/jniHandles.cpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/runtime/jniHandles.cpp Tue Jun 26 16:59:38 2018 -0400
@@ -109,7 +109,7 @@
// Return NULL on allocation failure.
if (ptr != NULL) {
assert(*ptr == NULL, "invariant");
- NativeAccess<IN_CONCURRENT_ROOT>::oop_store(ptr, obj());
+ NativeAccess<>::oop_store(ptr, obj());
res = reinterpret_cast<jobject>(ptr);
} else {
report_handle_allocation_failure(alloc_failmode, "global");
@@ -175,7 +175,7 @@
if (handle != NULL) {
assert(!is_jweak(handle), "wrong method for detroying jweak");
oop* oop_ptr = jobject_ptr(handle);
- NativeAccess<IN_CONCURRENT_ROOT>::oop_store(oop_ptr, (oop)NULL);
+ NativeAccess<>::oop_store(oop_ptr, (oop)NULL);
global_handles()->release(oop_ptr);
}
}
--- a/src/hotspot/share/runtime/jniHandles.inline.hpp Tue Jun 26 13:50:59 2018 -0700
+++ b/src/hotspot/share/runtime/jniHandles.inline.hpp Tue Jun 26 16:59:38 2018 -0400
@@ -57,7 +57,7 @@
if (is_jweak(handle)) { // Unlikely
result = resolve_jweak(handle);
} else {
- result = NativeAccess<IN_CONCURRENT_ROOT>::oop_load(jobject_ptr(handle));
+ result = NativeAccess<>::oop_load(jobject_ptr(handle));
// Construction of jobjects canonicalize a null value into a null
// jobject, so for non-jweak the pointee should never be null.
assert(external_guard || result != NULL, "Invalid JNI handle");