< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page

        

@@ -63,31 +63,33 @@
 
   // Handle value type arrays
   const TypeOopPtr* elemptr = elemtype->make_oopptr();
   const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
   if (elemtype->isa_valuetype() != NULL) {
+    C->set_flattened_accesses();
     // Load from flattened value type array
     Node* vt = ValueTypeNode::make_from_flattened(this, elemtype->value_klass(), ary, adr);
     push(vt);
     return;
   } else if (elemptr != NULL && elemptr->is_valuetypeptr() && !elemptr->maybe_null()) {
     // Load from non-flattened but flattenable value type array (elements can never be null)
     bt = T_VALUETYPE;
   } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() &&
              !ary_t->klass_is_exact() && (!elemptr->is_valuetypeptr() || elemptr->value_klass()->flatten_array())) {
     // Cannot statically determine if array is flattened, emit runtime check
+    Node* ctl = control();
     IdealKit ideal(this);
     IdealVariable res(ideal);
     ideal.declarations_done();
     Node* kls = load_object_klass(ary);
     Node* tag = load_lh_array_tag(kls);
     ideal.if_then(tag, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
       // non-flattened
       sync_kit(ideal);
       const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
       Node* ld = access_load_at(ary, adr, adr_type, elemptr, bt,
-                                IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD);
+                                IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD, ctl);
       ideal.sync_kit(this);
       ideal.set(res, ld);
     } ideal.else_(); {
       // flattened
       sync_kit(ideal);

@@ -100,10 +102,11 @@
         const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr();
         Node* cast = _gvn.transform(new CheckCastPPNode(control(), ary, arytype));
         adr = array_element_address(cast, idx, T_VALUETYPE, ary_t->size(), control());
         Node* vt = ValueTypeNode::make_from_flattened(this, vk, cast, adr)->allocate(this, false, false)->get_oop();
         ideal.set(res, vt);
+        ideal.sync_kit(this);
       } else {
         // Element type is unknown, emit runtime call
         assert(!ary_t->klass_is_exact(), "should not have exact type here");
         Node* k_adr = basic_plus_adr(kls, in_bytes(ArrayKlass::element_klass_offset()));
         Node* elem_klass = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), k_adr, TypeInstPtr::KLASS));

@@ -114,10 +117,16 @@
         dec_sp(2);
 
         AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn);
         assert(alloc->maybe_set_complete(&_gvn), "");
         alloc->initialization()->set_complete_with_arraycopy();
+
+        // This membar keeps this access to an unknown flattened array
+        // correctly ordered with other unknown and known flattened
+        // array accesses.
+        insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES));
+        
         BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
         // Unknown value type might contain reference fields
         if (!bs->array_copy_requires_gc_barriers(false, T_OBJECT, false, BarrierSetC2::Parsing)) {
           int base_off = sizeof(instanceOopDesc);
           Node* dst_base = basic_plus_adr(alloc_obj, base_off);

@@ -142,15 +151,28 @@
                                "load_unknown_value",
                                ary, idx, alloc_obj);
           sync_kit(ideal);
         }
 
-        insert_mem_bar(Op_MemBarStoreStore, alloc->proj_out_or_null(AllocateNode::RawAddress));
+        // This makes sure no other thread sees a partially initialized buffered value
+        insert_mem_bar_volatile(Op_MemBarStoreStore, Compile::AliasIdxRaw, alloc->proj_out_or_null(AllocateNode::RawAddress));
+        
+        // Same as MemBarCPUOrder above: keep this unknown flattened
+        // array access correctly ordered with other flattened array
+        // access
+        insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES));
+
+        // Prevent any use of the newly allocated value before it is
+        // fully initialized
+        alloc_obj = new CastPPNode(alloc_obj, _gvn.type(alloc_obj), true);
+        alloc_obj->set_req(0, control());
+        alloc_obj = _gvn.transform(alloc_obj);
+
+        ideal.sync_kit(this);
 
         ideal.set(res, alloc_obj);
       }
-      ideal.sync_kit(this);
     } ideal.end_if();
     sync_kit(ideal);
     push_node(bt, _gvn.transform(ideal.value(res)));
     return;
   }

@@ -193,10 +215,11 @@
   const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
   if (bt == T_OBJECT) {
     const TypeOopPtr* elemptr = elemtype->make_oopptr();
     const Type* val_t = _gvn.type(val);
     if (elemtype->isa_valuetype() != NULL) {
+      C->set_flattened_accesses();
       // Store to flattened value type array
       if (!cast_val->is_ValueType()) {
         inc_sp(3);
         cast_val = null_check(cast_val);
         if (stopped()) return;

@@ -267,14 +290,30 @@
             val->as_ValueType()->store_flattened(this, ary, adr);
             ideal.sync_kit(this);
           } else if (!ideal.ctrl()->is_top()) {
             // Element type is unknown, emit runtime call
             assert(!ary_t->klass_is_exact(), "should not have exact type here");
+            sync_kit(ideal);
+
+            // This membar keeps this access to an unknown flattened
+            // array correctly ordered with other unknown and known
+            // flattened array accesses.
+            insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES));
+            ideal.sync_kit(this);
+
             ideal.make_leaf_call(OptoRuntime::store_unknown_value_Type(),
                                  CAST_FROM_FN_PTR(address, OptoRuntime::store_unknown_value),
                                  "store_unknown_value",
                                  val, ary, idx);
+
+            sync_kit(ideal);
+            // Same as MemBarCPUOrder above: keep this unknown
+            // flattened array access correctly ordered with other
+            // flattened array access
+            insert_mem_bar_volatile(Op_MemBarCPUOrder, C->get_alias_index(TypeAryPtr::VALUES));
+            ideal.sync_kit(this);
+            
           }
         } ideal.end_if();
         sync_kit(ideal);
         return;
       } else {
< prev index next >