src/share/vm/opto/memnode.hpp

changeset 6479
2113136690bc
parent 5110
6f3fd5150b67
child 6485
da862781b584
     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; }

mercurial