8227677: Shenandoah: C2: Make in-native LRB special case of normal LRB
Reviewed-by: roland
This commit is contained in:
parent
5224520e9f
commit
ec7f1c13d9
@ -472,19 +472,6 @@ const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() {
|
||||
return TypeFunc::make(domain, range);
|
||||
}
|
||||
|
||||
const TypeFunc* ShenandoahBarrierSetC2::oop_load_from_native_barrier_Type() {
|
||||
const Type **fields = TypeTuple::fields(1);
|
||||
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
|
||||
const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields);
|
||||
|
||||
// create result type (range)
|
||||
fields = TypeTuple::fields(1);
|
||||
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL;
|
||||
const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+1, fields);
|
||||
|
||||
return TypeFunc::make(domain, range);
|
||||
}
|
||||
|
||||
const TypeFunc* ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type() {
|
||||
const Type **fields = TypeTuple::fields(1);
|
||||
fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // original field value
|
||||
@ -555,22 +542,9 @@ Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val
|
||||
Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top;
|
||||
Node* load = BarrierSetC2::load_at_resolved(access, val_type);
|
||||
|
||||
if ((decorators & IN_NATIVE) != 0) {
|
||||
assert(access.is_oop(), "IN_NATIVE access only for oop values");
|
||||
assert(access.is_parse_access(), "IN_NATIVE access only during parsing");
|
||||
GraphKit* kit = static_cast<C2ParseAccess &>(access).kit();
|
||||
Node* call = kit->make_runtime_call(GraphKit::RC_LEAF,
|
||||
oop_load_from_native_barrier_Type(),
|
||||
CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native),
|
||||
"ShenandoahRuntime::load_reference_barrier_native",
|
||||
NULL, load);
|
||||
Node* proj = kit->gvn().transform(new ProjNode(call, TypeFunc::Parms+0));
|
||||
return kit->gvn().transform(new CheckCastPPNode(kit->control(), proj, load->bottom_type()));
|
||||
}
|
||||
|
||||
if (access.is_oop()) {
|
||||
if (ShenandoahLoadRefBarrier) {
|
||||
load = new ShenandoahLoadReferenceBarrierNode(NULL, load);
|
||||
load = new ShenandoahLoadReferenceBarrierNode(NULL, load, (decorators & IN_NATIVE) != 0);
|
||||
if (access.is_parse_access()) {
|
||||
load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load);
|
||||
} else {
|
||||
@ -655,7 +629,7 @@ Node* ShenandoahBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess
|
||||
load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type()));
|
||||
}
|
||||
#endif
|
||||
load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store));
|
||||
load_store = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, load_store, false));
|
||||
return load_store;
|
||||
}
|
||||
return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type);
|
||||
@ -723,7 +697,7 @@ Node* ShenandoahBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& acces
|
||||
}
|
||||
Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, val, value_type);
|
||||
if (access.is_oop()) {
|
||||
result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result));
|
||||
result = kit->gvn().transform(new ShenandoahLoadReferenceBarrierNode(NULL, result, false));
|
||||
shenandoah_write_barrier_pre(kit, false /* do_load */,
|
||||
NULL, NULL, max_juint, NULL, NULL,
|
||||
result /* pre_val */, T_OBJECT);
|
||||
@ -749,8 +723,7 @@ bool ShenandoahBarrierSetC2::is_gc_barrier_node(Node* node) const {
|
||||
|
||||
return strcmp(call->_name, "shenandoah_clone_barrier") == 0 ||
|
||||
strcmp(call->_name, "shenandoah_cas_obj") == 0 ||
|
||||
strcmp(call->_name, "shenandoah_wb_pre") == 0 ||
|
||||
strcmp(call->_name, "ShenandoahRuntime::load_reference_barrier_native") == 0;
|
||||
strcmp(call->_name, "shenandoah_wb_pre") == 0;
|
||||
}
|
||||
|
||||
Node* ShenandoahBarrierSetC2::step_over_gc_barrier(Node* c) const {
|
||||
@ -1182,11 +1155,6 @@ bool ShenandoahBarrierSetC2::escape_add_to_con_graph(ConnectionGraph* conn_graph
|
||||
case Op_ShenandoahLoadReferenceBarrier:
|
||||
conn_graph->add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahLoadReferenceBarrierNode::ValueIn), delayed_worklist);
|
||||
return true;
|
||||
case Op_CallLeaf:
|
||||
if (strcmp(n->as_CallLeaf()->_name, "ShenandoahRuntime::load_reference_barrier_native") == 0) {
|
||||
conn_graph->map_ideal_node(n, conn_graph->phantom_obj);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// Nothing
|
||||
break;
|
||||
|
@ -103,7 +103,6 @@ public:
|
||||
static const TypeFunc* write_ref_field_pre_entry_Type();
|
||||
static const TypeFunc* shenandoah_clone_barrier_Type();
|
||||
static const TypeFunc* shenandoah_load_reference_barrier_Type();
|
||||
static const TypeFunc* oop_load_from_native_barrier_Type();
|
||||
virtual bool has_load_barriers() const { return true; }
|
||||
|
||||
// This is the entry-point for the backend to perform accesses through the Access API.
|
||||
|
@ -208,10 +208,7 @@ bool ShenandoahBarrierC2Support::verify_helper(Node* in, Node_Stack& phis, Vecto
|
||||
if (trace) {
|
||||
tty->print("Found raw LoadP (OSR argument?)");
|
||||
}
|
||||
} else if (in->Opcode() == Op_ShenandoahLoadReferenceBarrier ||
|
||||
(in->Opcode() == Op_Proj &&
|
||||
in->in(0)->Opcode() == Op_CallLeaf &&
|
||||
strcmp(in->in(0)->as_Call()->_name, "ShenandoahRuntime::load_reference_barrier_native") == 0)) {
|
||||
} else if (in->Opcode() == Op_ShenandoahLoadReferenceBarrier) {
|
||||
if (t == ShenandoahOopStore) {
|
||||
uint i = 0;
|
||||
for (; i < phis.size(); i++) {
|
||||
@ -530,7 +527,7 @@ void ShenandoahBarrierC2Support::verify(RootNode* root) {
|
||||
if (!verify_helper(n->in(TypeFunc::Parms), phis, visited, ShenandoahStore, trace, barriers_used)) {
|
||||
report_verify_failure("Shenandoah verification: _fill should have barriers", n);
|
||||
}
|
||||
} else if (!strcmp(call->_name, "shenandoah_wb_pre") || !strcmp(call->_name, "ShenandoahRuntime::load_reference_barrier_native")) {
|
||||
} else if (!strcmp(call->_name, "shenandoah_wb_pre")) {
|
||||
// skip
|
||||
} else {
|
||||
const int calls_len = sizeof(calls) / sizeof(calls[0]);
|
||||
@ -1085,7 +1082,7 @@ void ShenandoahBarrierC2Support::in_cset_fast_test(Node*& ctrl, Node*& not_cset_
|
||||
phase->register_control(ctrl, loop, in_cset_fast_test_iff);
|
||||
}
|
||||
|
||||
void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase) {
|
||||
void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase) {
|
||||
IdealLoopTree*loop = phase->get_loop(ctrl);
|
||||
const TypePtr* obj_type = phase->igvn().type(val)->is_oopptr()->cast_to_nonconst();
|
||||
|
||||
@ -1096,9 +1093,10 @@ void ShenandoahBarrierC2Support::call_lrb_stub(Node*& ctrl, Node*& val, Node*& r
|
||||
mm->set_memory_at(Compile::AliasIdxRaw, raw_mem);
|
||||
phase->register_new_node(mm, ctrl);
|
||||
|
||||
Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(),
|
||||
CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier),
|
||||
"shenandoah_load_reference_barrier", TypeRawPtr::BOTTOM);
|
||||
address calladdr = is_native ? CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native)
|
||||
: CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier);
|
||||
const char* name = is_native ? "oop_load_from_native_barrier" : "load_reference_barrier";
|
||||
Node* call = new CallLeafNode(ShenandoahBarrierSetC2::shenandoah_load_reference_barrier_Type(), calladdr, name, TypeRawPtr::BOTTOM);
|
||||
call->init_req(TypeFunc::Control, ctrl);
|
||||
call->init_req(TypeFunc::I_O, phase->C->top());
|
||||
call->init_req(TypeFunc::Memory, mm);
|
||||
@ -1561,7 +1559,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
|
||||
Node* result_mem = NULL;
|
||||
ctrl = if_not_fwd;
|
||||
fwd = new_val;
|
||||
call_lrb_stub(ctrl, fwd, result_mem, raw_mem, phase);
|
||||
call_lrb_stub(ctrl, fwd, result_mem, raw_mem, lrb->is_native(), phase);
|
||||
region->init_req(_evac_path, ctrl);
|
||||
val_phi->init_req(_evac_path, fwd);
|
||||
raw_mem_phi->init_req(_evac_path, result_mem);
|
||||
@ -3004,11 +3002,28 @@ void MemoryGraphFixer::fix_memory_uses(Node* mem, Node* replacement, Node* rep_p
|
||||
}
|
||||
}
|
||||
|
||||
ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj)
|
||||
: Node(ctrl, obj) {
|
||||
ShenandoahLoadReferenceBarrierNode::ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* obj, bool native)
|
||||
: Node(ctrl, obj), _native(native) {
|
||||
ShenandoahBarrierSetC2::bsc2()->state()->add_load_reference_barrier(this);
|
||||
}
|
||||
|
||||
bool ShenandoahLoadReferenceBarrierNode::is_native() const {
|
||||
return _native;
|
||||
}
|
||||
|
||||
uint ShenandoahLoadReferenceBarrierNode::size_of() const {
|
||||
return sizeof(*this);
|
||||
}
|
||||
|
||||
uint ShenandoahLoadReferenceBarrierNode::hash() const {
|
||||
return Node::hash() + _native ? 1 : 0;
|
||||
}
|
||||
|
||||
bool ShenandoahLoadReferenceBarrierNode::cmp( const Node &n ) const {
|
||||
return Node::cmp(n) && n.Opcode() == Op_ShenandoahLoadReferenceBarrier &&
|
||||
_native == ((const ShenandoahLoadReferenceBarrierNode&)n)._native;
|
||||
}
|
||||
|
||||
const Type* ShenandoahLoadReferenceBarrierNode::bottom_type() const {
|
||||
if (in(ValueIn) == NULL || in(ValueIn)->is_top()) {
|
||||
return Type::TOP;
|
||||
|
@ -60,7 +60,7 @@ private:
|
||||
static void test_null(Node*& ctrl, Node* val, Node*& null_ctrl, PhaseIdealLoop* phase);
|
||||
static void test_heap_stable(Node*& ctrl, Node* raw_mem, Node*& heap_stable_ctrl,
|
||||
PhaseIdealLoop* phase);
|
||||
static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, PhaseIdealLoop* phase);
|
||||
static void call_lrb_stub(Node*& ctrl, Node*& val, Node*& result_mem, Node* raw_mem, bool is_native, PhaseIdealLoop* phase);
|
||||
static Node* clone_null_check(Node*& c, Node* val, Node* unc_ctrl, PhaseIdealLoop* phase);
|
||||
static void fix_null_check(Node* unc, Node* unc_ctrl, Node* new_unc_ctrl, Unique_Node_List& uses,
|
||||
PhaseIdealLoop* phase);
|
||||
@ -234,8 +234,13 @@ public:
|
||||
NONE, WEAK, STRONG, NA
|
||||
};
|
||||
|
||||
ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val);
|
||||
private:
|
||||
bool _native;
|
||||
|
||||
public:
|
||||
ShenandoahLoadReferenceBarrierNode(Node* ctrl, Node* val, bool native);
|
||||
|
||||
bool is_native() const;
|
||||
virtual int Opcode() const;
|
||||
virtual const Type* bottom_type() const;
|
||||
virtual const Type* Value(PhaseGVN* phase) const;
|
||||
@ -247,9 +252,9 @@ public:
|
||||
|
||||
virtual Node* Identity(PhaseGVN* phase);
|
||||
|
||||
uint size_of() const {
|
||||
return sizeof(*this);
|
||||
}
|
||||
virtual uint size_of() const;
|
||||
virtual uint hash() const;
|
||||
virtual bool cmp( const Node &n ) const;
|
||||
|
||||
Strength get_barrier_strength();
|
||||
CallStaticJavaNode* pin_and_expand_null_check(PhaseIterGVN& igvn);
|
||||
|
Loading…
Reference in New Issue
Block a user