< prev index next >

src/share/vm/opto/parse2.cpp

Print this page

        

@@ -48,33 +48,33 @@
            explicit_null_checks_elided;
 
 //---------------------------------array_load----------------------------------
 void Parse::array_load(BasicType elem_type) {
   const Type* elem = Type::TOP;
-  Node* adr = array_addressing(elem_type, 0, &elem);
+  Node* adr = array_addressing(elem_type, 0, false, &elem);
   if (stopped())  return;     // guaranteed null or range check
   dec_sp(2);                  // Pop array and index
   const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
   Node* ld = make_load(control(), adr, elem, elem_type, adr_type, MemNode::unordered);
   push(ld);
 }
 
 
 //--------------------------------array_store----------------------------------
 void Parse::array_store(BasicType elem_type) {
-  Node* adr = array_addressing(elem_type, 1);
+  Node* adr = array_addressing(elem_type, 1, true);
   if (stopped())  return;     // guaranteed null or range check
   Node* val = pop();
   dec_sp(2);                  // Pop array and index
   const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
   store_to_memory(control(), adr, val, elem_type, adr_type, StoreNode::release_if_reference(elem_type));
 }
 
 
 //------------------------------array_addressing-------------------------------
 // Pull array and index from the stack.  Compute pointer-to-element.
-Node* Parse::array_addressing(BasicType type, int vals, const Type* *result2) {
+Node* Parse::array_addressing(BasicType type, int vals, bool is_store, const Type* *result2) {
   Node *idx   = peek(0+vals);   // Get from stack without popping
   Node *ary   = peek(1+vals);   // in case of exception
 
   // Null check the array base, with correct stack contents
   ary = null_check(ary, T_ARRAY);

@@ -156,10 +156,16 @@
     }
   }
   // Check for always knowing you are throwing a range-check exception
   if (stopped())  return top();
 
+  if (is_store) {
+    ary = shenandoah_write_barrier(ary);
+  } else {
+    ary = shenandoah_read_barrier(ary);
+  }
+
   Node* ptr = array_element_address(ary, idx, type, sizetype);
 
   if (result2 != NULL)  *result2 = elemtype;
 
   assert(ptr != top(), "top should go hand-in-hand with stopped");

@@ -1694,18 +1700,18 @@
   case Bytecodes::_iaload: array_load(T_INT);    break;
   case Bytecodes::_saload: array_load(T_SHORT);  break;
   case Bytecodes::_faload: array_load(T_FLOAT);  break;
   case Bytecodes::_aaload: array_load(T_OBJECT); break;
   case Bytecodes::_laload: {
-    a = array_addressing(T_LONG, 0);
+    a = array_addressing(T_LONG, 0, false);
     if (stopped())  return;     // guaranteed null or range check
     dec_sp(2);                  // Pop array and index
     push_pair(make_load(control(), a, TypeLong::LONG, T_LONG, TypeAryPtr::LONGS, MemNode::unordered));
     break;
   }
   case Bytecodes::_daload: {
-    a = array_addressing(T_DOUBLE, 0);
+    a = array_addressing(T_DOUBLE, 0, false);
     if (stopped())  return;     // guaranteed null or range check
     dec_sp(2);                  // Pop array and index
     push_pair(make_load(control(), a, Type::DOUBLE, T_DOUBLE, TypeAryPtr::DOUBLES, MemNode::unordered));
     break;
   }

@@ -1713,32 +1719,37 @@
   case Bytecodes::_castore: array_store(T_CHAR);  break;
   case Bytecodes::_iastore: array_store(T_INT);   break;
   case Bytecodes::_sastore: array_store(T_SHORT); break;
   case Bytecodes::_fastore: array_store(T_FLOAT); break;
   case Bytecodes::_aastore: {
-    d = array_addressing(T_OBJECT, 1);
+    d = array_addressing(T_OBJECT, 1, true);
     if (stopped())  return;     // guaranteed null or range check
     array_store_check();
     c = pop();                  // Oop to store
     b = pop();                  // index (already used)
     a = pop();                  // the array itself
     const TypeOopPtr* elemtype  = _gvn.type(a)->is_aryptr()->elem()->make_oopptr();
     const TypeAryPtr* adr_type = TypeAryPtr::OOPS;
+    // Note: We don't need a write barrier for Shenandoah on a here, because
+    // a is not used except for an assert. The address d already has the
+    // write barrier. Adding a barrier on a only results in additional code
+    // being generated.
+    c = shenandoah_read_barrier_nomem(c);
     Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT,
                                      StoreNode::release_if_reference(T_OBJECT));
     break;
   }
   case Bytecodes::_lastore: {
-    a = array_addressing(T_LONG, 2);
+    a = array_addressing(T_LONG, 2, true);
     if (stopped())  return;     // guaranteed null or range check
     c = pop_pair();
     dec_sp(2);                  // Pop array and index
     store_to_memory(control(), a, c, T_LONG, TypeAryPtr::LONGS, MemNode::unordered);
     break;
   }
   case Bytecodes::_dastore: {
-    a = array_addressing(T_DOUBLE, 2);
+    a = array_addressing(T_DOUBLE, 2, true);
     if (stopped())  return;     // guaranteed null or range check
     c = pop_pair();
     dec_sp(2);                  // Pop array and index
     c = dstore_rounding(c);
     store_to_memory(control(), a, c, T_DOUBLE, TypeAryPtr::DOUBLES, MemNode::unordered);

@@ -2274,10 +2285,11 @@
   handle_if_acmp:
     // If this is a backwards branch in the bytecodes, add Safepoint
     maybe_add_safepoint(iter().get_dest());
     a = pop();
     b = pop();
+    shenandoah_acmp_barrier(a, b);
     c = _gvn.transform( new CmpPNode(b, a) );
     c = optimize_cmp_with_klass(c);
     do_if(btest, c);
     break;
 
< prev index next >