8227677: Shenandoah: C2: Make in-native LRB special case of normal LRB
authorrkennke
Wed, 17 Jul 2019 11:43:38 +0200
changeset 55692 64330bbb9be5
parent 55691 443f7359b34d
child 55693 9a97b1393e72
8227677: Shenandoah: C2: Make in-native LRB special case of normal LRB Reviewed-by: roland
src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp
src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp
src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp
--- 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<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 @@
       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;
--- 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.
--- 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;
--- 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);