# HG changeset patch # User rkennke # Date 1563356618 -7200 # Node ID 64330bbb9be54ce74d1ae9fe85716996b534a829 # Parent 443f7359b34d60e7821216ffc60f88b6ffe0ccdd 8227677: Shenandoah: C2: Make in-native LRB special case of normal LRB Reviewed-by: roland diff -r 443f7359b34d -r 64330bbb9be5 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Tue Jul 16 11:10:38 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Wed Jul 17 11:43:38 2019 +0200 @@ -472,19 +472,6 @@ 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* 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(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(access).kit()->gvn().transform(load); } else { @@ -655,7 +629,7 @@ 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* 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 @@ 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 @@ 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; diff -r 443f7359b34d -r 64330bbb9be5 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp Tue Jul 16 11:10:38 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp Wed Jul 17 11:43:38 2019 +0200 @@ -103,7 +103,6 @@ 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. diff -r 443f7359b34d -r 64330bbb9be5 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Tue Jul 16 11:10:38 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp Wed Jul 17 11:43:38 2019 +0200 @@ -208,10 +208,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } } -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; diff -r 443f7359b34d -r 64330bbb9be5 src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Tue Jul 16 11:10:38 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp Wed Jul 17 11:43:38 2019 +0200 @@ -60,7 +60,7 @@ 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 @@ 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 @@ 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);