8233339: Shenandoah: Centralize load barrier decisions into ShenandoahBarrierSet
Reviewed-by: rkennke
--- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Fri Nov 08 10:55:14 2019 +0100
+++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Fri Nov 08 09:50:07 2019 -0500
@@ -22,8 +22,8 @@
*/
#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
-#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
#include "gc/shenandoah/shenandoahForwarding.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
@@ -370,8 +370,8 @@
return;
}
- // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set
- if (ShenandoahLoadRefBarrier) {
+ // 2: load a reference from src location and apply LRB if needed
+ if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
Register result_dst = dst;
// Preserve src location for LRB
@@ -382,9 +382,7 @@
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
- // Native barrier is for concurrent root processing
- bool in_native = (decorators & IN_NATIVE) != 0;
- if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) {
+ if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) {
load_reference_barrier_native(masm, dst, src);
} else {
load_reference_barrier(masm, dst, src);
@@ -398,25 +396,17 @@
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
}
- // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set
- if (ShenandoahKeepAliveBarrier) {
- bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
- bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
- bool on_reference = on_weak || on_phantom;
- bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
- bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode;
-
- if (on_reference && keep_alive) {
- __ enter();
- satb_write_barrier_pre(masm /* masm */,
- noreg /* obj */,
- dst /* pre_val */,
- rthread /* thread */,
- tmp1 /* tmp */,
- true /* tosca_live */,
- true /* expand_call */);
- __ leave();
- }
+ // 3: apply keep-alive barrier if needed
+ if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
+ __ enter();
+ satb_write_barrier_pre(masm /* masm */,
+ noreg /* obj */,
+ dst /* pre_val */,
+ rthread /* thread */,
+ tmp1 /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
+ __ leave();
}
}
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Fri Nov 08 10:55:14 2019 +0100
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Fri Nov 08 09:50:07 2019 -0500
@@ -22,8 +22,8 @@
*/
#include "precompiled.hpp"
+#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
-#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
#include "gc/shenandoah/shenandoahForwarding.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
@@ -467,8 +467,10 @@
return;
}
- // 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set
- if (ShenandoahLoadRefBarrier) {
+ assert((decorators & ON_UNKNOWN_OOP_REF) == 0, "Not expected");
+
+ // 2: load a reference from src location and apply LRB if needed
+ if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
Register result_dst = dst;
bool use_tmp1_for_dst = false;
@@ -487,9 +489,7 @@
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
- // Native barrier is for concurrent root processing
- bool in_native = (decorators & IN_NATIVE) != 0;
- if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) {
+ if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) {
load_reference_barrier_native(masm, dst, src);
} else {
load_reference_barrier(masm, dst, src);
@@ -509,28 +509,20 @@
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
}
- // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set
- if (ShenandoahKeepAliveBarrier) {
- bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
- bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
- bool on_reference = on_weak || on_phantom;
- bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
- bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
-
- if (on_reference && keep_alive) {
- const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
- assert_different_registers(dst, tmp1, tmp_thread);
- NOT_LP64(__ get_thread(thread));
- // Generate the SATB pre-barrier code to log the value of
- // the referent field in an SATB buffer.
- shenandoah_write_barrier_pre(masm /* masm */,
- noreg /* obj */,
- dst /* pre_val */,
- thread /* thread */,
- tmp1 /* tmp */,
- true /* tosca_live */,
- true /* expand_call */);
- }
+ // 3: apply keep-alive barrier if needed
+ if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
+ const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
+ assert_different_registers(dst, tmp1, tmp_thread);
+ NOT_LP64(__ get_thread(thread));
+ // Generate the SATB pre-barrier code to log the value of
+ // the referent field in an SATB buffer.
+ shenandoah_write_barrier_pre(masm /* masm */,
+ noreg /* obj */,
+ dst /* pre_val */,
+ thread /* thread */,
+ tmp1 /* tmp */,
+ true /* tosca_live */,
+ true /* expand_call */);
}
}
--- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Fri Nov 08 10:55:14 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.cpp Fri Nov 08 09:50:07 2019 -0500
@@ -24,8 +24,8 @@
#include "precompiled.hpp"
#include "c1/c1_IR.hpp"
#include "gc/shared/satbMarkQueue.hpp"
+#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
-#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
#include "gc/shenandoah/shenandoahRuntime.hpp"
@@ -212,12 +212,11 @@
LIRGenerator* gen = access.gen();
DecoratorSet decorators = access.decorators();
+ BasicType type = access.type();
// 2: load a reference from src location and apply LRB if ShenandoahLoadRefBarrier is set
- if (ShenandoahLoadRefBarrier) {
- // Native barrier is for concurrent root processing
- bool in_native = (decorators & IN_NATIVE) != 0;
- if (in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots()) {
+ if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
+ if (ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type)) {
BarrierSetC1::load_at_resolved(access, result);
LIR_OprList* args = new LIR_OprList();
LIR_Opr addr = access.resolved_addr();
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Fri Nov 08 10:55:14 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Fri Nov 08 09:50:07 2019 -0500
@@ -23,7 +23,7 @@
#include "precompiled.hpp"
#include "gc/shared/barrierSet.hpp"
-#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
+#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahForwarding.hpp"
#include "gc/shenandoah/shenandoahHeap.hpp"
#include "gc/shenandoah/shenandoahHeuristics.hpp"
@@ -542,13 +542,13 @@
Node* load = BarrierSetC2::load_at_resolved(access, val_type);
DecoratorSet decorators = access.decorators();
- bool in_native = (decorators & IN_NATIVE) != 0;
+ BasicType type = access.type();
- // 2: apply LRB if ShenandoahLoadRefBarrier is set
- if (ShenandoahLoadRefBarrier) {
- // Native barrier is for concurrent root processing
- bool use_native_barrier = in_native && ShenandoahConcurrentRoots::can_do_concurrent_roots();
- load = new ShenandoahLoadReferenceBarrierNode(NULL, load, use_native_barrier);
+ // 2: apply LRB if needed
+ if (ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) {
+ load = new ShenandoahLoadReferenceBarrierNode(NULL,
+ load,
+ ShenandoahBarrierSet::use_load_reference_barrier_native(decorators, type));
if (access.is_parse_access()) {
load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
} else {
@@ -556,8 +556,8 @@
}
}
- // 3: apply keep-alive barrier if ShenandoahKeepAliveBarrier is set
- if (ShenandoahKeepAliveBarrier) {
+ // 3: apply keep-alive barrier if needed
+ if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
Node* top = Compile::current()->top();
Node* adr = access.addr().node();
Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top;
@@ -583,6 +583,7 @@
GraphKit* kit = parse_access.kit();
bool mismatched = (decorators & C2_MISMATCHED) != 0;
bool is_unordered = (decorators & MO_UNORDERED) != 0;
+ bool in_native = (decorators & IN_NATIVE) != 0;
bool need_cpu_mem_bar = !is_unordered || mismatched || in_native;
if (on_weak_ref) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Fri Nov 08 10:55:14 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Fri Nov 08 09:50:07 2019 -0500
@@ -27,6 +27,7 @@
#include "gc/shenandoah/shenandoahBarrierSetClone.inline.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
+#include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
#include "gc/shenandoah/shenandoahHeuristics.hpp"
#include "gc/shenandoah/shenandoahTraversalGC.hpp"
@@ -71,6 +72,35 @@
return true;
}
+bool ShenandoahBarrierSet::need_load_reference_barrier(DecoratorSet decorators, BasicType type) {
+ if (!ShenandoahLoadRefBarrier) return false;
+ // Only needed for references
+ return is_reference_type(type);
+}
+
+bool ShenandoahBarrierSet::use_load_reference_barrier_native(DecoratorSet decorators, BasicType type) {
+ assert(need_load_reference_barrier(decorators, type), "Should be subset of LRB");
+ assert(is_reference_type(type), "Why we here?");
+ // Native load reference barrier is only needed for concurrent root processing
+ if (!ShenandoahConcurrentRoots::can_do_concurrent_roots()) {
+ return false;
+ }
+
+ return (decorators & IN_NATIVE) != 0;
+}
+
+bool ShenandoahBarrierSet::need_keep_alive_barrier(DecoratorSet decorators,BasicType type) {
+ if (!ShenandoahKeepAliveBarrier) return false;
+ // Only needed for references
+ if (!is_reference_type(type)) return false;
+
+ bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0;
+ bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0;
+ bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
+ bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0;
+ return (on_weak_ref || unknown) && (keep_alive || is_traversal_mode);
+}
+
template <class T>
inline void ShenandoahBarrierSet::inline_write_ref_field_pre(T* field, oop new_val) {
shenandoah_assert_not_in_cset_loc_except(field, _heap->cancelled_gc());
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Fri Nov 08 10:55:14 2019 +0100
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Fri Nov 08 09:50:07 2019 -0500
@@ -57,6 +57,10 @@
return barrier_set()->_satb_mark_queue_set;
}
+ static bool need_load_reference_barrier(DecoratorSet decorators, BasicType type);
+ static bool use_load_reference_barrier_native(DecoratorSet decorators, BasicType type);
+ static bool need_keep_alive_barrier(DecoratorSet decorators, BasicType type);
+
void print_on(outputStream* st) const;
bool is_a(BarrierSet::Name bsn);