1.1 --- a/src/share/vm/opto/memnode.hpp Thu Nov 07 11:47:11 2013 +0100 1.2 +++ b/src/share/vm/opto/memnode.hpp Fri Nov 15 11:05:32 2013 -0800 1.3 @@ -51,6 +51,10 @@ 1.4 ValueIn, // Value to store 1.5 OopStore // Preceeding oop store, only in StoreCM 1.6 }; 1.7 + typedef enum { unordered = 0, 1.8 + acquire, // Load has to acquire or be succeeded by MemBarAcquire. 1.9 + release // Store has to release or be preceded by MemBarRelease. 1.10 + } MemOrd; 1.11 protected: 1.12 MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at ) 1.13 : Node(c0,c1,c2 ) { 1.14 @@ -134,20 +138,32 @@ 1.15 //------------------------------LoadNode--------------------------------------- 1.16 // Load value; requires Memory and Address 1.17 class LoadNode : public MemNode { 1.18 +private: 1.19 + // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish 1.20 + // loads that can be reordered, and such requiring acquire semantics to 1.21 + // adhere to the Java specification. The required behaviour is stored in 1.22 + // this field. 1.23 + const MemOrd _mo; 1.24 + 1.25 protected: 1.26 - virtual uint cmp( const Node &n ) const; 1.27 + virtual uint cmp(const Node &n) const; 1.28 virtual uint size_of() const; // Size is bigger 1.29 const Type* const _type; // What kind of value is loaded? 1.30 public: 1.31 1.32 - LoadNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt ) 1.33 - : MemNode(c,mem,adr,at), _type(rt) { 1.34 + LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo) 1.35 + : MemNode(c,mem,adr,at), _type(rt), _mo(mo) { 1.36 init_class_id(Class_Load); 1.37 } 1.38 + inline bool is_unordered() const { return !is_acquire(); } 1.39 + inline bool is_acquire() const { 1.40 + assert(_mo == unordered || _mo == acquire, "unexpected"); 1.41 + return _mo == acquire; 1.42 + } 1.43 1.44 // Polymorphic factory method: 1.45 - static Node* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, 1.46 - const TypePtr* at, const Type *rt, BasicType bt ); 1.47 + static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, 1.48 + const TypePtr* at, const Type *rt, BasicType bt, MemOrd mo); 1.49 1.50 virtual uint hash() const; // Check the type 1.51 1.52 @@ -210,8 +226,8 @@ 1.53 // Load a byte (8bits signed) from memory 1.54 class LoadBNode : public LoadNode { 1.55 public: 1.56 - LoadBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE ) 1.57 - : LoadNode(c,mem,adr,at,ti) {} 1.58 + LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) 1.59 + : LoadNode(c, mem, adr, at, ti, mo) {} 1.60 virtual int Opcode() const; 1.61 virtual uint ideal_reg() const { return Op_RegI; } 1.62 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 1.63 @@ -224,8 +240,8 @@ 1.64 // Load a unsigned byte (8bits unsigned) from memory 1.65 class LoadUBNode : public LoadNode { 1.66 public: 1.67 - LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti = TypeInt::UBYTE ) 1.68 - : LoadNode(c, mem, adr, at, ti) {} 1.69 + LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo) 1.70 + : LoadNode(c, mem, adr, at, ti, mo) {} 1.71 virtual int Opcode() const; 1.72 virtual uint ideal_reg() const { return Op_RegI; } 1.73 virtual Node* Ideal(PhaseGVN *phase, bool can_reshape); 1.74 @@ -238,8 +254,8 @@ 1.75 // Load an unsigned short/char (16bits unsigned) from memory 1.76 class LoadUSNode : public LoadNode { 1.77 public: 1.78 - LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR ) 1.79 - : LoadNode(c,mem,adr,at,ti) {} 1.80 + LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) 1.81 + : LoadNode(c, mem, adr, at, ti, mo) {} 1.82 virtual int Opcode() const; 1.83 virtual uint ideal_reg() const { return Op_RegI; } 1.84 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 1.85 @@ -252,8 +268,8 @@ 1.86 // Load a short (16bits signed) from memory 1.87 class LoadSNode : public LoadNode { 1.88 public: 1.89 - LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT ) 1.90 - : LoadNode(c,mem,adr,at,ti) {} 1.91 + LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) 1.92 + : LoadNode(c, mem, adr, at, ti, mo) {} 1.93 virtual int Opcode() const; 1.94 virtual uint ideal_reg() const { return Op_RegI; } 1.95 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 1.96 @@ -266,8 +282,8 @@ 1.97 // Load an integer from memory 1.98 class LoadINode : public LoadNode { 1.99 public: 1.100 - LoadINode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT ) 1.101 - : LoadNode(c,mem,adr,at,ti) {} 1.102 + LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo) 1.103 + : LoadNode(c, mem, adr, at, ti, mo) {} 1.104 virtual int Opcode() const; 1.105 virtual uint ideal_reg() const { return Op_RegI; } 1.106 virtual int store_Opcode() const { return Op_StoreI; } 1.107 @@ -278,8 +294,8 @@ 1.108 // Load an array length from the array 1.109 class LoadRangeNode : public LoadINode { 1.110 public: 1.111 - LoadRangeNode( Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS ) 1.112 - : LoadINode(c,mem,adr,TypeAryPtr::RANGE,ti) {} 1.113 + LoadRangeNode(Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS) 1.114 + : LoadINode(c, mem, adr, TypeAryPtr::RANGE, ti, MemNode::unordered) {} 1.115 virtual int Opcode() const; 1.116 virtual const Type *Value( PhaseTransform *phase ) const; 1.117 virtual Node *Identity( PhaseTransform *phase ); 1.118 @@ -298,18 +314,16 @@ 1.119 const bool _require_atomic_access; // is piecewise load forbidden? 1.120 1.121 public: 1.122 - LoadLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, 1.123 - const TypeLong *tl = TypeLong::LONG, 1.124 - bool require_atomic_access = false ) 1.125 - : LoadNode(c,mem,adr,at,tl) 1.126 - , _require_atomic_access(require_atomic_access) 1.127 - {} 1.128 + LoadLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeLong *tl, 1.129 + MemOrd mo, bool require_atomic_access = false) 1.130 + : LoadNode(c, mem, adr, at, tl, mo), _require_atomic_access(require_atomic_access) {} 1.131 virtual int Opcode() const; 1.132 virtual uint ideal_reg() const { return Op_RegL; } 1.133 virtual int store_Opcode() const { return Op_StoreL; } 1.134 virtual BasicType memory_type() const { return T_LONG; } 1.135 bool require_atomic_access() { return _require_atomic_access; } 1.136 - static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt); 1.137 + static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, 1.138 + const Type* rt, MemOrd mo); 1.139 #ifndef PRODUCT 1.140 virtual void dump_spec(outputStream *st) const { 1.141 LoadNode::dump_spec(st); 1.142 @@ -322,8 +336,8 @@ 1.143 // Load a long from unaligned memory 1.144 class LoadL_unalignedNode : public LoadLNode { 1.145 public: 1.146 - LoadL_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) 1.147 - : LoadLNode(c,mem,adr,at) {} 1.148 + LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo) 1.149 + : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo) {} 1.150 virtual int Opcode() const; 1.151 }; 1.152 1.153 @@ -331,8 +345,8 @@ 1.154 // Load a float (64 bits) from memory 1.155 class LoadFNode : public LoadNode { 1.156 public: 1.157 - LoadFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::FLOAT ) 1.158 - : LoadNode(c,mem,adr,at,t) {} 1.159 + LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo) 1.160 + : LoadNode(c, mem, adr, at, t, mo) {} 1.161 virtual int Opcode() const; 1.162 virtual uint ideal_reg() const { return Op_RegF; } 1.163 virtual int store_Opcode() const { return Op_StoreF; } 1.164 @@ -343,8 +357,8 @@ 1.165 // Load a double (64 bits) from memory 1.166 class LoadDNode : public LoadNode { 1.167 public: 1.168 - LoadDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::DOUBLE ) 1.169 - : LoadNode(c,mem,adr,at,t) {} 1.170 + LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo) 1.171 + : LoadNode(c, mem, adr, at, t, mo) {} 1.172 virtual int Opcode() const; 1.173 virtual uint ideal_reg() const { return Op_RegD; } 1.174 virtual int store_Opcode() const { return Op_StoreD; } 1.175 @@ -355,8 +369,8 @@ 1.176 // Load a double from unaligned memory 1.177 class LoadD_unalignedNode : public LoadDNode { 1.178 public: 1.179 - LoadD_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at ) 1.180 - : LoadDNode(c,mem,adr,at) {} 1.181 + LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo) 1.182 + : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo) {} 1.183 virtual int Opcode() const; 1.184 }; 1.185 1.186 @@ -364,8 +378,8 @@ 1.187 // Load a pointer from memory (either object or array) 1.188 class LoadPNode : public LoadNode { 1.189 public: 1.190 - LoadPNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t ) 1.191 - : LoadNode(c,mem,adr,at,t) {} 1.192 + LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo) 1.193 + : LoadNode(c, mem, adr, at, t, mo) {} 1.194 virtual int Opcode() const; 1.195 virtual uint ideal_reg() const { return Op_RegP; } 1.196 virtual int store_Opcode() const { return Op_StoreP; } 1.197 @@ -387,8 +401,8 @@ 1.198 // Load a narrow oop from memory (either object or array) 1.199 class LoadNNode : public LoadNode { 1.200 public: 1.201 - LoadNNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t ) 1.202 - : LoadNode(c,mem,adr,at,t) {} 1.203 + LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo) 1.204 + : LoadNode(c, mem, adr, at, t, mo) {} 1.205 virtual int Opcode() const; 1.206 virtual uint ideal_reg() const { return Op_RegN; } 1.207 virtual int store_Opcode() const { return Op_StoreN; } 1.208 @@ -409,8 +423,8 @@ 1.209 // Load a Klass from an object 1.210 class LoadKlassNode : public LoadPNode { 1.211 public: 1.212 - LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk ) 1.213 - : LoadPNode(c,mem,adr,at,tk) {} 1.214 + LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo) 1.215 + : LoadPNode(c, mem, adr, at, tk, mo) {} 1.216 virtual int Opcode() const; 1.217 virtual const Type *Value( PhaseTransform *phase ) const; 1.218 virtual Node *Identity( PhaseTransform *phase ); 1.219 @@ -425,8 +439,8 @@ 1.220 // Load a narrow Klass from an object. 1.221 class LoadNKlassNode : public LoadNNode { 1.222 public: 1.223 - LoadNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk ) 1.224 - : LoadNNode(c,mem,adr,at,tk) {} 1.225 + LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo) 1.226 + : LoadNNode(c, mem, adr, at, tk, mo) {} 1.227 virtual int Opcode() const; 1.228 virtual uint ideal_reg() const { return Op_RegN; } 1.229 virtual int store_Opcode() const { return Op_StoreNKlass; } 1.230 @@ -441,6 +455,14 @@ 1.231 //------------------------------StoreNode-------------------------------------- 1.232 // Store value; requires Store, Address and Value 1.233 class StoreNode : public MemNode { 1.234 +private: 1.235 + // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish 1.236 + // stores that can be reordered, and such requiring release semantics to 1.237 + // adhere to the Java specification. The required behaviour is stored in 1.238 + // this field. 1.239 + const MemOrd _mo; 1.240 + // Needed for proper cloning. 1.241 + virtual uint size_of() const { return sizeof(*this); } 1.242 protected: 1.243 virtual uint cmp( const Node &n ) const; 1.244 virtual bool depends_only_on_test() const { return false; } 1.245 @@ -449,18 +471,44 @@ 1.246 Node *Ideal_sign_extended_input(PhaseGVN *phase, int num_bits); 1.247 1.248 public: 1.249 - StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) 1.250 - : MemNode(c,mem,adr,at,val) { 1.251 + // We must ensure that stores of object references will be visible 1.252 + // only after the object's initialization. So the callers of this 1.253 + // procedure must indicate that the store requires `release' 1.254 + // semantics, if the stored value is an object reference that might 1.255 + // point to a new object and may become externally visible. 1.256 + StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.257 + : MemNode(c, mem, adr, at, val), _mo(mo) { 1.258 init_class_id(Class_Store); 1.259 } 1.260 - StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store ) 1.261 - : MemNode(c,mem,adr,at,val,oop_store) { 1.262 + StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, MemOrd mo) 1.263 + : MemNode(c, mem, adr, at, val, oop_store), _mo(mo) { 1.264 init_class_id(Class_Store); 1.265 } 1.266 1.267 - // Polymorphic factory method: 1.268 - static StoreNode* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr, 1.269 - const TypePtr* at, Node *val, BasicType bt ); 1.270 + inline bool is_unordered() const { return !is_release(); } 1.271 + inline bool is_release() const { 1.272 + assert((_mo == unordered || _mo == release), "unexpected"); 1.273 + return _mo == release; 1.274 + } 1.275 + 1.276 + // Conservatively release stores of object references in order to 1.277 + // ensure visibility of object initialization. 1.278 + static inline MemOrd release_if_reference(const BasicType t) { 1.279 + const MemOrd mo = (t == T_ARRAY || 1.280 + t == T_ADDRESS || // Might be the address of an object reference (`boxing'). 1.281 + t == T_OBJECT) ? release : unordered; 1.282 + return mo; 1.283 + } 1.284 + 1.285 + // Polymorphic factory method 1.286 + // 1.287 + // We must ensure that stores of object references will be visible 1.288 + // only after the object's initialization. So the callers of this 1.289 + // procedure must indicate that the store requires `release' 1.290 + // semantics, if the stored value is an object reference that might 1.291 + // point to a new object and may become externally visible. 1.292 + static StoreNode* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr, 1.293 + const TypePtr* at, Node *val, BasicType bt, MemOrd mo); 1.294 1.295 virtual uint hash() const; // Check the type 1.296 1.297 @@ -491,7 +539,8 @@ 1.298 // Store byte to memory 1.299 class StoreBNode : public StoreNode { 1.300 public: 1.301 - StoreBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.302 + StoreBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.303 + : StoreNode(c, mem, adr, at, val, mo) {} 1.304 virtual int Opcode() const; 1.305 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 1.306 virtual BasicType memory_type() const { return T_BYTE; } 1.307 @@ -501,7 +550,8 @@ 1.308 // Store char/short to memory 1.309 class StoreCNode : public StoreNode { 1.310 public: 1.311 - StoreCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.312 + StoreCNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.313 + : StoreNode(c, mem, adr, at, val, mo) {} 1.314 virtual int Opcode() const; 1.315 virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 1.316 virtual BasicType memory_type() const { return T_CHAR; } 1.317 @@ -511,7 +561,8 @@ 1.318 // Store int to memory 1.319 class StoreINode : public StoreNode { 1.320 public: 1.321 - StoreINode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.322 + StoreINode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.323 + : StoreNode(c, mem, adr, at, val, mo) {} 1.324 virtual int Opcode() const; 1.325 virtual BasicType memory_type() const { return T_INT; } 1.326 }; 1.327 @@ -528,15 +579,12 @@ 1.328 const bool _require_atomic_access; // is piecewise store forbidden? 1.329 1.330 public: 1.331 - StoreLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, 1.332 - bool require_atomic_access = false ) 1.333 - : StoreNode(c,mem,adr,at,val) 1.334 - , _require_atomic_access(require_atomic_access) 1.335 - {} 1.336 + StoreLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo, bool require_atomic_access = false) 1.337 + : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {} 1.338 virtual int Opcode() const; 1.339 virtual BasicType memory_type() const { return T_LONG; } 1.340 bool require_atomic_access() { return _require_atomic_access; } 1.341 - static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val); 1.342 + static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo); 1.343 #ifndef PRODUCT 1.344 virtual void dump_spec(outputStream *st) const { 1.345 StoreNode::dump_spec(st); 1.346 @@ -549,7 +597,8 @@ 1.347 // Store float to memory 1.348 class StoreFNode : public StoreNode { 1.349 public: 1.350 - StoreFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.351 + StoreFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.352 + : StoreNode(c, mem, adr, at, val, mo) {} 1.353 virtual int Opcode() const; 1.354 virtual BasicType memory_type() const { return T_FLOAT; } 1.355 }; 1.356 @@ -558,7 +607,8 @@ 1.357 // Store double to memory 1.358 class StoreDNode : public StoreNode { 1.359 public: 1.360 - StoreDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.361 + StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.362 + : StoreNode(c, mem, adr, at, val, mo) {} 1.363 virtual int Opcode() const; 1.364 virtual BasicType memory_type() const { return T_DOUBLE; } 1.365 }; 1.366 @@ -567,7 +617,8 @@ 1.367 // Store pointer to memory 1.368 class StorePNode : public StoreNode { 1.369 public: 1.370 - StorePNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.371 + StorePNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.372 + : StoreNode(c, mem, adr, at, val, mo) {} 1.373 virtual int Opcode() const; 1.374 virtual BasicType memory_type() const { return T_ADDRESS; } 1.375 }; 1.376 @@ -576,7 +627,8 @@ 1.377 // Store narrow oop to memory 1.378 class StoreNNode : public StoreNode { 1.379 public: 1.380 - StoreNNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {} 1.381 + StoreNNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.382 + : StoreNode(c, mem, adr, at, val, mo) {} 1.383 virtual int Opcode() const; 1.384 virtual BasicType memory_type() const { return T_NARROWOOP; } 1.385 }; 1.386 @@ -585,7 +637,8 @@ 1.387 // Store narrow klass to memory 1.388 class StoreNKlassNode : public StoreNNode { 1.389 public: 1.390 - StoreNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNNode(c,mem,adr,at,val) {} 1.391 + StoreNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo) 1.392 + : StoreNNode(c, mem, adr, at, val, mo) {} 1.393 virtual int Opcode() const; 1.394 virtual BasicType memory_type() const { return T_NARROWKLASS; } 1.395 }; 1.396 @@ -606,7 +659,7 @@ 1.397 1.398 public: 1.399 StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) : 1.400 - StoreNode(c,mem,adr,at,val,oop_store), 1.401 + StoreNode(c, mem, adr, at, val, oop_store, MemNode::release), 1.402 _oop_alias_idx(oop_alias_idx) { 1.403 assert(_oop_alias_idx >= Compile::AliasIdxRaw || 1.404 _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0, 1.405 @@ -626,8 +679,8 @@ 1.406 // On PowerPC and friends it's a real load-locked. 1.407 class LoadPLockedNode : public LoadPNode { 1.408 public: 1.409 - LoadPLockedNode( Node *c, Node *mem, Node *adr ) 1.410 - : LoadPNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) {} 1.411 + LoadPLockedNode(Node *c, Node *mem, Node *adr, MemOrd mo) 1.412 + : LoadPNode(c, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, mo) {} 1.413 virtual int Opcode() const; 1.414 virtual int store_Opcode() const { return Op_StorePConditional; } 1.415 virtual bool depends_only_on_test() const { return true; }