diff -r 3243c42d737d -r 92ab031d6540 src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp --- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Thu Jul 11 06:56:51 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp Thu Jul 04 17:31:03 2019 +0200 @@ -472,6 +472,19 @@ 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 @@ -542,6 +555,19 @@ 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::oop_load_from_native_barrier), + "ShenandoahRuntime::oop_load_from_native_barrier", + 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); @@ -723,7 +749,8 @@ 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, "shenandoah_wb_pre") == 0 || + strcmp(call->_name, "ShenandoahRuntime::oop_load_from_native_barrier") == 0; } Node* ShenandoahBarrierSetC2::step_over_gc_barrier(Node* c) const { @@ -1155,6 +1182,11 @@ 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::oop_load_from_native_barrier") == 0) { + conn_graph->map_ideal_node(n, conn_graph->phantom_obj); + return true; + } default: // Nothing break;