mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-24 04:54:40 +02:00
8036851: volatile double accesses are not explicitly atomic in C2
The C2 structure is adapted to distinguish between volatile and non-volatile double accesses. Reviewed-by: twisti, kvn
This commit is contained in:
parent
ded0d16e25
commit
85296fec28
3 changed files with 54 additions and 6 deletions
|
@ -1509,6 +1509,8 @@ Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
|
||||||
Node* ld;
|
Node* ld;
|
||||||
if (require_atomic_access && bt == T_LONG) {
|
if (require_atomic_access && bt == T_LONG) {
|
||||||
ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t, mo);
|
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 {
|
} else {
|
||||||
ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo);
|
ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo);
|
||||||
}
|
}
|
||||||
|
@ -1531,6 +1533,8 @@ Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
|
||||||
Node* st;
|
Node* st;
|
||||||
if (require_atomic_access && bt == T_LONG) {
|
if (require_atomic_access && bt == T_LONG) {
|
||||||
st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val, mo);
|
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 {
|
} else {
|
||||||
st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt, mo);
|
st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt, mo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -938,6 +938,10 @@ LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, c
|
||||||
return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic);
|
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 @@ StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr,
|
||||||
return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic);
|
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----------------------------------------
|
//--------------------------bottom_type----------------------------------------
|
||||||
const Type *StoreNode::bottom_type() const {
|
const Type *StoreNode::bottom_type() const {
|
||||||
|
|
|
@ -332,7 +332,7 @@ public:
|
||||||
virtual uint ideal_reg() const { return Op_RegL; }
|
virtual uint ideal_reg() const { return Op_RegL; }
|
||||||
virtual int store_Opcode() const { return Op_StoreL; }
|
virtual int store_Opcode() const { return Op_StoreL; }
|
||||||
virtual BasicType memory_type() const { return T_LONG; }
|
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,
|
static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
|
||||||
const Type* rt, MemOrd mo);
|
const Type* rt, MemOrd mo);
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -367,13 +367,31 @@ public:
|
||||||
//------------------------------LoadDNode--------------------------------------
|
//------------------------------LoadDNode--------------------------------------
|
||||||
// Load a double (64 bits) from memory
|
// Load a double (64 bits) from memory
|
||||||
class LoadDNode : public LoadNode {
|
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:
|
public:
|
||||||
LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
|
LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t,
|
||||||
: LoadNode(c, mem, adr, at, t, mo) {}
|
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 int Opcode() const;
|
||||||
virtual uint ideal_reg() const { return Op_RegD; }
|
virtual uint ideal_reg() const { return Op_RegD; }
|
||||||
virtual int store_Opcode() const { return Op_StoreD; }
|
virtual int store_Opcode() const { return Op_StoreD; }
|
||||||
virtual BasicType memory_type() const { return T_DOUBLE; }
|
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----------------------------
|
//------------------------------LoadD_unalignedNode----------------------------
|
||||||
|
@ -574,7 +592,7 @@ public:
|
||||||
: StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {}
|
: StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {}
|
||||||
virtual int Opcode() const;
|
virtual int Opcode() const;
|
||||||
virtual BasicType memory_type() const { return T_LONG; }
|
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);
|
static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo);
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
virtual void dump_spec(outputStream *st) const {
|
virtual void dump_spec(outputStream *st) const {
|
||||||
|
@ -597,11 +615,28 @@ public:
|
||||||
//------------------------------StoreDNode-------------------------------------
|
//------------------------------StoreDNode-------------------------------------
|
||||||
// Store double to memory
|
// Store double to memory
|
||||||
class StoreDNode : public StoreNode {
|
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:
|
public:
|
||||||
StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
|
StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val,
|
||||||
: StoreNode(c, mem, adr, at, val, mo) {}
|
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 int Opcode() const;
|
||||||
virtual BasicType memory_type() const { return T_DOUBLE; }
|
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-------------------------------------
|
//------------------------------StorePNode-------------------------------------
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue