# HG changeset patch # User anoll # Date 1399360677 -7200 # Node ID 55d07ec5bde435df649cb8d0b6dd80694a7a996e # Parent 8c3941f2020c7da315a9798249ea85cf24b55619 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 diff -r 8c3941f2020c -r 55d07ec5bde4 src/share/vm/opto/graphKit.cpp --- a/src/share/vm/opto/graphKit.cpp Tue May 26 11:26:50 2015 -0700 +++ b/src/share/vm/opto/graphKit.cpp Tue May 06 09:17:57 2014 +0200 @@ -1460,6 +1460,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); } @@ -1482,6 +1484,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); } diff -r 8c3941f2020c -r 55d07ec5bde4 src/share/vm/opto/memnode.cpp --- a/src/share/vm/opto/memnode.cpp Tue May 26 11:26:50 2015 -0700 +++ b/src/share/vm/opto/memnode.cpp Tue May 06 09:17:57 2014 +0200 @@ -940,6 +940,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); +} @@ -2398,6 +2402,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 { diff -r 8c3941f2020c -r 55d07ec5bde4 src/share/vm/opto/memnode.hpp --- a/src/share/vm/opto/memnode.hpp Tue May 26 11:26:50 2015 -0700 +++ b/src/share/vm/opto/memnode.hpp Tue May 06 09:17:57 2014 +0200 @@ -336,7 +336,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 @@ -371,13 +371,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---------------------------- @@ -582,7 +600,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 { @@ -605,11 +623,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-------------------------------------