8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering

Fri, 15 Nov 2013 11:05:32 -0800

author
goetz
date
Fri, 15 Nov 2013 11:05:32 -0800
changeset 6479
2113136690bc
parent 6477
eb178e97560c
child 6480
ea78de16a4a4

8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering
Summary: Add a field to C2 LoadNode and StoreNode classes which indicates whether the load/store should do an acquire/release on platforms which support it.
Reviewed-by: kvn

src/share/vm/opto/generateOptoStub.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/graphKit.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/idealKit.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/idealKit.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/library_call.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/macro.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/matcher.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/memnode.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/mulnode.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parse1.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parse2.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parse3.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/parseHelper.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/stringopts.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/vectornode.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/generateOptoStub.cpp	Thu Nov 07 11:47:11 2013 +0100
     1.2 +++ b/src/share/vm/opto/generateOptoStub.cpp	Fri Nov 15 11:05:32 2013 -0800
     1.3 @@ -104,13 +104,12 @@
     1.4    //
     1.5    Node *adr_sp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_sp_offset()));
     1.6    Node *last_sp = basic_plus_adr(top(), frameptr(), (intptr_t) STACK_BIAS);
     1.7 -  store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias);
     1.8 +  store_to_memory(NULL, adr_sp, last_sp, T_ADDRESS, NoAlias, MemNode::unordered);
     1.9  
    1.10    // Set _thread_in_native
    1.11    // The order of stores into TLS is critical!  Setting _thread_in_native MUST
    1.12    // be last, because a GC is allowed at any time after setting it and the GC
    1.13    // will require last_Java_pc and last_Java_sp.
    1.14 -  Node* adr_state = basic_plus_adr(top(), thread, in_bytes(JavaThread::thread_state_offset()));
    1.15  
    1.16    //-----------------------------
    1.17    // Compute signature for C call.  Varies from the Java signature!
    1.18 @@ -225,16 +224,15 @@
    1.19    //-----------------------------
    1.20  
    1.21    // Clear last_Java_sp
    1.22 -  store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias);
    1.23 +  store_to_memory(NULL, adr_sp, null(), T_ADDRESS, NoAlias, MemNode::unordered);
    1.24    // Clear last_Java_pc and (optionally)_flags
    1.25 -  store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias);
    1.26 +  store_to_memory(NULL, adr_last_Java_pc, null(), T_ADDRESS, NoAlias, MemNode::unordered);
    1.27  #if defined(SPARC)
    1.28 -  store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias);
    1.29 +  store_to_memory(NULL, adr_flags, intcon(0), T_INT, NoAlias, MemNode::unordered);
    1.30  #endif /* defined(SPARC) */
    1.31  #if (defined(IA64) && !defined(AIX))
    1.32    Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset()));
    1.33 -  if( os::is_MP() ) insert_mem_bar(Op_MemBarRelease);
    1.34 -  store_to_memory(NULL, adr_last_Java_fp,    null(),    T_ADDRESS, NoAlias);
    1.35 +  store_to_memory(NULL, adr_last_Java_fp, null(), T_ADDRESS, NoAlias, MemNode::unordered);
    1.36  #endif
    1.37  
    1.38    // For is-fancy-jump, the C-return value is also the branch target
    1.39 @@ -242,16 +240,16 @@
    1.40    // Runtime call returning oop in TLS?  Fetch it out
    1.41    if( pass_tls ) {
    1.42      Node* adr = basic_plus_adr(top(), thread, in_bytes(JavaThread::vm_result_offset()));
    1.43 -    Node* vm_result = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
    1.44 +    Node* vm_result = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, MemNode::unordered);
    1.45      map()->set_req(TypeFunc::Parms, vm_result); // vm_result passed as result
    1.46      // clear thread-local-storage(tls)
    1.47 -    store_to_memory(NULL, adr, null(), T_ADDRESS, NoAlias);
    1.48 +    store_to_memory(NULL, adr, null(), T_ADDRESS, NoAlias, MemNode::unordered);
    1.49    }
    1.50  
    1.51    //-----------------------------
    1.52    // check exception
    1.53    Node* adr = basic_plus_adr(top(), thread, in_bytes(Thread::pending_exception_offset()));
    1.54 -  Node* pending = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, false);
    1.55 +  Node* pending = make_load(NULL, adr, TypeOopPtr::BOTTOM, T_OBJECT, NoAlias, MemNode::unordered);
    1.56  
    1.57    Node* exit_memory = reset_memory();
    1.58  
     2.1 --- a/src/share/vm/opto/graphKit.cpp	Thu Nov 07 11:47:11 2013 +0100
     2.2 +++ b/src/share/vm/opto/graphKit.cpp	Fri Nov 15 11:05:32 2013 -0800
     2.3 @@ -494,7 +494,7 @@
     2.4      // first must access the should_post_on_exceptions_flag in this thread's JavaThread
     2.5      Node* jthread = _gvn.transform(new (C) ThreadLocalNode());
     2.6      Node* adr = basic_plus_adr(top(), jthread, in_bytes(JavaThread::should_post_on_exceptions_flag_offset()));
     2.7 -    Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, false);
     2.8 +    Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, MemNode::unordered);
     2.9  
    2.10      // Test the should_post_on_exceptions_flag vs. 0
    2.11      Node* chk = _gvn.transform( new (C) CmpINode(should_post_flag, intcon(0)) );
    2.12 @@ -596,7 +596,8 @@
    2.13  
    2.14        Node *adr = basic_plus_adr(ex_node, ex_node, offset);
    2.15        const TypeOopPtr* val_type = TypeOopPtr::make_from_klass(env()->String_klass());
    2.16 -      Node *store = store_oop_to_object(control(), ex_node, adr, adr_typ, null(), val_type, T_OBJECT);
    2.17 +      // Conservatively release stores of object references.
    2.18 +      Node *store = store_oop_to_object(control(), ex_node, adr, adr_typ, null(), val_type, T_OBJECT, MemNode::release);
    2.19  
    2.20        add_exception_state(make_exception_state(ex_node));
    2.21        return;
    2.22 @@ -1483,16 +1484,16 @@
    2.23  // factory methods in "int adr_idx"
    2.24  Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
    2.25                            int adr_idx,
    2.26 -                          bool require_atomic_access) {
    2.27 +                          MemNode::MemOrd mo, bool require_atomic_access) {
    2.28    assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
    2.29    const TypePtr* adr_type = NULL; // debug-mode-only argument
    2.30    debug_only(adr_type = C->get_adr_type(adr_idx));
    2.31    Node* mem = memory(adr_idx);
    2.32    Node* ld;
    2.33    if (require_atomic_access && bt == T_LONG) {
    2.34 -    ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t);
    2.35 +    ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t, mo);
    2.36    } else {
    2.37 -    ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt);
    2.38 +    ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo);
    2.39    }
    2.40    ld = _gvn.transform(ld);
    2.41    if ((bt == T_OBJECT) && C->do_escape_analysis() || C->eliminate_boxing()) {
    2.42 @@ -1504,6 +1505,7 @@
    2.43  
    2.44  Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
    2.45                                  int adr_idx,
    2.46 +                                MemNode::MemOrd mo,
    2.47                                  bool require_atomic_access) {
    2.48    assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
    2.49    const TypePtr* adr_type = NULL;
    2.50 @@ -1511,9 +1513,9 @@
    2.51    Node *mem = memory(adr_idx);
    2.52    Node* st;
    2.53    if (require_atomic_access && bt == T_LONG) {
    2.54 -    st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val);
    2.55 +    st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val, mo);
    2.56    } else {
    2.57 -    st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt);
    2.58 +    st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt, mo);
    2.59    }
    2.60    st = _gvn.transform(st);
    2.61    set_memory(st, adr_idx);
    2.62 @@ -1613,7 +1615,8 @@
    2.63                            Node* val,
    2.64                            const TypeOopPtr* val_type,
    2.65                            BasicType bt,
    2.66 -                          bool use_precise) {
    2.67 +                          bool use_precise,
    2.68 +                          MemNode::MemOrd mo) {
    2.69    // Transformation of a value which could be NULL pointer (CastPP #NULL)
    2.70    // could be delayed during Parse (for example, in adjust_map_after_if()).
    2.71    // Execute transformation here to avoid barrier generation in such case.
    2.72 @@ -1633,7 +1636,7 @@
    2.73                NULL /* pre_val */,
    2.74                bt);
    2.75  
    2.76 -  Node* store = store_to_memory(control(), adr, val, bt, adr_idx);
    2.77 +  Node* store = store_to_memory(control(), adr, val, bt, adr_idx, mo);
    2.78    post_barrier(control(), store, obj, adr, adr_idx, val, bt, use_precise);
    2.79    return store;
    2.80  }
    2.81 @@ -1644,7 +1647,8 @@
    2.82                               Node* adr,  // actual adress to store val at
    2.83                               const TypePtr* adr_type,
    2.84                               Node* val,
    2.85 -                             BasicType bt) {
    2.86 +                             BasicType bt,
    2.87 +                             MemNode::MemOrd mo) {
    2.88    Compile::AliasType* at = C->alias_type(adr_type);
    2.89    const TypeOopPtr* val_type = NULL;
    2.90    if (adr_type->isa_instptr()) {
    2.91 @@ -1663,7 +1667,7 @@
    2.92    if (val_type == NULL) {
    2.93      val_type = TypeInstPtr::BOTTOM;
    2.94    }
    2.95 -  return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true);
    2.96 +  return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true, mo);
    2.97  }
    2.98  
    2.99  
   2.100 @@ -1707,7 +1711,7 @@
   2.101    const Type* elemtype = arytype->elem();
   2.102    BasicType elembt = elemtype->array_element_basic_type();
   2.103    Node* adr = array_element_address(ary, idx, elembt, arytype->size());
   2.104 -  Node* ld = make_load(ctl, adr, elemtype, elembt, arytype);
   2.105 +  Node* ld = make_load(ctl, adr, elemtype, elembt, arytype, MemNode::unordered);
   2.106    return ld;
   2.107  }
   2.108  
   2.109 @@ -1942,9 +1946,9 @@
   2.110  void GraphKit::increment_counter(Node* counter_addr) {
   2.111    int adr_type = Compile::AliasIdxRaw;
   2.112    Node* ctrl = control();
   2.113 -  Node* cnt  = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type);
   2.114 +  Node* cnt  = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
   2.115    Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
   2.116 -  store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type );
   2.117 +  store_to_memory(ctrl, counter_addr, incr, T_INT, adr_type, MemNode::unordered);
   2.118  }
   2.119  
   2.120  
   2.121 @@ -2525,7 +2529,8 @@
   2.122  
   2.123    // First load the super-klass's check-offset
   2.124    Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) );
   2.125 -  Node *chk_off = _gvn.transform( new (C) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) );
   2.126 +  Node *chk_off = _gvn.transform(new (C) LoadINode(NULL, memory(p1), p1, _gvn.type(p1)->is_ptr(),
   2.127 +                                                   TypeInt::INT, MemNode::unordered));
   2.128    int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset());
   2.129    bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con);
   2.130  
   2.131 @@ -3238,7 +3243,7 @@
   2.132    }
   2.133    constant_value = Klass::_lh_neutral_value;  // put in a known value
   2.134    Node* lhp = basic_plus_adr(klass_node, klass_node, in_bytes(Klass::layout_helper_offset()));
   2.135 -  return make_load(NULL, lhp, TypeInt::INT, T_INT);
   2.136 +  return make_load(NULL, lhp, TypeInt::INT, T_INT, MemNode::unordered);
   2.137  }
   2.138  
   2.139  // We just put in an allocate/initialize with a big raw-memory effect.
   2.140 @@ -3773,7 +3778,7 @@
   2.141  
   2.142    // Smash zero into card
   2.143    if( !UseConcMarkSweepGC ) {
   2.144 -    __ store(__ ctrl(), card_adr, zero, bt, adr_type);
   2.145 +    __ store(__ ctrl(), card_adr, zero, bt, adr_type, MemNode::release);
   2.146    } else {
   2.147      // Specialized path for CM store barrier
   2.148      __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type);
   2.149 @@ -3870,9 +3875,9 @@
   2.150  
   2.151          // Now get the buffer location we will log the previous value into and store it
   2.152          Node *log_addr = __ AddP(no_base, buffer, next_index);
   2.153 -        __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw);
   2.154 +        __ store(__ ctrl(), log_addr, pre_val, T_OBJECT, Compile::AliasIdxRaw, MemNode::unordered);
   2.155          // update the index
   2.156 -        __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw);
   2.157 +        __ store(__ ctrl(), index_adr, next_index, index_bt, Compile::AliasIdxRaw, MemNode::unordered);
   2.158  
   2.159        } __ else_(); {
   2.160  
   2.161 @@ -3912,8 +3917,9 @@
   2.162      Node* next_index = _gvn.transform(new (C) SubXNode(index, __ ConX(sizeof(intptr_t))));
   2.163      Node* log_addr = __ AddP(no_base, buffer, next_index);
   2.164  
   2.165 -    __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw);
   2.166 -    __ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw);
   2.167 +    // Order, see storeCM.
   2.168 +    __ store(__ ctrl(), log_addr, card_adr, T_ADDRESS, Compile::AliasIdxRaw, MemNode::unordered);
   2.169 +    __ store(__ ctrl(), index_adr, next_index, TypeX_X->basic_type(), Compile::AliasIdxRaw, MemNode::unordered);
   2.170  
   2.171    } __ else_(); {
   2.172      __ make_leaf_call(tf, CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), "g1_wb_post", card_adr, __ thread());
   2.173 @@ -4043,7 +4049,7 @@
   2.174      int offset_field_idx = C->get_alias_index(offset_field_type);
   2.175      return make_load(ctrl,
   2.176                       basic_plus_adr(str, str, offset_offset),
   2.177 -                     TypeInt::INT, T_INT, offset_field_idx);
   2.178 +                     TypeInt::INT, T_INT, offset_field_idx, MemNode::unordered);
   2.179    } else {
   2.180      return intcon(0);
   2.181    }
   2.182 @@ -4058,7 +4064,7 @@
   2.183      int count_field_idx = C->get_alias_index(count_field_type);
   2.184      return make_load(ctrl,
   2.185                       basic_plus_adr(str, str, count_offset),
   2.186 -                     TypeInt::INT, T_INT, count_field_idx);
   2.187 +                     TypeInt::INT, T_INT, count_field_idx, MemNode::unordered);
   2.188    } else {
   2.189      return load_array_length(load_String_value(ctrl, str));
   2.190    }
   2.191 @@ -4074,7 +4080,7 @@
   2.192                                                     ciTypeArrayKlass::make(T_CHAR), true, 0);
   2.193    int value_field_idx = C->get_alias_index(value_field_type);
   2.194    Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset),
   2.195 -                         value_type, T_OBJECT, value_field_idx);
   2.196 +                         value_type, T_OBJECT, value_field_idx, MemNode::unordered);
   2.197    // String.value field is known to be @Stable.
   2.198    if (UseImplicitStableValues) {
   2.199      load = cast_array_to_stable(load, value_type);
   2.200 @@ -4089,7 +4095,7 @@
   2.201    const TypePtr* offset_field_type = string_type->add_offset(offset_offset);
   2.202    int offset_field_idx = C->get_alias_index(offset_field_type);
   2.203    store_to_memory(ctrl, basic_plus_adr(str, offset_offset),
   2.204 -                  value, T_INT, offset_field_idx);
   2.205 +                  value, T_INT, offset_field_idx, MemNode::unordered);
   2.206  }
   2.207  
   2.208  void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) {
   2.209 @@ -4099,7 +4105,7 @@
   2.210    const TypePtr* value_field_type = string_type->add_offset(value_offset);
   2.211  
   2.212    store_oop_to_object(ctrl, str,  basic_plus_adr(str, value_offset), value_field_type,
   2.213 -      value, TypeAryPtr::CHARS, T_OBJECT);
   2.214 +      value, TypeAryPtr::CHARS, T_OBJECT, MemNode::unordered);
   2.215  }
   2.216  
   2.217  void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) {
   2.218 @@ -4109,7 +4115,7 @@
   2.219    const TypePtr* count_field_type = string_type->add_offset(count_offset);
   2.220    int count_field_idx = C->get_alias_index(count_field_type);
   2.221    store_to_memory(ctrl, basic_plus_adr(str, count_offset),
   2.222 -                  value, T_INT, count_field_idx);
   2.223 +                  value, T_INT, count_field_idx, MemNode::unordered);
   2.224  }
   2.225  
   2.226  Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) {
     3.1 --- a/src/share/vm/opto/graphKit.hpp	Thu Nov 07 11:47:11 2013 +0100
     3.2 +++ b/src/share/vm/opto/graphKit.hpp	Fri Nov 15 11:05:32 2013 -0800
     3.3 @@ -510,36 +510,50 @@
     3.4  
     3.5    // Create a LoadNode, reading from the parser's memory state.
     3.6    // (Note:  require_atomic_access is useful only with T_LONG.)
     3.7 +  //
     3.8 +  // We choose the unordered semantics by default because we have
     3.9 +  // adapted the `do_put_xxx' and `do_get_xxx' procedures for the case
    3.10 +  // of volatile fields.
    3.11    Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
    3.12 -                  bool require_atomic_access = false) {
    3.13 +                  MemNode::MemOrd mo, bool require_atomic_access = false) {
    3.14      // This version computes alias_index from bottom_type
    3.15      return make_load(ctl, adr, t, bt, adr->bottom_type()->is_ptr(),
    3.16 -                     require_atomic_access);
    3.17 +                     mo, require_atomic_access);
    3.18    }
    3.19 -  Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, const TypePtr* adr_type, bool require_atomic_access = false) {
    3.20 +  Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, const TypePtr* adr_type,
    3.21 +                  MemNode::MemOrd mo, bool require_atomic_access = false) {
    3.22      // This version computes alias_index from an address type
    3.23      assert(adr_type != NULL, "use other make_load factory");
    3.24      return make_load(ctl, adr, t, bt, C->get_alias_index(adr_type),
    3.25 -                     require_atomic_access);
    3.26 +                     mo, require_atomic_access);
    3.27    }
    3.28    // This is the base version which is given an alias index.
    3.29 -  Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, int adr_idx, bool require_atomic_access = false);
    3.30 +  Node* make_load(Node* ctl, Node* adr, const Type* t, BasicType bt, int adr_idx,
    3.31 +                  MemNode::MemOrd mo, bool require_atomic_access = false);
    3.32  
    3.33    // Create & transform a StoreNode and store the effect into the
    3.34    // parser's memory state.
    3.35 +  //
    3.36 +  // We must ensure that stores of object references will be visible
    3.37 +  // only after the object's initialization. So the clients of this
    3.38 +  // procedure must indicate that the store requires `release'
    3.39 +  // semantics, if the stored value is an object reference that might
    3.40 +  // point to a new object and may become externally visible.
    3.41    Node* store_to_memory(Node* ctl, Node* adr, Node* val, BasicType bt,
    3.42                          const TypePtr* adr_type,
    3.43 +                        MemNode::MemOrd mo,
    3.44                          bool require_atomic_access = false) {
    3.45      // This version computes alias_index from an address type
    3.46      assert(adr_type != NULL, "use other store_to_memory factory");
    3.47      return store_to_memory(ctl, adr, val, bt,
    3.48                             C->get_alias_index(adr_type),
    3.49 -                           require_atomic_access);
    3.50 +                           mo, require_atomic_access);
    3.51    }
    3.52    // This is the base version which is given alias index
    3.53    // Return the new StoreXNode
    3.54    Node* store_to_memory(Node* ctl, Node* adr, Node* val, BasicType bt,
    3.55                          int adr_idx,
    3.56 +                        MemNode::MemOrd,
    3.57                          bool require_atomic_access = false);
    3.58  
    3.59  
    3.60 @@ -557,40 +571,44 @@
    3.61  
    3.62    Node* store_oop(Node* ctl,
    3.63                    Node* obj,   // containing obj
    3.64 -                  Node* adr,  // actual adress to store val at
    3.65 +                  Node* adr,   // actual adress to store val at
    3.66                    const TypePtr* adr_type,
    3.67                    Node* val,
    3.68                    const TypeOopPtr* val_type,
    3.69                    BasicType bt,
    3.70 -                  bool use_precise);
    3.71 +                  bool use_precise,
    3.72 +                  MemNode::MemOrd mo);
    3.73  
    3.74    Node* store_oop_to_object(Node* ctl,
    3.75                              Node* obj,   // containing obj
    3.76 -                            Node* adr,  // actual adress to store val at
    3.77 +                            Node* adr,   // actual adress to store val at
    3.78                              const TypePtr* adr_type,
    3.79                              Node* val,
    3.80                              const TypeOopPtr* val_type,
    3.81 -                            BasicType bt) {
    3.82 -    return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, false);
    3.83 +                            BasicType bt,
    3.84 +                            MemNode::MemOrd mo) {
    3.85 +    return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, false, mo);
    3.86    }
    3.87  
    3.88    Node* store_oop_to_array(Node* ctl,
    3.89                             Node* obj,   // containing obj
    3.90 -                           Node* adr,  // actual adress to store val at
    3.91 +                           Node* adr,   // actual adress to store val at
    3.92                             const TypePtr* adr_type,
    3.93                             Node* val,
    3.94                             const TypeOopPtr* val_type,
    3.95 -                           BasicType bt) {
    3.96 -    return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true);
    3.97 +                           BasicType bt,
    3.98 +                           MemNode::MemOrd mo) {
    3.99 +    return store_oop(ctl, obj, adr, adr_type, val, val_type, bt, true, mo);
   3.100    }
   3.101  
   3.102    // Could be an array or object we don't know at compile time (unsafe ref.)
   3.103    Node* store_oop_to_unknown(Node* ctl,
   3.104                               Node* obj,   // containing obj
   3.105 -                             Node* adr,  // actual adress to store val at
   3.106 +                             Node* adr,   // actual adress to store val at
   3.107                               const TypePtr* adr_type,
   3.108                               Node* val,
   3.109 -                             BasicType bt);
   3.110 +                             BasicType bt,
   3.111 +                             MemNode::MemOrd mo);
   3.112  
   3.113    // For the few case where the barriers need special help
   3.114    void pre_barrier(bool do_load, Node* ctl,
     4.1 --- a/src/share/vm/opto/idealKit.cpp	Thu Nov 07 11:47:11 2013 +0100
     4.2 +++ b/src/share/vm/opto/idealKit.cpp	Fri Nov 15 11:05:32 2013 -0800
     4.3 @@ -359,25 +359,25 @@
     4.4    Node* mem = memory(adr_idx);
     4.5    Node* ld;
     4.6    if (require_atomic_access && bt == T_LONG) {
     4.7 -    ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t);
     4.8 +    ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t, MemNode::unordered);
     4.9    } else {
    4.10 -    ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt);
    4.11 +    ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, MemNode::unordered);
    4.12    }
    4.13    return transform(ld);
    4.14  }
    4.15  
    4.16  Node* IdealKit::store(Node* ctl, Node* adr, Node *val, BasicType bt,
    4.17 -                                int adr_idx,
    4.18 -                                bool require_atomic_access) {
    4.19 -  assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
    4.20 +                      int adr_idx,
    4.21 +                      MemNode::MemOrd mo, bool require_atomic_access) {
    4.22 +  assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory");
    4.23    const TypePtr* adr_type = NULL;
    4.24    debug_only(adr_type = C->get_adr_type(adr_idx));
    4.25    Node *mem = memory(adr_idx);
    4.26    Node* st;
    4.27    if (require_atomic_access && bt == T_LONG) {
    4.28 -    st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val);
    4.29 +    st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val, mo);
    4.30    } else {
    4.31 -    st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt);
    4.32 +    st = StoreNode::make(_gvn, ctl, mem, adr, adr_type, val, bt, mo);
    4.33    }
    4.34    st = transform(st);
    4.35    set_memory(st, adr_idx);
     5.1 --- a/src/share/vm/opto/idealKit.hpp	Thu Nov 07 11:47:11 2013 +0100
     5.2 +++ b/src/share/vm/opto/idealKit.hpp	Fri Nov 15 11:05:32 2013 -0800
     5.3 @@ -226,6 +226,7 @@
     5.4                Node* val,
     5.5                BasicType bt,
     5.6                int adr_idx,
     5.7 +              MemNode::MemOrd mo,
     5.8                bool require_atomic_access = false);
     5.9  
    5.10    // Store a card mark ordered after store_oop
     6.1 --- a/src/share/vm/opto/library_call.cpp	Thu Nov 07 11:47:11 2013 +0100
     6.2 +++ b/src/share/vm/opto/library_call.cpp	Fri Nov 15 11:05:32 2013 -0800
     6.3 @@ -1057,7 +1057,7 @@
     6.4    const Type* thread_type  = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
     6.5    Node* thread = _gvn.transform(new (C) ThreadLocalNode());
     6.6    Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
     6.7 -  Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
     6.8 +  Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT, MemNode::unordered);
     6.9    tls_output = thread;
    6.10    return threadObj;
    6.11  }
    6.12 @@ -2640,7 +2640,7 @@
    6.13    if (need_mem_bar) insert_mem_bar(Op_MemBarCPUOrder);
    6.14  
    6.15    if (!is_store) {
    6.16 -    Node* p = make_load(control(), adr, value_type, type, adr_type, is_volatile);
    6.17 +    Node* p = make_load(control(), adr, value_type, type, adr_type, MemNode::unordered, is_volatile);
    6.18      // load value
    6.19      switch (type) {
    6.20      case T_BOOLEAN:
    6.21 @@ -2684,13 +2684,14 @@
    6.22        break;
    6.23      }
    6.24  
    6.25 +    MemNode::MemOrd mo = is_volatile ? MemNode::release : MemNode::unordered;
    6.26      if (type != T_OBJECT ) {
    6.27 -      (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile);
    6.28 +      (void) store_to_memory(control(), adr, val, type, adr_type, mo, is_volatile);
    6.29      } else {
    6.30        // Possibly an oop being stored to Java heap or native memory
    6.31        if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) {
    6.32          // oop to Java heap.
    6.33 -        (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type);
    6.34 +        (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo);
    6.35        } else {
    6.36          // We can't tell at compile time if we are storing in the Java heap or outside
    6.37          // of it. So we need to emit code to conditionally do the proper type of
    6.38 @@ -2702,11 +2703,11 @@
    6.39          __ if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); {
    6.40            // Sync IdealKit and graphKit.
    6.41            sync_kit(ideal);
    6.42 -          Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type);
    6.43 +          Node* st = store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, type, mo);
    6.44            // Update IdealKit memory.
    6.45            __ sync_kit(this);
    6.46          } __ else_(); {
    6.47 -          __ store(__ ctrl(), adr, val, type, alias_type->index(), is_volatile);
    6.48 +          __ store(__ ctrl(), adr, val, type, alias_type->index(), mo, is_volatile);
    6.49          } __ end_if();
    6.50          // Final sync IdealKit and GraphKit.
    6.51          final_sync(ideal);
    6.52 @@ -2979,12 +2980,12 @@
    6.53        Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
    6.54        if (kind == LS_xchg) {
    6.55          load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr,
    6.56 -                                                              newval_enc, adr_type, value_type->make_narrowoop()));
    6.57 +                                                           newval_enc, adr_type, value_type->make_narrowoop()));
    6.58        } else {
    6.59          assert(kind == LS_cmpxchg, "wrong LoadStore operation");
    6.60          Node *oldval_enc = _gvn.transform(new (C) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop()));
    6.61          load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr,
    6.62 -                                                                   newval_enc, oldval_enc));
    6.63 +                                                                newval_enc, oldval_enc));
    6.64        }
    6.65      } else
    6.66  #endif
    6.67 @@ -3090,9 +3091,9 @@
    6.68    const bool require_atomic_access = true;
    6.69    Node* store;
    6.70    if (type == T_OBJECT) // reference stores need a store barrier.
    6.71 -    store = store_oop_to_unknown(control(), base, adr, adr_type, val, type);
    6.72 +    store = store_oop_to_unknown(control(), base, adr, adr_type, val, type, MemNode::release);
    6.73    else {
    6.74 -    store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access);
    6.75 +    store = store_to_memory(control(), adr, val, type, adr_type, MemNode::release, require_atomic_access);
    6.76    }
    6.77    insert_mem_bar(Op_MemBarCPUOrder);
    6.78    return true;
    6.79 @@ -3152,7 +3153,7 @@
    6.80      Node* insp = basic_plus_adr(kls, in_bytes(InstanceKlass::init_state_offset()));
    6.81      // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
    6.82      // can generate code to load it as unsigned byte.
    6.83 -    Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
    6.84 +    Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered);
    6.85      Node* bits = intcon(InstanceKlass::fully_initialized);
    6.86      test = _gvn.transform(new (C) SubINode(inst, bits));
    6.87      // The 'test' is non-zero if we need to take a slow path.
    6.88 @@ -3176,14 +3177,14 @@
    6.89    kls = null_check(kls, T_OBJECT);
    6.90    ByteSize offset = TRACE_ID_OFFSET;
    6.91    Node* insp = basic_plus_adr(kls, in_bytes(offset));
    6.92 -  Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG);
    6.93 +  Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG, MemNode::unordered);
    6.94    Node* bits = longcon(~0x03l); // ignore bit 0 & 1
    6.95    Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits));
    6.96    Node* clsused = longcon(0x01l); // set the class bit
    6.97    Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused));
    6.98  
    6.99    const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
   6.100 -  store_to_memory(control(), insp, orl, T_LONG, adr_type);
   6.101 +  store_to_memory(control(), insp, orl, T_LONG, adr_type, MemNode::unordered);
   6.102    set_result(andl);
   6.103    return true;
   6.104  }
   6.105 @@ -3192,15 +3193,15 @@
   6.106    Node* tls_ptr = NULL;
   6.107    Node* cur_thr = generate_current_thread(tls_ptr);
   6.108    Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
   6.109 -  Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS);
   6.110 +  Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
   6.111    p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::thread_id_offset()));
   6.112  
   6.113    Node* threadid = NULL;
   6.114    size_t thread_id_size = OSThread::thread_id_size();
   6.115    if (thread_id_size == (size_t) BytesPerLong) {
   6.116 -    threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG));
   6.117 +    threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG, MemNode::unordered));
   6.118    } else if (thread_id_size == (size_t) BytesPerInt) {
   6.119 -    threadid = make_load(control(), p, TypeInt::INT, T_INT);
   6.120 +    threadid = make_load(control(), p, TypeInt::INT, T_INT, MemNode::unordered);
   6.121    } else {
   6.122      ShouldNotReachHere();
   6.123    }
   6.124 @@ -3275,11 +3276,11 @@
   6.125  
   6.126    // (b) Interrupt bit on TLS must be false.
   6.127    Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
   6.128 -  Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS);
   6.129 +  Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS, MemNode::unordered);
   6.130    p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
   6.131  
   6.132    // Set the control input on the field _interrupted read to prevent it floating up.
   6.133 -  Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT);
   6.134 +  Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT, MemNode::unordered);
   6.135    Node* cmp_bit = _gvn.transform(new (C) CmpINode(int_bit, intcon(0)));
   6.136    Node* bol_bit = _gvn.transform(new (C) BoolNode(cmp_bit, BoolTest::ne));
   6.137  
   6.138 @@ -3347,7 +3348,7 @@
   6.139  // Given a klass oop, load its java mirror (a java.lang.Class oop).
   6.140  Node* LibraryCallKit::load_mirror_from_klass(Node* klass) {
   6.141    Node* p = basic_plus_adr(klass, in_bytes(Klass::java_mirror_offset()));
   6.142 -  return make_load(NULL, p, TypeInstPtr::MIRROR, T_OBJECT);
   6.143 +  return make_load(NULL, p, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
   6.144  }
   6.145  
   6.146  //-----------------------load_klass_from_mirror_common-------------------------
   6.147 @@ -3384,7 +3385,7 @@
   6.148    // Branch around if the given klass has the given modifier bit set.
   6.149    // Like generate_guard, adds a new path onto the region.
   6.150    Node* modp = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset()));
   6.151 -  Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT);
   6.152 +  Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT, MemNode::unordered);
   6.153    Node* mask = intcon(modifier_mask);
   6.154    Node* bits = intcon(modifier_bits);
   6.155    Node* mbit = _gvn.transform(new (C) AndINode(mods, mask));
   6.156 @@ -3501,7 +3502,7 @@
   6.157  
   6.158    case vmIntrinsics::_getModifiers:
   6.159      p = basic_plus_adr(kls, in_bytes(Klass::modifier_flags_offset()));
   6.160 -    query_value = make_load(NULL, p, TypeInt::INT, T_INT);
   6.161 +    query_value = make_load(NULL, p, TypeInt::INT, T_INT, MemNode::unordered);
   6.162      break;
   6.163  
   6.164    case vmIntrinsics::_isInterface:
   6.165 @@ -3559,7 +3560,7 @@
   6.166        // Be sure to pin the oop load to the guard edge just created:
   6.167        Node* is_array_ctrl = region->in(region->req()-1);
   6.168        Node* cma = basic_plus_adr(kls, in_bytes(ArrayKlass::component_mirror_offset()));
   6.169 -      Node* cmo = make_load(is_array_ctrl, cma, TypeInstPtr::MIRROR, T_OBJECT);
   6.170 +      Node* cmo = make_load(is_array_ctrl, cma, TypeInstPtr::MIRROR, T_OBJECT, MemNode::unordered);
   6.171        phi->add_req(cmo);
   6.172      }
   6.173      query_value = null();  // non-array case is null
   6.174 @@ -3567,7 +3568,7 @@
   6.175  
   6.176    case vmIntrinsics::_getClassAccessFlags:
   6.177      p = basic_plus_adr(kls, in_bytes(Klass::access_flags_offset()));
   6.178 -    query_value = make_load(NULL, p, TypeInt::INT, T_INT);
   6.179 +    query_value = make_load(NULL, p, TypeInt::INT, T_INT, MemNode::unordered);
   6.180      break;
   6.181  
   6.182    default:
   6.183 @@ -3933,7 +3934,7 @@
   6.184                       vtable_index*vtableEntry::size()) * wordSize +
   6.185                       vtableEntry::method_offset_in_bytes();
   6.186    Node* entry_addr  = basic_plus_adr(obj_klass, entry_offset);
   6.187 -  Node* target_call = make_load(NULL, entry_addr, TypePtr::NOTNULL, T_ADDRESS);
   6.188 +  Node* target_call = make_load(NULL, entry_addr, TypePtr::NOTNULL, T_ADDRESS, MemNode::unordered);
   6.189  
   6.190    // Compare the target method with the expected method (e.g., Object.hashCode).
   6.191    const TypePtr* native_call_addr = TypeMetadataPtr::make(method);
   6.192 @@ -4059,7 +4060,7 @@
   6.193  
   6.194    // Get the header out of the object, use LoadMarkNode when available
   6.195    Node* header_addr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
   6.196 -  Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type());
   6.197 +  Node* header = make_load(control(), header_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered);
   6.198  
   6.199    // Test the header to see if it is unlocked.
   6.200    Node *lock_mask      = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place);
   6.201 @@ -5480,7 +5481,7 @@
   6.202          // Store a zero to the immediately preceding jint:
   6.203          Node* x1 = _gvn.transform(new(C) AddXNode(start, MakeConX(-bump_bit)));
   6.204          Node* p1 = basic_plus_adr(dest, x1);
   6.205 -        mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT);
   6.206 +        mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT, MemNode::unordered);
   6.207          mem = _gvn.transform(mem);
   6.208        }
   6.209      }
   6.210 @@ -5530,8 +5531,8 @@
   6.211          ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) {
   6.212        Node* sptr = basic_plus_adr(src,  src_off);
   6.213        Node* dptr = basic_plus_adr(dest, dest_off);
   6.214 -      Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type);
   6.215 -      store_to_memory(control(), dptr, sval, T_INT, adr_type);
   6.216 +      Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
   6.217 +      store_to_memory(control(), dptr, sval, T_INT, adr_type, MemNode::unordered);
   6.218        src_off += BytesPerInt;
   6.219        dest_off += BytesPerInt;
   6.220      } else {
   6.221 @@ -5596,7 +5597,7 @@
   6.222    // super_check_offset, for the desired klass.
   6.223    int sco_offset = in_bytes(Klass::super_check_offset_offset());
   6.224    Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
   6.225 -  Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
   6.226 +  Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr(), TypeInt::INT, MemNode::unordered);
   6.227    Node* check_offset = ConvI2X(_gvn.transform(n3));
   6.228    Node* check_value  = dest_elem_klass;
   6.229  
   6.230 @@ -5737,7 +5738,7 @@
   6.231    Node* base = makecon(TypeRawPtr::make(StubRoutines::crc_table_addr()));
   6.232    Node* offset = _gvn.transform(new (C) LShiftINode(result, intcon(0x2)));
   6.233    Node* adr = basic_plus_adr(top(), base, ConvI2X(offset));
   6.234 -  result = make_load(control(), adr, TypeInt::INT, T_INT);
   6.235 +  result = make_load(control(), adr, TypeInt::INT, T_INT, MemNode::unordered);
   6.236  
   6.237    crc = _gvn.transform(new (C) URShiftINode(crc, intcon(8)));
   6.238    result = _gvn.transform(new (C) XorINode(crc, result));
   6.239 @@ -5838,7 +5839,7 @@
   6.240    const TypeOopPtr* object_type = TypeOopPtr::make_from_klass(klass);
   6.241  
   6.242    Node* no_ctrl = NULL;
   6.243 -  Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT);
   6.244 +  Node* result = make_load(no_ctrl, adr, object_type, T_OBJECT, MemNode::unordered);
   6.245  
   6.246    // Use the pre-barrier to record the value in the referent field
   6.247    pre_barrier(false /* do_load */,
   6.248 @@ -5885,7 +5886,7 @@
   6.249    const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass());
   6.250  
   6.251    // Build the load.
   6.252 -  Node* loadedField = make_load(NULL, adr, type, bt, adr_type, is_vol);
   6.253 +  Node* loadedField = make_load(NULL, adr, type, bt, adr_type, MemNode::unordered, is_vol);
   6.254    return loadedField;
   6.255  }
   6.256  
     7.1 --- a/src/share/vm/opto/macro.cpp	Thu Nov 07 11:47:11 2013 +0100
     7.2 +++ b/src/share/vm/opto/macro.cpp	Fri Nov 15 11:05:32 2013 -0800
     7.3 @@ -1084,7 +1084,7 @@
     7.4  Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) {
     7.5    Node* adr = basic_plus_adr(base, offset);
     7.6    const TypePtr* adr_type = adr->bottom_type()->is_ptr();
     7.7 -  Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt);
     7.8 +  Node* value = LoadNode::make(_igvn, ctl, mem, adr, adr_type, value_type, bt, MemNode::unordered);
     7.9    transform_later(value);
    7.10    return value;
    7.11  }
    7.12 @@ -1092,7 +1092,7 @@
    7.13  
    7.14  Node* PhaseMacroExpand::make_store(Node* ctl, Node* mem, Node* base, int offset, Node* value, BasicType bt) {
    7.15    Node* adr = basic_plus_adr(base, offset);
    7.16 -  mem = StoreNode::make(_igvn, ctl, mem, adr, NULL, value, bt);
    7.17 +  mem = StoreNode::make(_igvn, ctl, mem, adr, NULL, value, bt, MemNode::unordered);
    7.18    transform_later(mem);
    7.19    return mem;
    7.20  }
    7.21 @@ -1272,8 +1272,8 @@
    7.22      // Load(-locked) the heap top.
    7.23      // See note above concerning the control input when using a TLAB
    7.24      Node *old_eden_top = UseTLAB
    7.25 -      ? new (C) LoadPNode      (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM)
    7.26 -      : new (C) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr);
    7.27 +      ? new (C) LoadPNode      (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, MemNode::unordered)
    7.28 +      : new (C) LoadPLockedNode(contended_region, contended_phi_rawmem, eden_top_adr, MemNode::acquire);
    7.29  
    7.30      transform_later(old_eden_top);
    7.31      // Add to heap top to get a new heap top
    7.32 @@ -1320,7 +1320,7 @@
    7.33      if (UseTLAB) {
    7.34        Node* store_eden_top =
    7.35          new (C) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr,
    7.36 -                              TypeRawPtr::BOTTOM, new_eden_top);
    7.37 +                              TypeRawPtr::BOTTOM, new_eden_top, MemNode::unordered);
    7.38        transform_later(store_eden_top);
    7.39        fast_oop_ctrl = needgc_false; // No contention, so this is the fast path
    7.40        fast_oop_rawmem = store_eden_top;
    7.41 @@ -1700,9 +1700,10 @@
    7.42                     _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) );
    7.43        transform_later(eden_pf_adr);
    7.44  
    7.45 -      Node *old_pf_wm = new (C) LoadPNode( needgc_false,
    7.46 +      Node *old_pf_wm = new (C) LoadPNode(needgc_false,
    7.47                                     contended_phi_rawmem, eden_pf_adr,
    7.48 -                                   TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM );
    7.49 +                                   TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM,
    7.50 +                                   MemNode::unordered);
    7.51        transform_later(old_pf_wm);
    7.52  
    7.53        // check against new_eden_top
    7.54 @@ -1726,9 +1727,10 @@
    7.55        transform_later(new_pf_wmt );
    7.56        new_pf_wmt->set_req(0, need_pf_true);
    7.57  
    7.58 -      Node *store_new_wmt = new (C) StorePNode( need_pf_true,
    7.59 +      Node *store_new_wmt = new (C) StorePNode(need_pf_true,
    7.60                                         contended_phi_rawmem, eden_pf_adr,
    7.61 -                                       TypeRawPtr::BOTTOM, new_pf_wmt );
    7.62 +                                       TypeRawPtr::BOTTOM, new_pf_wmt,
    7.63 +                                       MemNode::unordered);
    7.64        transform_later(store_new_wmt);
    7.65  
    7.66        // adding prefetches
     8.1 --- a/src/share/vm/opto/matcher.cpp	Thu Nov 07 11:47:11 2013 +0100
     8.2 +++ b/src/share/vm/opto/matcher.cpp	Fri Nov 15 11:05:32 2013 -0800
     8.3 @@ -825,16 +825,15 @@
     8.4  
     8.5    // Compute generic short-offset Loads
     8.6  #ifdef _LP64
     8.7 -  MachNode *spillCP = match_tree(new (C) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
     8.8 +  MachNode *spillCP = match_tree(new (C) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered));
     8.9  #endif
    8.10 -  MachNode *spillI  = match_tree(new (C) LoadINode(NULL,mem,fp,atp));
    8.11 -  MachNode *spillL  = match_tree(new (C) LoadLNode(NULL,mem,fp,atp));
    8.12 -  MachNode *spillF  = match_tree(new (C) LoadFNode(NULL,mem,fp,atp));
    8.13 -  MachNode *spillD  = match_tree(new (C) LoadDNode(NULL,mem,fp,atp));
    8.14 -  MachNode *spillP  = match_tree(new (C) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
    8.15 +  MachNode *spillI  = match_tree(new (C) LoadINode(NULL,mem,fp,atp,TypeInt::INT,MemNode::unordered));
    8.16 +  MachNode *spillL  = match_tree(new (C) LoadLNode(NULL,mem,fp,atp,TypeLong::LONG,MemNode::unordered,false));
    8.17 +  MachNode *spillF  = match_tree(new (C) LoadFNode(NULL,mem,fp,atp,Type::FLOAT,MemNode::unordered));
    8.18 +  MachNode *spillD  = match_tree(new (C) LoadDNode(NULL,mem,fp,atp,Type::DOUBLE,MemNode::unordered));
    8.19 +  MachNode *spillP  = match_tree(new (C) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM,MemNode::unordered));
    8.20    assert(spillI != NULL && spillL != NULL && spillF != NULL &&
    8.21           spillD != NULL && spillP != NULL, "");
    8.22 -
    8.23    // Get the ADLC notion of the right regmask, for each basic type.
    8.24  #ifdef _LP64
    8.25    idealreg2regmask[Op_RegN] = &spillCP->out_RegMask();
     9.1 --- a/src/share/vm/opto/memnode.cpp	Thu Nov 07 11:47:11 2013 +0100
     9.2 +++ b/src/share/vm/opto/memnode.cpp	Fri Nov 15 11:05:32 2013 -0800
     9.3 @@ -907,7 +907,7 @@
     9.4  
     9.5  //----------------------------LoadNode::make-----------------------------------
     9.6  // Polymorphic factory method:
     9.7 -Node *LoadNode::make( PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt ) {
     9.8 +Node *LoadNode::make(PhaseGVN& gvn, Node *ctl, Node *mem, Node *adr, const TypePtr* adr_type, const Type *rt, BasicType bt, MemOrd mo) {
     9.9    Compile* C = gvn.C;
    9.10  
    9.11    // sanity check the alias category against the created node type
    9.12 @@ -923,34 +923,34 @@
    9.13            rt->isa_oopptr() || is_immutable_value(adr),
    9.14            "raw memory operations should have control edge");
    9.15    switch (bt) {
    9.16 -  case T_BOOLEAN: return new (C) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int()    );
    9.17 -  case T_BYTE:    return new (C) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
    9.18 -  case T_INT:     return new (C) LoadINode (ctl, mem, adr, adr_type, rt->is_int()    );
    9.19 -  case T_CHAR:    return new (C) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int()    );
    9.20 -  case T_SHORT:   return new (C) LoadSNode (ctl, mem, adr, adr_type, rt->is_int()    );
    9.21 -  case T_LONG:    return new (C) LoadLNode (ctl, mem, adr, adr_type, rt->is_long()   );
    9.22 -  case T_FLOAT:   return new (C) LoadFNode (ctl, mem, adr, adr_type, rt              );
    9.23 -  case T_DOUBLE:  return new (C) LoadDNode (ctl, mem, adr, adr_type, rt              );
    9.24 -  case T_ADDRESS: return new (C) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
    9.25 +  case T_BOOLEAN: return new (C) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int(),  mo);
    9.26 +  case T_BYTE:    return new (C) LoadBNode (ctl, mem, adr, adr_type, rt->is_int(),  mo);
    9.27 +  case T_INT:     return new (C) LoadINode (ctl, mem, adr, adr_type, rt->is_int(),  mo);
    9.28 +  case T_CHAR:    return new (C) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int(),  mo);
    9.29 +  case T_SHORT:   return new (C) LoadSNode (ctl, mem, adr, adr_type, rt->is_int(),  mo);
    9.30 +  case T_LONG:    return new (C) LoadLNode (ctl, mem, adr, adr_type, rt->is_long(), mo);
    9.31 +  case T_FLOAT:   return new (C) LoadFNode (ctl, mem, adr, adr_type, rt,            mo);
    9.32 +  case T_DOUBLE:  return new (C) LoadDNode (ctl, mem, adr, adr_type, rt,            mo);
    9.33 +  case T_ADDRESS: return new (C) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr(),  mo);
    9.34    case T_OBJECT:
    9.35  #ifdef _LP64
    9.36      if (adr->bottom_type()->is_ptr_to_narrowoop()) {
    9.37 -      Node* load  = gvn.transform(new (C) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
    9.38 +      Node* load  = gvn.transform(new (C) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop(), mo));
    9.39        return new (C) DecodeNNode(load, load->bottom_type()->make_ptr());
    9.40      } else
    9.41  #endif
    9.42      {
    9.43        assert(!adr->bottom_type()->is_ptr_to_narrowoop() && !adr->bottom_type()->is_ptr_to_narrowklass(), "should have got back a narrow oop");
    9.44 -      return new (C) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr());
    9.45 +      return new (C) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr(), mo);
    9.46      }
    9.47    }
    9.48    ShouldNotReachHere();
    9.49    return (LoadNode*)NULL;
    9.50  }
    9.51  
    9.52 -LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt) {
    9.53 +LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt, MemOrd mo) {
    9.54    bool require_atomic = true;
    9.55 -  return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic);
    9.56 +  return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), mo, require_atomic);
    9.57  }
    9.58  
    9.59  
    9.60 @@ -2032,12 +2032,12 @@
    9.61  #ifdef _LP64
    9.62    if (adr_type->is_ptr_to_narrowklass()) {
    9.63      assert(UseCompressedClassPointers, "no compressed klasses");
    9.64 -    Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass()));
    9.65 +    Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowklass(), MemNode::unordered));
    9.66      return new (C) DecodeNKlassNode(load_klass, load_klass->bottom_type()->make_ptr());
    9.67    }
    9.68  #endif
    9.69    assert(!adr_type->is_ptr_to_narrowklass() && !adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
    9.70 -  return new (C) LoadKlassNode(ctl, mem, adr, at, tk);
    9.71 +  return new (C) LoadKlassNode(ctl, mem, adr, at, tk, MemNode::unordered);
    9.72  }
    9.73  
    9.74  //------------------------------Value------------------------------------------
    9.75 @@ -2347,45 +2347,46 @@
    9.76  //=============================================================================
    9.77  //---------------------------StoreNode::make-----------------------------------
    9.78  // Polymorphic factory method:
    9.79 -StoreNode* StoreNode::make( PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt ) {
    9.80 +StoreNode* StoreNode::make(PhaseGVN& gvn, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, BasicType bt, MemOrd mo) {
    9.81 +  assert((mo == unordered || mo == release), "unexpected");
    9.82    Compile* C = gvn.C;
    9.83 -  assert( C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
    9.84 -          ctl != NULL, "raw memory operations should have control edge");
    9.85 +  assert(C->get_alias_index(adr_type) != Compile::AliasIdxRaw ||
    9.86 +         ctl != NULL, "raw memory operations should have control edge");
    9.87  
    9.88    switch (bt) {
    9.89    case T_BOOLEAN:
    9.90 -  case T_BYTE:    return new (C) StoreBNode(ctl, mem, adr, adr_type, val);
    9.91 -  case T_INT:     return new (C) StoreINode(ctl, mem, adr, adr_type, val);
    9.92 +  case T_BYTE:    return new (C) StoreBNode(ctl, mem, adr, adr_type, val, mo);
    9.93 +  case T_INT:     return new (C) StoreINode(ctl, mem, adr, adr_type, val, mo);
    9.94    case T_CHAR:
    9.95 -  case T_SHORT:   return new (C) StoreCNode(ctl, mem, adr, adr_type, val);
    9.96 -  case T_LONG:    return new (C) StoreLNode(ctl, mem, adr, adr_type, val);
    9.97 -  case T_FLOAT:   return new (C) StoreFNode(ctl, mem, adr, adr_type, val);
    9.98 -  case T_DOUBLE:  return new (C) StoreDNode(ctl, mem, adr, adr_type, val);
    9.99 +  case T_SHORT:   return new (C) StoreCNode(ctl, mem, adr, adr_type, val, mo);
   9.100 +  case T_LONG:    return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo);
   9.101 +  case T_FLOAT:   return new (C) StoreFNode(ctl, mem, adr, adr_type, val, mo);
   9.102 +  case T_DOUBLE:  return new (C) StoreDNode(ctl, mem, adr, adr_type, val, mo);
   9.103    case T_METADATA:
   9.104    case T_ADDRESS:
   9.105    case T_OBJECT:
   9.106  #ifdef _LP64
   9.107      if (adr->bottom_type()->is_ptr_to_narrowoop()) {
   9.108        val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop()));
   9.109 -      return new (C) StoreNNode(ctl, mem, adr, adr_type, val);
   9.110 +      return new (C) StoreNNode(ctl, mem, adr, adr_type, val, mo);
   9.111      } else if (adr->bottom_type()->is_ptr_to_narrowklass() ||
   9.112                 (UseCompressedClassPointers && val->bottom_type()->isa_klassptr() &&
   9.113                  adr->bottom_type()->isa_rawptr())) {
   9.114        val = gvn.transform(new (C) EncodePKlassNode(val, val->bottom_type()->make_narrowklass()));
   9.115 -      return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val);
   9.116 +      return new (C) StoreNKlassNode(ctl, mem, adr, adr_type, val, mo);
   9.117      }
   9.118  #endif
   9.119      {
   9.120 -      return new (C) StorePNode(ctl, mem, adr, adr_type, val);
   9.121 +      return new (C) StorePNode(ctl, mem, adr, adr_type, val, mo);
   9.122      }
   9.123    }
   9.124    ShouldNotReachHere();
   9.125    return (StoreNode*)NULL;
   9.126  }
   9.127  
   9.128 -StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val) {
   9.129 +StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo) {
   9.130    bool require_atomic = true;
   9.131 -  return new (C) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic);
   9.132 +  return new (C) StoreLNode(ctl, mem, adr, adr_type, val, mo, require_atomic);
   9.133  }
   9.134  
   9.135  
   9.136 @@ -2778,12 +2779,12 @@
   9.137  
   9.138    Node *zero = phase->makecon(TypeLong::ZERO);
   9.139    Node *off  = phase->MakeConX(BytesPerLong);
   9.140 -  mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero);
   9.141 +  mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false);
   9.142    count--;
   9.143    while( count-- ) {
   9.144      mem = phase->transform(mem);
   9.145      adr = phase->transform(new (phase->C) AddPNode(base,adr,off));
   9.146 -    mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero);
   9.147 +    mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero,MemNode::unordered,false);
   9.148    }
   9.149    return mem;
   9.150  }
   9.151 @@ -2827,7 +2828,7 @@
   9.152      Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(offset));
   9.153      adr = phase->transform(adr);
   9.154      const TypePtr* atp = TypeRawPtr::BOTTOM;
   9.155 -    mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
   9.156 +    mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered);
   9.157      mem = phase->transform(mem);
   9.158      offset += BytesPerInt;
   9.159    }
   9.160 @@ -2888,7 +2889,7 @@
   9.161      Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(done_offset));
   9.162      adr = phase->transform(adr);
   9.163      const TypePtr* atp = TypeRawPtr::BOTTOM;
   9.164 -    mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
   9.165 +    mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT, MemNode::unordered);
   9.166      mem = phase->transform(mem);
   9.167      done_offset += BytesPerInt;
   9.168    }
   9.169 @@ -3762,14 +3763,14 @@
   9.170        ++new_long;
   9.171        off[nst] = offset;
   9.172        st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp,
   9.173 -                                  phase->longcon(con), T_LONG);
   9.174 +                                  phase->longcon(con), T_LONG, MemNode::unordered);
   9.175      } else {
   9.176        // Omit either if it is a zero.
   9.177        if (con0 != 0) {
   9.178          ++new_int;
   9.179          off[nst]  = offset;
   9.180          st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp,
   9.181 -                                    phase->intcon(con0), T_INT);
   9.182 +                                    phase->intcon(con0), T_INT, MemNode::unordered);
   9.183        }
   9.184        if (con1 != 0) {
   9.185          ++new_int;
   9.186 @@ -3777,7 +3778,7 @@
   9.187          adr = make_raw_address(offset, phase);
   9.188          off[nst]  = offset;
   9.189          st[nst++] = StoreNode::make(*phase, ctl, zmem, adr, atp,
   9.190 -                                    phase->intcon(con1), T_INT);
   9.191 +                                    phase->intcon(con1), T_INT, MemNode::unordered);
   9.192        }
   9.193      }
   9.194  
    10.1 --- a/src/share/vm/opto/memnode.hpp	Thu Nov 07 11:47:11 2013 +0100
    10.2 +++ b/src/share/vm/opto/memnode.hpp	Fri Nov 15 11:05:32 2013 -0800
    10.3 @@ -51,6 +51,10 @@
    10.4           ValueIn,               // Value to store
    10.5           OopStore               // Preceeding oop store, only in StoreCM
    10.6    };
    10.7 +  typedef enum { unordered = 0,
    10.8 +                 acquire,       // Load has to acquire or be succeeded by MemBarAcquire.
    10.9 +                 release        // Store has to release or be preceded by MemBarRelease.
   10.10 +  } MemOrd;
   10.11  protected:
   10.12    MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at )
   10.13      : Node(c0,c1,c2   ) {
   10.14 @@ -134,20 +138,32 @@
   10.15  //------------------------------LoadNode---------------------------------------
   10.16  // Load value; requires Memory and Address
   10.17  class LoadNode : public MemNode {
   10.18 +private:
   10.19 +  // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
   10.20 +  // loads that can be reordered, and such requiring acquire semantics to
   10.21 +  // adhere to the Java specification.  The required behaviour is stored in
   10.22 +  // this field.
   10.23 +  const MemOrd _mo;
   10.24 +
   10.25  protected:
   10.26 -  virtual uint cmp( const Node &n ) const;
   10.27 +  virtual uint cmp(const Node &n) const;
   10.28    virtual uint size_of() const; // Size is bigger
   10.29    const Type* const _type;      // What kind of value is loaded?
   10.30  public:
   10.31  
   10.32 -  LoadNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt )
   10.33 -    : MemNode(c,mem,adr,at), _type(rt) {
   10.34 +  LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo)
   10.35 +    : MemNode(c,mem,adr,at), _type(rt), _mo(mo) {
   10.36      init_class_id(Class_Load);
   10.37    }
   10.38 +  inline bool is_unordered() const { return !is_acquire(); }
   10.39 +  inline bool is_acquire() const {
   10.40 +    assert(_mo == unordered || _mo == acquire, "unexpected");
   10.41 +    return _mo == acquire;
   10.42 +  }
   10.43  
   10.44    // Polymorphic factory method:
   10.45 -  static Node* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
   10.46 -                     const TypePtr* at, const Type *rt, BasicType bt );
   10.47 +   static Node* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
   10.48 +                     const TypePtr* at, const Type *rt, BasicType bt, MemOrd mo);
   10.49  
   10.50    virtual uint hash()   const;  // Check the type
   10.51  
   10.52 @@ -210,8 +226,8 @@
   10.53  // Load a byte (8bits signed) from memory
   10.54  class LoadBNode : public LoadNode {
   10.55  public:
   10.56 -  LoadBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE )
   10.57 -    : LoadNode(c,mem,adr,at,ti) {}
   10.58 +  LoadBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
   10.59 +    : LoadNode(c, mem, adr, at, ti, mo) {}
   10.60    virtual int Opcode() const;
   10.61    virtual uint ideal_reg() const { return Op_RegI; }
   10.62    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   10.63 @@ -224,8 +240,8 @@
   10.64  // Load a unsigned byte (8bits unsigned) from memory
   10.65  class LoadUBNode : public LoadNode {
   10.66  public:
   10.67 -  LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti = TypeInt::UBYTE )
   10.68 -    : LoadNode(c, mem, adr, at, ti) {}
   10.69 +  LoadUBNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt* ti, MemOrd mo)
   10.70 +    : LoadNode(c, mem, adr, at, ti, mo) {}
   10.71    virtual int Opcode() const;
   10.72    virtual uint ideal_reg() const { return Op_RegI; }
   10.73    virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);
   10.74 @@ -238,8 +254,8 @@
   10.75  // Load an unsigned short/char (16bits unsigned) from memory
   10.76  class LoadUSNode : public LoadNode {
   10.77  public:
   10.78 -  LoadUSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR )
   10.79 -    : LoadNode(c,mem,adr,at,ti) {}
   10.80 +  LoadUSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
   10.81 +    : LoadNode(c, mem, adr, at, ti, mo) {}
   10.82    virtual int Opcode() const;
   10.83    virtual uint ideal_reg() const { return Op_RegI; }
   10.84    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   10.85 @@ -252,8 +268,8 @@
   10.86  // Load a short (16bits signed) from memory
   10.87  class LoadSNode : public LoadNode {
   10.88  public:
   10.89 -  LoadSNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT )
   10.90 -    : LoadNode(c,mem,adr,at,ti) {}
   10.91 +  LoadSNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
   10.92 +    : LoadNode(c, mem, adr, at, ti, mo) {}
   10.93    virtual int Opcode() const;
   10.94    virtual uint ideal_reg() const { return Op_RegI; }
   10.95    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
   10.96 @@ -266,8 +282,8 @@
   10.97  // Load an integer from memory
   10.98  class LoadINode : public LoadNode {
   10.99  public:
  10.100 -  LoadINode( Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT )
  10.101 -    : LoadNode(c,mem,adr,at,ti) {}
  10.102 +  LoadINode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeInt *ti, MemOrd mo)
  10.103 +    : LoadNode(c, mem, adr, at, ti, mo) {}
  10.104    virtual int Opcode() const;
  10.105    virtual uint ideal_reg() const { return Op_RegI; }
  10.106    virtual int store_Opcode() const { return Op_StoreI; }
  10.107 @@ -278,8 +294,8 @@
  10.108  // Load an array length from the array
  10.109  class LoadRangeNode : public LoadINode {
  10.110  public:
  10.111 -  LoadRangeNode( Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS )
  10.112 -    : LoadINode(c,mem,adr,TypeAryPtr::RANGE,ti) {}
  10.113 +  LoadRangeNode(Node *c, Node *mem, Node *adr, const TypeInt *ti = TypeInt::POS)
  10.114 +    : LoadINode(c, mem, adr, TypeAryPtr::RANGE, ti, MemNode::unordered) {}
  10.115    virtual int Opcode() const;
  10.116    virtual const Type *Value( PhaseTransform *phase ) const;
  10.117    virtual Node *Identity( PhaseTransform *phase );
  10.118 @@ -298,18 +314,16 @@
  10.119    const bool _require_atomic_access;  // is piecewise load forbidden?
  10.120  
  10.121  public:
  10.122 -  LoadLNode( Node *c, Node *mem, Node *adr, const TypePtr* at,
  10.123 -             const TypeLong *tl = TypeLong::LONG,
  10.124 -             bool require_atomic_access = false )
  10.125 -    : LoadNode(c,mem,adr,at,tl)
  10.126 -    , _require_atomic_access(require_atomic_access)
  10.127 -  {}
  10.128 +  LoadLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const TypeLong *tl,
  10.129 +            MemOrd mo, bool require_atomic_access = false)
  10.130 +    : LoadNode(c, mem, adr, at, tl, mo), _require_atomic_access(require_atomic_access) {}
  10.131    virtual int Opcode() const;
  10.132    virtual uint ideal_reg() const { return Op_RegL; }
  10.133    virtual int store_Opcode() const { return Op_StoreL; }
  10.134    virtual BasicType memory_type() const { return T_LONG; }
  10.135    bool require_atomic_access() { return _require_atomic_access; }
  10.136 -  static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt);
  10.137 +  static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type,
  10.138 +                                const Type* rt, MemOrd mo);
  10.139  #ifndef PRODUCT
  10.140    virtual void dump_spec(outputStream *st) const {
  10.141      LoadNode::dump_spec(st);
  10.142 @@ -322,8 +336,8 @@
  10.143  // Load a long from unaligned memory
  10.144  class LoadL_unalignedNode : public LoadLNode {
  10.145  public:
  10.146 -  LoadL_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at )
  10.147 -    : LoadLNode(c,mem,adr,at) {}
  10.148 +  LoadL_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo)
  10.149 +    : LoadLNode(c, mem, adr, at, TypeLong::LONG, mo) {}
  10.150    virtual int Opcode() const;
  10.151  };
  10.152  
  10.153 @@ -331,8 +345,8 @@
  10.154  // Load a float (64 bits) from memory
  10.155  class LoadFNode : public LoadNode {
  10.156  public:
  10.157 -  LoadFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::FLOAT )
  10.158 -    : LoadNode(c,mem,adr,at,t) {}
  10.159 +  LoadFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
  10.160 +    : LoadNode(c, mem, adr, at, t, mo) {}
  10.161    virtual int Opcode() const;
  10.162    virtual uint ideal_reg() const { return Op_RegF; }
  10.163    virtual int store_Opcode() const { return Op_StoreF; }
  10.164 @@ -343,8 +357,8 @@
  10.165  // Load a double (64 bits) from memory
  10.166  class LoadDNode : public LoadNode {
  10.167  public:
  10.168 -  LoadDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t = Type::DOUBLE )
  10.169 -    : LoadNode(c,mem,adr,at,t) {}
  10.170 +  LoadDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *t, MemOrd mo)
  10.171 +    : LoadNode(c, mem, adr, at, t, mo) {}
  10.172    virtual int Opcode() const;
  10.173    virtual uint ideal_reg() const { return Op_RegD; }
  10.174    virtual int store_Opcode() const { return Op_StoreD; }
  10.175 @@ -355,8 +369,8 @@
  10.176  // Load a double from unaligned memory
  10.177  class LoadD_unalignedNode : public LoadDNode {
  10.178  public:
  10.179 -  LoadD_unalignedNode( Node *c, Node *mem, Node *adr, const TypePtr* at )
  10.180 -    : LoadDNode(c,mem,adr,at) {}
  10.181 +  LoadD_unalignedNode(Node *c, Node *mem, Node *adr, const TypePtr* at, MemOrd mo)
  10.182 +    : LoadDNode(c, mem, adr, at, Type::DOUBLE, mo) {}
  10.183    virtual int Opcode() const;
  10.184  };
  10.185  
  10.186 @@ -364,8 +378,8 @@
  10.187  // Load a pointer from memory (either object or array)
  10.188  class LoadPNode : public LoadNode {
  10.189  public:
  10.190 -  LoadPNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t )
  10.191 -    : LoadNode(c,mem,adr,at,t) {}
  10.192 +  LoadPNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypePtr* t, MemOrd mo)
  10.193 +    : LoadNode(c, mem, adr, at, t, mo) {}
  10.194    virtual int Opcode() const;
  10.195    virtual uint ideal_reg() const { return Op_RegP; }
  10.196    virtual int store_Opcode() const { return Op_StoreP; }
  10.197 @@ -387,8 +401,8 @@
  10.198  // Load a narrow oop from memory (either object or array)
  10.199  class LoadNNode : public LoadNode {
  10.200  public:
  10.201 -  LoadNNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t )
  10.202 -    : LoadNode(c,mem,adr,at,t) {}
  10.203 +  LoadNNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const Type* t, MemOrd mo)
  10.204 +    : LoadNode(c, mem, adr, at, t, mo) {}
  10.205    virtual int Opcode() const;
  10.206    virtual uint ideal_reg() const { return Op_RegN; }
  10.207    virtual int store_Opcode() const { return Op_StoreN; }
  10.208 @@ -409,8 +423,8 @@
  10.209  // Load a Klass from an object
  10.210  class LoadKlassNode : public LoadPNode {
  10.211  public:
  10.212 -  LoadKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk )
  10.213 -    : LoadPNode(c,mem,adr,at,tk) {}
  10.214 +  LoadKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeKlassPtr *tk, MemOrd mo)
  10.215 +    : LoadPNode(c, mem, adr, at, tk, mo) {}
  10.216    virtual int Opcode() const;
  10.217    virtual const Type *Value( PhaseTransform *phase ) const;
  10.218    virtual Node *Identity( PhaseTransform *phase );
  10.219 @@ -425,8 +439,8 @@
  10.220  // Load a narrow Klass from an object.
  10.221  class LoadNKlassNode : public LoadNNode {
  10.222  public:
  10.223 -  LoadNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk )
  10.224 -    : LoadNNode(c,mem,adr,at,tk) {}
  10.225 +  LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo)
  10.226 +    : LoadNNode(c, mem, adr, at, tk, mo) {}
  10.227    virtual int Opcode() const;
  10.228    virtual uint ideal_reg() const { return Op_RegN; }
  10.229    virtual int store_Opcode() const { return Op_StoreNKlass; }
  10.230 @@ -441,6 +455,14 @@
  10.231  //------------------------------StoreNode--------------------------------------
  10.232  // Store value; requires Store, Address and Value
  10.233  class StoreNode : public MemNode {
  10.234 +private:
  10.235 +  // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish
  10.236 +  // stores that can be reordered, and such requiring release semantics to
  10.237 +  // adhere to the Java specification.  The required behaviour is stored in
  10.238 +  // this field.
  10.239 +  const MemOrd _mo;
  10.240 +  // Needed for proper cloning.
  10.241 +  virtual uint size_of() const { return sizeof(*this); }
  10.242  protected:
  10.243    virtual uint cmp( const Node &n ) const;
  10.244    virtual bool depends_only_on_test() const { return false; }
  10.245 @@ -449,18 +471,44 @@
  10.246    Node *Ideal_sign_extended_input(PhaseGVN *phase, int  num_bits);
  10.247  
  10.248  public:
  10.249 -  StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val )
  10.250 -    : MemNode(c,mem,adr,at,val) {
  10.251 +  // We must ensure that stores of object references will be visible
  10.252 +  // only after the object's initialization. So the callers of this
  10.253 +  // procedure must indicate that the store requires `release'
  10.254 +  // semantics, if the stored value is an object reference that might
  10.255 +  // point to a new object and may become externally visible.
  10.256 +  StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.257 +    : MemNode(c, mem, adr, at, val), _mo(mo) {
  10.258      init_class_id(Class_Store);
  10.259    }
  10.260 -  StoreNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store )
  10.261 -    : MemNode(c,mem,adr,at,val,oop_store) {
  10.262 +  StoreNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, MemOrd mo)
  10.263 +    : MemNode(c, mem, adr, at, val, oop_store), _mo(mo) {
  10.264      init_class_id(Class_Store);
  10.265    }
  10.266  
  10.267 -  // Polymorphic factory method:
  10.268 -  static StoreNode* make( PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
  10.269 -                          const TypePtr* at, Node *val, BasicType bt );
  10.270 +  inline bool is_unordered() const { return !is_release(); }
  10.271 +  inline bool is_release() const {
  10.272 +    assert((_mo == unordered || _mo == release), "unexpected");
  10.273 +    return _mo == release;
  10.274 +  }
  10.275 +
  10.276 +  // Conservatively release stores of object references in order to
  10.277 +  // ensure visibility of object initialization.
  10.278 +  static inline MemOrd release_if_reference(const BasicType t) {
  10.279 +    const MemOrd mo = (t == T_ARRAY ||
  10.280 +                       t == T_ADDRESS || // Might be the address of an object reference (`boxing').
  10.281 +                       t == T_OBJECT) ? release : unordered;
  10.282 +    return mo;
  10.283 +  }
  10.284 +
  10.285 +  // Polymorphic factory method
  10.286 +  //
  10.287 +  // We must ensure that stores of object references will be visible
  10.288 +  // only after the object's initialization. So the callers of this
  10.289 +  // procedure must indicate that the store requires `release'
  10.290 +  // semantics, if the stored value is an object reference that might
  10.291 +  // point to a new object and may become externally visible.
  10.292 +  static StoreNode* make(PhaseGVN& gvn, Node *c, Node *mem, Node *adr,
  10.293 +                         const TypePtr* at, Node *val, BasicType bt, MemOrd mo);
  10.294  
  10.295    virtual uint hash() const;    // Check the type
  10.296  
  10.297 @@ -491,7 +539,8 @@
  10.298  // Store byte to memory
  10.299  class StoreBNode : public StoreNode {
  10.300  public:
  10.301 -  StoreBNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.302 +  StoreBNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.303 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.304    virtual int Opcode() const;
  10.305    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  10.306    virtual BasicType memory_type() const { return T_BYTE; }
  10.307 @@ -501,7 +550,8 @@
  10.308  // Store char/short to memory
  10.309  class StoreCNode : public StoreNode {
  10.310  public:
  10.311 -  StoreCNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.312 +  StoreCNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.313 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.314    virtual int Opcode() const;
  10.315    virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
  10.316    virtual BasicType memory_type() const { return T_CHAR; }
  10.317 @@ -511,7 +561,8 @@
  10.318  // Store int to memory
  10.319  class StoreINode : public StoreNode {
  10.320  public:
  10.321 -  StoreINode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.322 +  StoreINode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.323 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.324    virtual int Opcode() const;
  10.325    virtual BasicType memory_type() const { return T_INT; }
  10.326  };
  10.327 @@ -528,15 +579,12 @@
  10.328    const bool _require_atomic_access;  // is piecewise store forbidden?
  10.329  
  10.330  public:
  10.331 -  StoreLNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val,
  10.332 -              bool require_atomic_access = false )
  10.333 -    : StoreNode(c,mem,adr,at,val)
  10.334 -    , _require_atomic_access(require_atomic_access)
  10.335 -  {}
  10.336 +  StoreLNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo, bool require_atomic_access = false)
  10.337 +    : StoreNode(c, mem, adr, at, val, mo), _require_atomic_access(require_atomic_access) {}
  10.338    virtual int Opcode() const;
  10.339    virtual BasicType memory_type() const { return T_LONG; }
  10.340    bool require_atomic_access() { return _require_atomic_access; }
  10.341 -  static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val);
  10.342 +  static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val, MemOrd mo);
  10.343  #ifndef PRODUCT
  10.344    virtual void dump_spec(outputStream *st) const {
  10.345      StoreNode::dump_spec(st);
  10.346 @@ -549,7 +597,8 @@
  10.347  // Store float to memory
  10.348  class StoreFNode : public StoreNode {
  10.349  public:
  10.350 -  StoreFNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.351 +  StoreFNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.352 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.353    virtual int Opcode() const;
  10.354    virtual BasicType memory_type() const { return T_FLOAT; }
  10.355  };
  10.356 @@ -558,7 +607,8 @@
  10.357  // Store double to memory
  10.358  class StoreDNode : public StoreNode {
  10.359  public:
  10.360 -  StoreDNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.361 +  StoreDNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.362 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.363    virtual int Opcode() const;
  10.364    virtual BasicType memory_type() const { return T_DOUBLE; }
  10.365  };
  10.366 @@ -567,7 +617,8 @@
  10.367  // Store pointer to memory
  10.368  class StorePNode : public StoreNode {
  10.369  public:
  10.370 -  StorePNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.371 +  StorePNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.372 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.373    virtual int Opcode() const;
  10.374    virtual BasicType memory_type() const { return T_ADDRESS; }
  10.375  };
  10.376 @@ -576,7 +627,8 @@
  10.377  // Store narrow oop to memory
  10.378  class StoreNNode : public StoreNode {
  10.379  public:
  10.380 -  StoreNNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNode(c,mem,adr,at,val) {}
  10.381 +  StoreNNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.382 +    : StoreNode(c, mem, adr, at, val, mo) {}
  10.383    virtual int Opcode() const;
  10.384    virtual BasicType memory_type() const { return T_NARROWOOP; }
  10.385  };
  10.386 @@ -585,7 +637,8 @@
  10.387  // Store narrow klass to memory
  10.388  class StoreNKlassNode : public StoreNNode {
  10.389  public:
  10.390 -  StoreNKlassNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val ) : StoreNNode(c,mem,adr,at,val) {}
  10.391 +  StoreNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, MemOrd mo)
  10.392 +    : StoreNNode(c, mem, adr, at, val, mo) {}
  10.393    virtual int Opcode() const;
  10.394    virtual BasicType memory_type() const { return T_NARROWKLASS; }
  10.395  };
  10.396 @@ -606,7 +659,7 @@
  10.397  
  10.398  public:
  10.399    StoreCMNode( Node *c, Node *mem, Node *adr, const TypePtr* at, Node *val, Node *oop_store, int oop_alias_idx ) :
  10.400 -    StoreNode(c,mem,adr,at,val,oop_store),
  10.401 +    StoreNode(c, mem, adr, at, val, oop_store, MemNode::release),
  10.402      _oop_alias_idx(oop_alias_idx) {
  10.403      assert(_oop_alias_idx >= Compile::AliasIdxRaw ||
  10.404             _oop_alias_idx == Compile::AliasIdxBot && Compile::current()->AliasLevel() == 0,
  10.405 @@ -626,8 +679,8 @@
  10.406  // On PowerPC and friends it's a real load-locked.
  10.407  class LoadPLockedNode : public LoadPNode {
  10.408  public:
  10.409 -  LoadPLockedNode( Node *c, Node *mem, Node *adr )
  10.410 -    : LoadPNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM) {}
  10.411 +  LoadPLockedNode(Node *c, Node *mem, Node *adr, MemOrd mo)
  10.412 +    : LoadPNode(c, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM, mo) {}
  10.413    virtual int Opcode() const;
  10.414    virtual int store_Opcode() const { return Op_StorePConditional; }
  10.415    virtual bool depends_only_on_test() const { return true; }
    11.1 --- a/src/share/vm/opto/mulnode.cpp	Thu Nov 07 11:47:11 2013 +0100
    11.2 +++ b/src/share/vm/opto/mulnode.cpp	Fri Nov 15 11:05:32 2013 -0800
    11.3 @@ -485,7 +485,8 @@
    11.4        Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control),
    11.5                                               load->in(MemNode::Memory),
    11.6                                               load->in(MemNode::Address),
    11.7 -                                             load->adr_type());
    11.8 +                                             load->adr_type(),
    11.9 +                                             TypeInt::CHAR, MemNode::unordered);
   11.10        ldus = phase->transform(ldus);
   11.11        return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF));
   11.12      }
   11.13 @@ -496,7 +497,8 @@
   11.14        Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control),
   11.15                                               load->in(MemNode::Memory),
   11.16                                               load->in(MemNode::Address),
   11.17 -                                             load->adr_type());
   11.18 +                                             load->adr_type(),
   11.19 +                                             TypeInt::UBYTE, MemNode::unordered);
   11.20        ldub = phase->transform(ldub);
   11.21        return new (phase->C) AndINode(ldub, phase->intcon(mask));
   11.22      }
   11.23 @@ -931,9 +933,10 @@
   11.24               ld->outcnt() == 1 && ld->unique_out() == shl)
   11.25        // Replace zero-extension-load with sign-extension-load
   11.26        return new (phase->C) LoadSNode( ld->in(MemNode::Control),
   11.27 -                                ld->in(MemNode::Memory),
   11.28 -                                ld->in(MemNode::Address),
   11.29 -                                ld->adr_type());
   11.30 +                                       ld->in(MemNode::Memory),
   11.31 +                                       ld->in(MemNode::Address),
   11.32 +                                       ld->adr_type(), TypeInt::SHORT,
   11.33 +                                       MemNode::unordered);
   11.34    }
   11.35  
   11.36    // Check for "(byte[i] <<24)>>24" which simply sign-extends
    12.1 --- a/src/share/vm/opto/parse1.cpp	Thu Nov 07 11:47:11 2013 +0100
    12.2 +++ b/src/share/vm/opto/parse1.cpp	Fri Nov 15 11:05:32 2013 -0800
    12.3 @@ -106,24 +106,24 @@
    12.4    // Very similar to LoadNode::make, except we handle un-aligned longs and
    12.5    // doubles on Sparc.  Intel can handle them just fine directly.
    12.6    Node *l;
    12.7 -  switch( bt ) {                // Signature is flattened
    12.8 -  case T_INT:     l = new (C) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
    12.9 -  case T_FLOAT:   l = new (C) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
   12.10 -  case T_ADDRESS: l = new (C) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM  ); break;
   12.11 -  case T_OBJECT:  l = new (C) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
   12.12 +  switch (bt) {                // Signature is flattened
   12.13 +  case T_INT:     l = new (C) LoadINode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInt::INT,        MemNode::unordered); break;
   12.14 +  case T_FLOAT:   l = new (C) LoadFNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::FLOAT,         MemNode::unordered); break;
   12.15 +  case T_ADDRESS: l = new (C) LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM,  MemNode::unordered); break;
   12.16 +  case T_OBJECT:  l = new (C) LoadPNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM, MemNode::unordered); break;
   12.17    case T_LONG:
   12.18    case T_DOUBLE: {
   12.19      // Since arguments are in reverse order, the argument address 'adr'
   12.20      // refers to the back half of the long/double.  Recompute adr.
   12.21 -    adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize );
   12.22 -    if( Matcher::misaligned_doubles_ok ) {
   12.23 +    adr = basic_plus_adr(local_addrs_base, local_addrs, -(index+1)*wordSize);
   12.24 +    if (Matcher::misaligned_doubles_ok) {
   12.25        l = (bt == T_DOUBLE)
   12.26 -        ? (Node*)new (C) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
   12.27 -        : (Node*)new (C) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
   12.28 +        ? (Node*)new (C) LoadDNode(ctl, mem, adr, TypeRawPtr::BOTTOM, Type::DOUBLE, MemNode::unordered)
   12.29 +        : (Node*)new (C) LoadLNode(ctl, mem, adr, TypeRawPtr::BOTTOM, TypeLong::LONG, MemNode::unordered);
   12.30      } else {
   12.31        l = (bt == T_DOUBLE)
   12.32 -        ? (Node*)new (C) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
   12.33 -        : (Node*)new (C) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
   12.34 +        ? (Node*)new (C) LoadD_unalignedNode(ctl, mem, adr, TypeRawPtr::BOTTOM, MemNode::unordered)
   12.35 +        : (Node*)new (C) LoadL_unalignedNode(ctl, mem, adr, TypeRawPtr::BOTTOM, MemNode::unordered);
   12.36      }
   12.37      break;
   12.38    }
   12.39 @@ -229,7 +229,7 @@
   12.40      Node *displaced_hdr = fetch_interpreter_state((index*2) + 1, T_ADDRESS, monitors_addr, osr_buf);
   12.41  
   12.42  
   12.43 -    store_to_memory(control(), box, displaced_hdr, T_ADDRESS, Compile::AliasIdxRaw);
   12.44 +    store_to_memory(control(), box, displaced_hdr, T_ADDRESS, Compile::AliasIdxRaw, MemNode::unordered);
   12.45  
   12.46      // Build a bogus FastLockNode (no code will be generated) and push the
   12.47      // monitor into our debug info.
   12.48 @@ -1931,7 +1931,7 @@
   12.49    Node* klass = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), klass_addr, TypeInstPtr::KLASS) );
   12.50  
   12.51    Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset()));
   12.52 -  Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT);
   12.53 +  Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT, MemNode::unordered);
   12.54  
   12.55    Node* mask  = _gvn.transform(new (C) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER)));
   12.56    Node* check = _gvn.transform(new (C) CmpINode(mask, intcon(0)));
    13.1 --- a/src/share/vm/opto/parse2.cpp	Thu Nov 07 11:47:11 2013 +0100
    13.2 +++ b/src/share/vm/opto/parse2.cpp	Fri Nov 15 11:05:32 2013 -0800
    13.3 @@ -50,7 +50,7 @@
    13.4    if (stopped())  return;     // guaranteed null or range check
    13.5    dec_sp(2);                  // Pop array and index
    13.6    const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
    13.7 -  Node* ld = make_load(control(), adr, elem, elem_type, adr_type);
    13.8 +  Node* ld = make_load(control(), adr, elem, elem_type, adr_type, MemNode::unordered);
    13.9    push(ld);
   13.10  }
   13.11  
   13.12 @@ -62,7 +62,7 @@
   13.13    Node* val = pop();
   13.14    dec_sp(2);                  // Pop array and index
   13.15    const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
   13.16 -  store_to_memory(control(), adr, val, elem_type, adr_type);
   13.17 +  store_to_memory(control(), adr, val, elem_type, adr_type, StoreNode::release_if_reference(elem_type));
   13.18  }
   13.19  
   13.20  
   13.21 @@ -1720,14 +1720,14 @@
   13.22      a = array_addressing(T_LONG, 0);
   13.23      if (stopped())  return;     // guaranteed null or range check
   13.24      dec_sp(2);                  // Pop array and index
   13.25 -    push_pair(make_load(control(), a, TypeLong::LONG, T_LONG, TypeAryPtr::LONGS));
   13.26 +    push_pair(make_load(control(), a, TypeLong::LONG, T_LONG, TypeAryPtr::LONGS, MemNode::unordered));
   13.27      break;
   13.28    }
   13.29    case Bytecodes::_daload: {
   13.30      a = array_addressing(T_DOUBLE, 0);
   13.31      if (stopped())  return;     // guaranteed null or range check
   13.32      dec_sp(2);                  // Pop array and index
   13.33 -    push_pair(make_load(control(), a, Type::DOUBLE, T_DOUBLE, TypeAryPtr::DOUBLES));
   13.34 +    push_pair(make_load(control(), a, Type::DOUBLE, T_DOUBLE, TypeAryPtr::DOUBLES, MemNode::unordered));
   13.35      break;
   13.36    }
   13.37    case Bytecodes::_bastore: array_store(T_BYTE);  break;
   13.38 @@ -1744,7 +1744,7 @@
   13.39      a = pop();                  // the array itself
   13.40      const TypeOopPtr* elemtype  = _gvn.type(a)->is_aryptr()->elem()->make_oopptr();
   13.41      const TypeAryPtr* adr_type = TypeAryPtr::OOPS;
   13.42 -    Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT);
   13.43 +    Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT, MemNode::release);
   13.44      break;
   13.45    }
   13.46    case Bytecodes::_lastore: {
   13.47 @@ -1752,7 +1752,7 @@
   13.48      if (stopped())  return;     // guaranteed null or range check
   13.49      c = pop_pair();
   13.50      dec_sp(2);                  // Pop array and index
   13.51 -    store_to_memory(control(), a, c, T_LONG, TypeAryPtr::LONGS);
   13.52 +    store_to_memory(control(), a, c, T_LONG, TypeAryPtr::LONGS, MemNode::unordered);
   13.53      break;
   13.54    }
   13.55    case Bytecodes::_dastore: {
   13.56 @@ -1761,7 +1761,7 @@
   13.57      c = pop_pair();
   13.58      dec_sp(2);                  // Pop array and index
   13.59      c = dstore_rounding(c);
   13.60 -    store_to_memory(control(), a, c, T_DOUBLE, TypeAryPtr::DOUBLES);
   13.61 +    store_to_memory(control(), a, c, T_DOUBLE, TypeAryPtr::DOUBLES, MemNode::unordered);
   13.62      break;
   13.63    }
   13.64    case Bytecodes::_getfield:
    14.1 --- a/src/share/vm/opto/parse3.cpp	Thu Nov 07 11:47:11 2013 +0100
    14.2 +++ b/src/share/vm/opto/parse3.cpp	Fri Nov 15 11:05:32 2013 -0800
    14.3 @@ -228,7 +228,9 @@
    14.4      type = Type::get_const_basic_type(bt);
    14.5    }
    14.6    // Build the load.
    14.7 -  Node* ld = make_load(NULL, adr, type, bt, adr_type, is_vol);
    14.8 +  //
    14.9 +  MemNode::MemOrd mo = is_vol ? MemNode::acquire : MemNode::unordered;
   14.10 +  Node* ld = make_load(NULL, adr, type, bt, adr_type, mo, is_vol);
   14.11  
   14.12    // Adjust Java stack
   14.13    if (type2size[bt] == 1)
   14.14 @@ -288,6 +290,16 @@
   14.15    // Round doubles before storing
   14.16    if (bt == T_DOUBLE)  val = dstore_rounding(val);
   14.17  
   14.18 +  // Conservatively release stores of object references.
   14.19 +  const MemNode::MemOrd mo =
   14.20 +    is_vol ?
   14.21 +    // Volatile fields need releasing stores.
   14.22 +    MemNode::release :
   14.23 +    // Non-volatile fields also need releasing stores if they hold an
   14.24 +    // object reference, because the object reference might point to
   14.25 +    // a freshly created object.
   14.26 +    StoreNode::release_if_reference(bt);
   14.27 +
   14.28    // Store the value.
   14.29    Node* store;
   14.30    if (bt == T_OBJECT) {
   14.31 @@ -297,9 +309,9 @@
   14.32      } else {
   14.33        field_type = TypeOopPtr::make_from_klass(field->type()->as_klass());
   14.34      }
   14.35 -    store = store_oop_to_object( control(), obj, adr, adr_type, val, field_type, bt);
   14.36 +    store = store_oop_to_object(control(), obj, adr, adr_type, val, field_type, bt, mo);
   14.37    } else {
   14.38 -    store = store_to_memory( control(), adr, val, bt, adr_type, is_vol );
   14.39 +    store = store_to_memory(control(), adr, val, bt, adr_type, mo, is_vol);
   14.40    }
   14.41  
   14.42    // If reference is volatile, prevent following volatiles ops from
   14.43 @@ -414,7 +426,7 @@
   14.44        Node*    elem   = expand_multianewarray(array_klass_1, &lengths[1], ndimensions-1, nargs);
   14.45        intptr_t offset = header + ((intptr_t)i << LogBytesPerHeapOop);
   14.46        Node*    eaddr  = basic_plus_adr(array, offset);
   14.47 -      store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT);
   14.48 +      store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT, MemNode::unordered);
   14.49      }
   14.50    }
   14.51    return array;
   14.52 @@ -503,7 +515,7 @@
   14.53        // Fill-in it with values
   14.54        for (j = 0; j < ndimensions; j++) {
   14.55          Node *dims_elem = array_element_address(dims, intcon(j), T_INT);
   14.56 -        store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS);
   14.57 +        store_to_memory(control(), dims_elem, length[j], T_INT, TypeAryPtr::INTS, MemNode::unordered);
   14.58        }
   14.59      }
   14.60  
    15.1 --- a/src/share/vm/opto/parseHelper.cpp	Thu Nov 07 11:47:11 2013 +0100
    15.2 +++ b/src/share/vm/opto/parseHelper.cpp	Fri Nov 15 11:05:32 2013 -0800
    15.3 @@ -222,7 +222,7 @@
    15.4  
    15.5    Node* init_thread_offset = _gvn.MakeConX(in_bytes(InstanceKlass::init_thread_offset()));
    15.6    Node* adr_node = basic_plus_adr(kls, kls, init_thread_offset);
    15.7 -  Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS);
    15.8 +  Node* init_thread = make_load(NULL, adr_node, TypeRawPtr::BOTTOM, T_ADDRESS, MemNode::unordered);
    15.9    Node *tst   = Bool( CmpP( init_thread, cur_thread), BoolTest::eq);
   15.10    IfNode* iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
   15.11    set_control(IfTrue(iff));
   15.12 @@ -232,7 +232,7 @@
   15.13    adr_node = basic_plus_adr(kls, kls, init_state_offset);
   15.14    // Use T_BOOLEAN for InstanceKlass::_init_state so the compiler
   15.15    // can generate code to load it as unsigned byte.
   15.16 -  Node* init_state = make_load(NULL, adr_node, TypeInt::UBYTE, T_BOOLEAN);
   15.17 +  Node* init_state = make_load(NULL, adr_node, TypeInt::UBYTE, T_BOOLEAN, MemNode::unordered);
   15.18    Node* being_init = _gvn.intcon(InstanceKlass::being_initialized);
   15.19    tst   = Bool( CmpI( init_state, being_init), BoolTest::eq);
   15.20    iff = create_and_map_if(control(), tst, PROB_ALWAYS, COUNT_UNKNOWN);
   15.21 @@ -354,13 +354,13 @@
   15.22    Node *counters_node = makecon(adr_type);
   15.23    Node* adr_iic_node = basic_plus_adr(counters_node, counters_node,
   15.24      MethodCounters::interpreter_invocation_counter_offset_in_bytes());
   15.25 -  Node* cnt = make_load(ctrl, adr_iic_node, TypeInt::INT, T_INT, adr_type);
   15.26 +  Node* cnt = make_load(ctrl, adr_iic_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
   15.27  
   15.28    test_counter_against_threshold(cnt, limit);
   15.29  
   15.30    // Add one to the counter and store
   15.31    Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
   15.32 -  store_to_memory( ctrl, adr_iic_node, incr, T_INT, adr_type );
   15.33 +  store_to_memory(ctrl, adr_iic_node, incr, T_INT, adr_type, MemNode::unordered);
   15.34  }
   15.35  
   15.36  //----------------------------method_data_addressing---------------------------
   15.37 @@ -392,9 +392,9 @@
   15.38    Node* adr_node = method_data_addressing(md, data, counter_offset, idx, stride);
   15.39  
   15.40    const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr();
   15.41 -  Node* cnt  = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type);
   15.42 +  Node* cnt  = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
   15.43    Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment)));
   15.44 -  store_to_memory(NULL, adr_node, incr, T_INT, adr_type );
   15.45 +  store_to_memory(NULL, adr_node, incr, T_INT, adr_type, MemNode::unordered);
   15.46  }
   15.47  
   15.48  //--------------------------test_for_osr_md_counter_at-------------------------
   15.49 @@ -402,7 +402,7 @@
   15.50    Node* adr_node = method_data_addressing(md, data, counter_offset);
   15.51  
   15.52    const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr();
   15.53 -  Node* cnt  = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type);
   15.54 +  Node* cnt  = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
   15.55  
   15.56    test_counter_against_threshold(cnt, limit);
   15.57  }
   15.58 @@ -412,9 +412,9 @@
   15.59    Node* adr_node = method_data_addressing(md, data, DataLayout::flags_offset());
   15.60  
   15.61    const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr();
   15.62 -  Node* flags = make_load(NULL, adr_node, TypeInt::BYTE, T_BYTE, adr_type);
   15.63 +  Node* flags = make_load(NULL, adr_node, TypeInt::BYTE, T_BYTE, adr_type, MemNode::unordered);
   15.64    Node* incr = _gvn.transform(new (C) OrINode(flags, _gvn.intcon(flag_constant)));
   15.65 -  store_to_memory(NULL, adr_node, incr, T_BYTE, adr_type);
   15.66 +  store_to_memory(NULL, adr_node, incr, T_BYTE, adr_type, MemNode::unordered);
   15.67  }
   15.68  
   15.69  //----------------------------profile_taken_branch-----------------------------
    16.1 --- a/src/share/vm/opto/stringopts.cpp	Thu Nov 07 11:47:11 2013 +0100
    16.2 +++ b/src/share/vm/opto/stringopts.cpp	Fri Nov 15 11:05:32 2013 -0800
    16.3 @@ -1122,7 +1122,8 @@
    16.4  
    16.5    return kit.make_load(NULL, kit.basic_plus_adr(klass_node, field->offset_in_bytes()),
    16.6                         type, T_OBJECT,
    16.7 -                       C->get_alias_index(mirror_type->add_offset(field->offset_in_bytes())));
    16.8 +                       C->get_alias_index(mirror_type->add_offset(field->offset_in_bytes())),
    16.9 +                       MemNode::unordered);
   16.10  }
   16.11  
   16.12  Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
   16.13 @@ -1314,7 +1315,7 @@
   16.14      Node* ch = __ AddI(r, __ intcon('0'));
   16.15  
   16.16      Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
   16.17 -                                  ch, T_CHAR, char_adr_idx);
   16.18 +                                  ch, T_CHAR, char_adr_idx, MemNode::unordered);
   16.19  
   16.20  
   16.21      IfNode* iff = kit.create_and_map_if(head, __ Bool(__ CmpI(q, __ intcon(0)), BoolTest::ne),
   16.22 @@ -1356,7 +1357,7 @@
   16.23      } else {
   16.24        Node* m1 = __ SubI(charPos, __ intcon(1));
   16.25        Node* st = __ store_to_memory(kit.control(), kit.array_element_address(char_array, m1, T_CHAR),
   16.26 -                                    sign, T_CHAR, char_adr_idx);
   16.27 +                                    sign, T_CHAR, char_adr_idx, MemNode::unordered);
   16.28  
   16.29        final_merge->init_req(1, kit.control());
   16.30        final_mem->init_req(1, st);
   16.31 @@ -1387,7 +1388,8 @@
   16.32      ciTypeArray* value_array = t->const_oop()->as_type_array();
   16.33      for (int e = 0; e < c; e++) {
   16.34        __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
   16.35 -                         __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx);
   16.36 +                         __ intcon(value_array->char_at(o + e)), T_CHAR, char_adr_idx,
   16.37 +                         MemNode::unordered);
   16.38        start = __ AddI(start, __ intcon(1));
   16.39      }
   16.40    } else {
   16.41 @@ -1607,7 +1609,7 @@
   16.42          }
   16.43          case StringConcat::CharMode: {
   16.44            __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
   16.45 -                             arg, T_CHAR, char_adr_idx);
   16.46 +                             arg, T_CHAR, char_adr_idx, MemNode::unordered);
   16.47            start = __ AddI(start, __ intcon(1));
   16.48            break;
   16.49          }
    17.1 --- a/src/share/vm/opto/vectornode.hpp	Thu Nov 07 11:47:11 2013 +0100
    17.2 +++ b/src/share/vm/opto/vectornode.hpp	Fri Nov 15 11:05:32 2013 -0800
    17.3 @@ -356,7 +356,7 @@
    17.4  class LoadVectorNode : public LoadNode {
    17.5   public:
    17.6    LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
    17.7 -    : LoadNode(c, mem, adr, at, vt) {
    17.8 +    : LoadNode(c, mem, adr, at, vt, MemNode::unordered) {
    17.9      init_class_id(Class_LoadVector);
   17.10    }
   17.11  
   17.12 @@ -380,7 +380,7 @@
   17.13  class StoreVectorNode : public StoreNode {
   17.14   public:
   17.15    StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
   17.16 -    : StoreNode(c, mem, adr, at, val) {
   17.17 +    : StoreNode(c, mem, adr, at, val, MemNode::unordered) {
   17.18      assert(val->is_Vector() || val->is_LoadVector(), "sanity");
   17.19      init_class_id(Class_StoreVector);
   17.20    }

mercurial