< prev index next >

src/hotspot/share/gc/shared/c2/barrierSetC2.cpp

Print this page
rev 50410 : 8204331: AArch64: fix CAS not embedded in normal graph error.
Reviewed-by: duke

@@ -210,10 +210,36 @@
     }
   }
 
 };
 
+class C2AtomicAccessFence: public C2AccessFence {
+  C2AtomicAccess& _access;
+
+public:
+  C2AtomicAccessFence(C2AtomicAccess& access) :
+    C2AccessFence(access), _access(access) { }
+
+  ~C2AtomicAccessFence() {
+    // ~C2AtomicAccessFence is called before ~C2AccessFence. This calling order
+    // matters here. Because SCMemProjNode should be added before memory barrier
+    // insertion (it is inserted in ~C2AccessFence).
+    if (!_access.needs_pinning()) {
+      return;
+    }
+    // SCMemProjNodes represent the memory state of a LoadStore. Their
+    // main role is to prevent LoadStore nodes from being optimized away
+    // when their results aren't used.
+    GraphKit* kit = _access.kit();
+    Node* load_store = _access.raw_access();
+    assert(load_store != NULL, "must pin atomic op");
+    Node* proj = kit->gvn().transform(new SCMemProjNode(load_store));
+    kit->set_memory(proj, _access.alias_idx());
+  }
+
+};
+
 Node* BarrierSetC2::store_at(C2Access& access, C2AccessValue& val) const {
   C2AccessFence fence(access);
   resolve_address(access);
   return store_at_resolved(access, val);
 }

@@ -291,24 +317,10 @@
   }
 }
 
 //--------------------------- atomic operations---------------------------------
 
-static void pin_atomic_op(C2AtomicAccess& access) {
-  if (!access.needs_pinning()) {
-    return;
-  }
-  // SCMemProjNodes represent the memory state of a LoadStore. Their
-  // main role is to prevent LoadStore nodes from being optimized away
-  // when their results aren't used.
-  GraphKit* kit = access.kit();
-  Node* load_store = access.raw_access();
-  assert(load_store != NULL, "must pin atomic op");
-  Node* proj = kit->gvn().transform(new SCMemProjNode(load_store));
-  kit->set_memory(proj, access.alias_idx());
-}
-
 void C2AtomicAccess::set_memory() {
   Node *mem = _kit->memory(_alias_idx);
   _memory = mem;
 }
 

@@ -356,11 +368,10 @@
         ShouldNotReachHere();
     }
   }
 
   access.set_raw_access(load_store);
-  pin_atomic_op(access);
 
 #ifdef _LP64
   if (access.is_oop() && adr->bottom_type()->is_ptr_to_narrowoop()) {
     return kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type()));
   }

@@ -436,11 +447,10 @@
         ShouldNotReachHere();
     }
   }
 
   access.set_raw_access(load_store);
-  pin_atomic_op(access);
 
   return load_store;
 }
 
 Node* BarrierSetC2::atomic_xchg_at_resolved(C2AtomicAccess& access, Node* new_val, const Type* value_type) const {

@@ -478,11 +488,10 @@
         ShouldNotReachHere();
     }
   }
 
   access.set_raw_access(load_store);
-  pin_atomic_op(access);
 
 #ifdef _LP64
   if (access.is_oop() && adr->bottom_type()->is_ptr_to_narrowoop()) {
     return kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type()));
   }

@@ -514,37 +523,36 @@
     default:
       ShouldNotReachHere();
   }
 
   access.set_raw_access(load_store);
-  pin_atomic_op(access);
 
   return load_store;
 }
 
 Node* BarrierSetC2::atomic_cmpxchg_val_at(C2AtomicAccess& access, Node* expected_val,
                                           Node* new_val, const Type* value_type) const {
-  C2AccessFence fence(access);
+  C2AtomicAccessFence fence(access);
   resolve_address(access);
   return atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type);
 }
 
 Node* BarrierSetC2::atomic_cmpxchg_bool_at(C2AtomicAccess& access, Node* expected_val,
                                            Node* new_val, const Type* value_type) const {
-  C2AccessFence fence(access);
+  C2AtomicAccessFence fence(access);
   resolve_address(access);
   return atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type);
 }
 
 Node* BarrierSetC2::atomic_xchg_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const {
-  C2AccessFence fence(access);
+  C2AtomicAccessFence fence(access);
   resolve_address(access);
   return atomic_xchg_at_resolved(access, new_val, value_type);
 }
 
 Node* BarrierSetC2::atomic_add_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const {
-  C2AccessFence fence(access);
+  C2AtomicAccessFence fence(access);
   resolve_address(access);
   return atomic_add_at_resolved(access, new_val, value_type);
 }
 
 void BarrierSetC2::clone(GraphKit* kit, Node* src, Node* dst, Node* size, bool is_array) const {
< prev index next >