8036851: volatile double accesses are not explicitly atomic in C2
authoranoll
Tue, 06 May 2014 09:17:57 +0200
changeset 24345 616bc709c0e4
parent 24344 9cd6465ec36c
child 24347 c657ae48974c
8036851: volatile double accesses are not explicitly atomic in C2 Summary: The C2 structure is adapted to distinguish between volatile and non-volatile double accesses. Reviewed-by: twisti, kvn Contributed-by: Tobias Hartmann <tobias.hartmann@oracle.com>
hotspot/src/share/vm/opto/graphKit.cpp
hotspot/src/share/vm/opto/memnode.cpp
hotspot/src/share/vm/opto/memnode.hpp
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Mon May 05 15:10:43 2014 +0200
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Tue May 06 09:17:57 2014 +0200
@@ -1509,6 +1509,8 @@
   Node* ld;
   if (require_atomic_access && bt == T_LONG) {
     ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t, mo);
+  } else if (require_atomic_access && bt == T_DOUBLE) {
+    ld = LoadDNode::make_atomic(C, ctl, mem, adr, adr_type, t, mo);
   } else {
     ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo);
   }
@@ -1531,6 +1533,8 @@
   Node* st;
   if (require_atomic_access && bt == T_LONG) {
     st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val, mo);
+  } else if (require_atomic_access && bt == T_DOUBLE) {
+    st = StoreDNode::make_atomic(C, ctl, mem, adr, adr_type, val, mo);
   } else {
     st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt, mo);
   }
--- a/hotspot/src/share/vm/opto/memnode.cpp	Mon May 05 15:10:43 2014 +0200
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Tue May 06 09:17:57 2014 +0200
@@ -938,6 +938,10 @@
   return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic);
 }
 
+LoadDNode* LoadDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) {
+  bool require_atomic = true;
+  return new (C) LoadDNode(ctl, mem, adr, adr_type, rt, mo, require_atomic);
+}
 
 
 
@@ -2380,6 +2384,11 @@
   return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic);
 }
 
+StoreDNode* StoreDNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) {
+  bool require_atomic = true;
+  return new (C) StoreDNode(ctl, mem, adr, adr_type, val, mo, require_atomic);
+}
+
 
 //--------------------------bottom_type----------------------------------------
 const Type *StoreNode::bottom_type() const {
--- a/hotspot/src/share/vm/opto/memnode.hpp	Mon May 05 15:10:43 2014 +0200
+++ b/hotspot/src/share/vm/opto/memnode.hpp	Tue May 06 09:17:57 2014 +0200
@@ -332,7 +332,7 @@
   virtual uint ideal_reg() const { return Op_RegL; }
   virtual int store_Opcode() const { return Op_StoreL; }
   virtual BasicType memory_type() const { return T_LONG; }
-  bool require_atomic_access() { return _require_atomic_access; }
+  bool require_atomic_access() const { return _require_atomic_access; }
   static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
                                 const Type* rt, MemOrd mo);
 #ifndef PRODUCT
@@ -367,13 +367,31 @@
 //------------------------------LoadDNode--------------------------------------
 // Load a double (64 bits) from memory
 class LoadDNode : public LoadNode {
+  virtual uint hash() const { return LoadNode::hash() + _require_atomic_access; }
+  virtual uint cmp( const Node &n ) const {
+    return _require_atomic_access == ((LoadDNode&)n)._require_atomic_access
+      && LoadNode::cmp(n);
+  }
+  virtual uint size_of() const { return sizeof(*this); }
+  const bool _require_atomic_access;  // is piecewise load forbidden?
+
 public:
-  LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
-    : LoadNode(c, mem, adr, at, t, mo) {}
+  LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t,
+            MemOrd mo, bool require_atomic_access = false)
+    : LoadNode(c, mem, adr, at, t, mo), _require_atomic_access(require_atomic_access) {}
   virtual int Opcode() const;
   virtual uint ideal_reg() const { return Op_RegD; }
   virtual int store_Opcode() const { return Op_StoreD; }
   virtual BasicType memory_type() const { return T_DOUBLE; }
+  bool require_atomic_access() const { return _require_atomic_access; }
+  static LoadDNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
+                                const Type* rt, MemOrd mo);
+#ifndef PRODUCT
+  virtual void dump_spec(outputStream *st) const {
+    LoadNode::dump_spec(st);
+    if (_require_atomic_access)  st->print(" Atomic!");
+  }
+#endif
 };
 
 //------------------------------LoadD_unalignedNode----------------------------
@@ -574,7 +592,7 @@
     : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {}
   virtual int Opcode() const;
   virtual BasicType memory_type() const { return T_LONG; }
-  bool require_atomic_access() { return _require_atomic_access; }
+  bool require_atomic_access() const { return _require_atomic_access; }
   static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo);
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const {
@@ -597,11 +615,28 @@
 //------------------------------StoreDNode-------------------------------------
 // Store double to memory
 class StoreDNode : public StoreNode {
+  virtual uint hash() const { return StoreNode::hash() + _require_atomic_access; }
+  virtual uint cmp( const Node &n ) const {
+    return _require_atomic_access == ((StoreDNode&)n)._require_atomic_access
+      && StoreNode::cmp(n);
+  }
+  virtual uint size_of() const { return sizeof(*this); }
+  const bool _require_atomic_access;  // is piecewise store forbidden?
 public:
-  StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
-    : StoreNode(c, mem, adr, at, val, mo) {}
+  StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val,
+             MemOrd mo, bool require_atomic_access = false)
+    : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {}
   virtual int Opcode() const;
   virtual BasicType memory_type() const { return T_DOUBLE; }
+  bool require_atomic_access() const { return _require_atomic_access; }
+  static StoreDNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo);
+#ifndef PRODUCT
+  virtual void dump_spec(outputStream *st) const {
+    StoreNode::dump_spec(st);
+    if (_require_atomic_access)  st->print(" Atomic!");
+  }
+#endif
+
 };
 
 //------------------------------StorePNode-------------------------------------