< 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 >