< prev index next >
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
Print this page
@@ -298,19 +298,30 @@
CodeEmitInfo* null_check_info = NULL;
if (x->needs_null_check()) {
null_check_info = new CodeEmitInfo(range_check_info);
}
+ LIR_Opr ary = array.result();
+ ary = shenandoah_write_barrier(ary, null_check_info, x->needs_null_check());
+ LIR_Opr val = value.result();
+ if (obj_store && UseShenandoahGC) {
+ if (! val->is_register()) {
+ assert(val->is_constant(), "expect constant");
+ } else {
+ val = shenandoah_read_barrier(val, NULL, true);
+ }
+ }
+
// emit array address setup early so it schedules better
- LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), obj_store);
+ LIR_Address* array_addr = emit_array_address(ary, index.result(), x->elt_type(), obj_store);
if (GenerateRangeChecks && needs_range_check) {
if (use_length) {
__ cmp(lir_cond_belowEqual, length.result(), index.result());
__ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
} else {
- array_range_check(array.result(), index.result(), null_check_info, range_check_info);
+ array_range_check(ary, index.result(), null_check_info, range_check_info);
// range_check also does the null check
null_check_info = NULL;
}
}
@@ -318,22 +329,22 @@
LIR_Opr tmp1 = new_register(objectType);
LIR_Opr tmp2 = new_register(objectType);
LIR_Opr tmp3 = new_register(objectType);
CodeEmitInfo* store_check_info = new CodeEmitInfo(range_check_info);
- __ store_check(value.result(), array.result(), tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());
+ __ store_check(val, ary, tmp1, tmp2, tmp3, store_check_info, x->profiled_method(), x->profiled_bci());
}
if (obj_store) {
// Needs GC write barriers.
pre_barrier(LIR_OprFact::address(array_addr), LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
- __ move(value.result(), array_addr, null_check_info);
+ __ move(val, array_addr, null_check_info);
// Seems to be a precise
post_barrier(LIR_OprFact::address(array_addr), value.result());
} else {
- __ move(value.result(), array_addr, null_check_info);
+ __ move(val, array_addr, null_check_info);
}
}
void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
@@ -356,11 +367,13 @@
info_for_exception = state_for(x);
}
// this CodeEmitInfo must not have the xhandlers because here the
// object is already locked (xhandlers expect object to be unlocked)
CodeEmitInfo* info = state_for(x, x->state(), true);
- monitor_enter(obj.result(), lock, syncTempOpr(), scratch,
+ LIR_Opr obj_opr = obj.result();
+ obj_opr = shenandoah_write_barrier(obj_opr, state_for(x), x->needs_null_check());
+ monitor_enter(obj_opr, lock, syncTempOpr(), scratch,
x->monitor_no(), info_for_exception, info);
}
void LIRGenerator::do_MonitorExit(MonitorExit* x) {
@@ -748,31 +761,35 @@
ShouldNotReachHere();
}
LIR_Opr addr = new_pointer_register();
LIR_Address* a;
+
+ LIR_Opr obj_op = obj.result();
+ obj_op = shenandoah_write_barrier(obj_op, NULL, false);
+
if(offset.result()->is_constant()) {
#ifdef _LP64
jlong c = offset.result()->as_jlong();
if ((jlong)((jint)c) == c) {
- a = new LIR_Address(obj.result(),
+ a = new LIR_Address(obj_op,
(jint)c,
as_BasicType(type));
} else {
LIR_Opr tmp = new_register(T_LONG);
__ move(offset.result(), tmp);
- a = new LIR_Address(obj.result(),
+ a = new LIR_Address(obj_op,
tmp,
as_BasicType(type));
}
#else
- a = new LIR_Address(obj.result(),
+ a = new LIR_Address(obj_op,
offset.result()->as_jint(),
as_BasicType(type));
#endif
} else {
- a = new LIR_Address(obj.result(),
+ a = new LIR_Address(obj_op,
offset.result(),
LIR_Address::times_1,
0,
as_BasicType(type));
}
@@ -783,27 +800,32 @@
pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
}
LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience
- if (type == objectType)
- __ cas_obj(addr, cmp.result(), val.result(), ill, ill);
+
+ LIR_Opr val_op = val.result();
+
+ if (type == objectType) {
+ val_op = shenandoah_read_barrier(val_op, NULL, true);
+ __ cas_obj(addr, cmp.result(), val_op, new_register(T_OBJECT), new_register(T_OBJECT));
+ }
else if (type == intType)
- __ cas_int(addr, cmp.result(), val.result(), ill, ill);
+ __ cas_int(addr, cmp.result(), val_op, ill, ill);
else if (type == longType)
- __ cas_long(addr, cmp.result(), val.result(), ill, ill);
+ __ cas_long(addr, cmp.result(), val_op, ill, ill);
else {
ShouldNotReachHere();
}
// generate conditional move of boolean result
LIR_Opr result = rlock_result(x);
__ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
result, as_BasicType(type));
if (type == objectType) { // Write-barrier needed for Object fields.
// Seems to be precise
- post_barrier(addr, val.result());
+ post_barrier(addr, val_op);
}
}
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
@@ -891,18 +913,23 @@
LIRItem src_pos(x->argument_at(1), this);
LIRItem dst(x->argument_at(2), this);
LIRItem dst_pos(x->argument_at(3), this);
LIRItem length(x->argument_at(4), this);
+ LIR_Opr dst_op = dst.result();
+ dst_op = shenandoah_write_barrier(dst_op, info, x->arg_needs_null_check(2));
+ LIR_Opr src_op = src.result();
+ src_op = shenandoah_read_barrier(src_op, info, x->arg_needs_null_check(0));
+
// operands for arraycopy must use fixed registers, otherwise
// LinearScan will fail allocation (because arraycopy always needs a
// call)
#ifndef _LP64
- src.load_item_force (FrameMap::rcx_oop_opr);
+ src_op = force_opr_to(src_op, FrameMap::rcx_oop_opr);
src_pos.load_item_force (FrameMap::rdx_opr);
- dst.load_item_force (FrameMap::rax_oop_opr);
+ dst_op = force_opr_to(dst_op, FrameMap::rax_oop_opr);
dst_pos.load_item_force (FrameMap::rbx_opr);
length.load_item_force (FrameMap::rdi_opr);
LIR_Opr tmp = (FrameMap::rsi_opr);
#else
@@ -912,13 +939,13 @@
// positions are not similar enough to pick one as the best.
// Also because the java calling convention is a "shifted" version
// of the C convention we can process the java args trivially into C
// args without worry of overwriting during the xfer
- src.load_item_force (FrameMap::as_oop_opr(j_rarg0));
+ src_op = force_opr_to(src_op, FrameMap::as_oop_opr(j_rarg0));
src_pos.load_item_force (FrameMap::as_opr(j_rarg1));
- dst.load_item_force (FrameMap::as_oop_opr(j_rarg2));
+ dst_op = force_opr_to(dst_op, FrameMap::as_oop_opr(j_rarg2));
dst_pos.load_item_force (FrameMap::as_opr(j_rarg3));
length.load_item_force (FrameMap::as_opr(j_rarg4));
LIR_Opr tmp = FrameMap::as_opr(j_rarg5);
#endif // LP64
@@ -927,11 +954,11 @@
int flags;
ciArrayKlass* expected_type;
arraycopy_helper(x, &flags, &expected_type);
- __ arraycopy(src.result(), src_pos.result(), dst.result(), dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
+ __ arraycopy(src_op, src_pos.result(), dst_op, dst_pos.result(), length.result(), tmp, expected_type, flags, info); // does add_safepoint
}
void LIRGenerator::do_update_CRC32(Intrinsic* x) {
assert(UseCRC32Intrinsics, "need AVX and LCMUL instructions support");
// Make all state_for calls early since they can emit code
@@ -978,10 +1005,14 @@
__ convert(Bytecodes::_i2l, index, tmp);
index = tmp;
}
#endif
+ if (is_updateBytes) {
+ base_op = shenandoah_read_barrier(base_op, NULL, false);
+ }
+
LIR_Address* a = new LIR_Address(base_op,
index,
LIR_Address::times_1,
offset,
T_BYTE);
@@ -1310,10 +1341,14 @@
}
set_no_result(x);
LIR_Opr left = xin->result();
LIR_Opr right = yin->result();
+ if (tag == objectTag && UseShenandoahGC && x->y()->type() != objectNull) { // Don't need to resolve for ifnull.
+ left = shenandoah_write_barrier(left, NULL, true);
+ right = shenandoah_read_barrier(right, NULL, true);
+ }
__ cmp(lir_cond(cond), left, right);
// Generate branch profiling. Profiling code doesn't kill flags.
profile_branch(x, cond);
move_to_phi(x->state());
if (x->x()->type()->is_float_kind()) {
@@ -1389,10 +1424,11 @@
}
}
void LIRGenerator::get_Object_unsafe(LIR_Opr dst, LIR_Opr src, LIR_Opr offset,
BasicType type, bool is_volatile) {
+ src = shenandoah_read_barrier(src, NULL, false);
if (is_volatile && type == T_LONG) {
LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
LIR_Opr tmp = new_register(T_DOUBLE);
__ load(addr, tmp);
LIR_Opr spill = new_register(T_LONG);
@@ -1406,10 +1442,11 @@
}
void LIRGenerator::put_Object_unsafe(LIR_Opr src, LIR_Opr offset, LIR_Opr data,
BasicType type, bool is_volatile) {
+ src = shenandoah_write_barrier(src, NULL, false);
if (is_volatile && type == T_LONG) {
LIR_Address* addr = new LIR_Address(src, offset, T_DOUBLE);
LIR_Opr tmp = new_register(T_DOUBLE);
LIR_Opr spill = new_register(T_DOUBLE);
set_vreg_flag(spill, must_start_in_memory);
@@ -1421,10 +1458,11 @@
bool is_obj = (type == T_ARRAY || type == T_OBJECT);
if (is_obj) {
// Do the pre-write barrier, if any.
pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
+ data = shenandoah_read_barrier(data, NULL, true);
__ move(data, addr);
assert(src->is_register(), "must be register");
// Seems to be a precise address
post_barrier(LIR_OprFact::address(addr), data);
} else {
@@ -1447,26 +1485,33 @@
LIR_Opr data = value.result();
bool is_obj = (type == T_ARRAY || type == T_OBJECT);
LIR_Opr offset = off.result();
assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
+
+ LIR_Opr src_op = src.result();
+ src_op = shenandoah_write_barrier(src_op, NULL, false);
+ if (is_obj) {
+ data = shenandoah_read_barrier(data, NULL, true);
+ }
+
LIR_Address* addr;
if (offset->is_constant()) {
#ifdef _LP64
jlong c = offset->as_jlong();
if ((jlong)((jint)c) == c) {
- addr = new LIR_Address(src.result(), (jint)c, type);
+ addr = new LIR_Address(src_op, (jint)c, type);
} else {
LIR_Opr tmp = new_register(T_LONG);
__ move(offset, tmp);
- addr = new LIR_Address(src.result(), tmp, type);
+ addr = new LIR_Address(src_op, tmp, type);
}
#else
- addr = new LIR_Address(src.result(), offset->as_jint(), type);
+ addr = new LIR_Address(src_op, offset->as_jint(), type);
#endif
} else {
- addr = new LIR_Address(src.result(), offset, type);
+ addr = new LIR_Address(src_op, offset, type);
}
// Because we want a 2-arg form of xchg and xadd
__ move(data, dst);
< prev index next >