8205559: Remove IN_CONCURRENT_ROOT Access decorator
Removed decorator and made all NativeAccess use barriers. Reviewed-by: pliden, stefank
This commit is contained in:
parent
ed24b806f1
commit
8a2170dad7
@ -2127,8 +2127,7 @@ void MacroAssembler::resolve_jobject(Register value, Register thread, Register t
|
||||
|
||||
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 @@ void MacroAssembler::load_klass(Register dst, Register src) {
|
||||
// ((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) {
|
||||
|
@ -321,9 +321,10 @@ void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorator
|
||||
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 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco
|
||||
g1_write_barrier_post(masm, store_addr, new_val, tmp1, tmp2, tmp3);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef COMPILER1
|
||||
|
||||
|
@ -2140,7 +2140,7 @@ void MacroAssembler::resolve_jobject(Register value,
|
||||
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);
|
||||
|
@ -400,9 +400,10 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm, Register
|
||||
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;
|
||||
|
||||
|
@ -182,8 +182,7 @@ void MacroAssembler::resolve_jobject(Register value, Register tmp) {
|
||||
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 @@ void MacroAssembler::reserved_stack_check() {
|
||||
// ((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) {
|
||||
|
@ -349,9 +349,10 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
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);
|
||||
|
@ -5238,8 +5238,7 @@ void MacroAssembler::resolve_jobject(Register value,
|
||||
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 @@ void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -832,9 +832,7 @@ void ClassLoaderData::remove_handle(OopHandle h) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,11 +52,6 @@ void G1BarrierSetC1::pre_barrier(LIRAccess& access, LIR_Opr addr_opr,
|
||||
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;
|
||||
|
@ -98,12 +98,10 @@ template <DecoratorSet decorators, typename BarrierSetT>
|
||||
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.
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -281,13 +281,11 @@ typeArrayOop StringDedupTable::lookup(typeArrayOop value, bool latin1, unsigned
|
||||
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 = 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++;
|
||||
|
@ -653,7 +653,6 @@ Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) co
|
||||
return p;
|
||||
}
|
||||
|
||||
bool conc_root = (access.decorators() & IN_CONCURRENT_ROOT) != 0;
|
||||
bool weak = (access.decorators() & ON_WEAK_OOP_REF) != 0;
|
||||
|
||||
GraphKit* kit = access.kit();
|
||||
|
@ -48,13 +48,10 @@ bool ZBarrierSet::barrier_needed(DecoratorSet decorators, BasicType type) {
|
||||
//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
|
||||
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
|
||||
return false;
|
||||
|
@ -375,8 +375,7 @@ void Access<decorators>::verify_decorators() {
|
||||
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
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -153,8 +153,8 @@ const DecoratorSet MO_DECORATOR_MASK = MO_UNORDERED | MO_VOLATILE | MO_RELAXED |
|
||||
// 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 @@ const DecoratorSet AS_DECORATOR_MASK = AS_RAW | AS_NO_KEEPALIVE | AS_NORMA
|
||||
// * 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 @@ const DecoratorSet ON_DECORATOR_MASK = ON_STRONG_OOP_REF | ON_WEAK_OOP_REF |
|
||||
// * 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 @@ const DecoratorSet IN_DECORATOR_MASK = IN_HEAP | IN_NATIVE | IN_CONCURRENT_ROOT
|
||||
// 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 @@ const DecoratorSet IS_NOT_NULL = UCONST64(1) << 25;
|
||||
// * 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 @@ namespace AccessInternal {
|
||||
// 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 @@ namespace AccessInternal {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -109,7 +109,7 @@ jobject JNIHandles::make_global(Handle obj, AllocFailType alloc_failmode) {
|
||||
// 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 @@ void JNIHandles::destroy_global(jobject handle) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ inline oop JNIHandles::resolve_impl(jobject handle) {
|
||||
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");
|
||||
|
Loading…
Reference in New Issue
Block a user