< prev index next >
src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
Print this page
*** 298,316 ****
CodeEmitInfo* null_check_info = NULL;
if (x->needs_null_check()) {
null_check_info = new CodeEmitInfo(range_check_info);
}
// 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);
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);
// range_check also does the null check
null_check_info = NULL;
}
}
--- 298,327 ----
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(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(ary, index.result(), null_check_info, range_check_info);
// range_check also does the null check
null_check_info = NULL;
}
}
*** 318,339 ****
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());
}
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);
// Seems to be a precise
post_barrier(LIR_OprFact::address(array_addr), value.result());
} else {
! __ move(value.result(), array_addr, null_check_info);
}
}
void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
--- 329,350 ----
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(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(val, array_addr, null_check_info);
// Seems to be a precise
post_barrier(LIR_OprFact::address(array_addr), value.result());
} else {
! __ move(val, array_addr, null_check_info);
}
}
void LIRGenerator::do_MonitorEnter(MonitorEnter* x) {
*** 356,366 ****
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,
x->monitor_no(), info_for_exception, info);
}
void LIRGenerator::do_MonitorExit(MonitorExit* x) {
--- 367,379 ----
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);
! 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,778 ****
ShouldNotReachHere();
}
LIR_Opr addr = new_pointer_register();
LIR_Address* a;
if(offset.result()->is_constant()) {
#ifdef _LP64
jlong c = offset.result()->as_jlong();
if ((jlong)((jint)c) == c) {
! a = new LIR_Address(obj.result(),
(jint)c,
as_BasicType(type));
} else {
LIR_Opr tmp = new_register(T_LONG);
__ move(offset.result(), tmp);
! a = new LIR_Address(obj.result(),
tmp,
as_BasicType(type));
}
#else
! a = new LIR_Address(obj.result(),
offset.result()->as_jint(),
as_BasicType(type));
#endif
} else {
! a = new LIR_Address(obj.result(),
offset.result(),
LIR_Address::times_1,
0,
as_BasicType(type));
}
--- 761,795 ----
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_op,
(jint)c,
as_BasicType(type));
} else {
LIR_Opr tmp = new_register(T_LONG);
__ move(offset.result(), tmp);
! a = new LIR_Address(obj_op,
tmp,
as_BasicType(type));
}
#else
! a = new LIR_Address(obj_op,
offset.result()->as_jint(),
as_BasicType(type));
#endif
} else {
! a = new LIR_Address(obj_op,
offset.result(),
LIR_Address::times_1,
0,
as_BasicType(type));
}
*** 783,809 ****
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);
else if (type == intType)
! __ cas_int(addr, cmp.result(), val.result(), ill, ill);
else if (type == longType)
! __ cas_long(addr, cmp.result(), val.result(), 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());
}
}
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
--- 800,831 ----
pre_barrier(addr, LIR_OprFact::illegalOpr /* pre_val */,
true /* do_load */, false /* patch */, NULL);
}
LIR_Opr ill = LIR_OprFact::illegalOpr; // for convenience
!
! 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_op, ill, ill);
else if (type == longType)
! __ 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_op);
}
}
void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
*** 891,908 ****
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);
// 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_pos.load_item_force (FrameMap::rdx_opr);
! dst.load_item_force (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
--- 913,935 ----
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_op = force_opr_to(src_op, FrameMap::rcx_oop_opr);
src_pos.load_item_force (FrameMap::rdx_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,924 ****
// 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_pos.load_item_force (FrameMap::as_opr(j_rarg1));
! dst.load_item_force (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
--- 939,951 ----
// 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_op = force_opr_to(src_op, FrameMap::as_oop_opr(j_rarg0));
src_pos.load_item_force (FrameMap::as_opr(j_rarg1));
! 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,937 ****
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
}
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
--- 954,964 ----
int flags;
ciArrayKlass* expected_type;
arraycopy_helper(x, &flags, &expected_type);
! __ 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,987 ****
--- 1005,1018 ----
__ 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,1319 ****
--- 1341,1354 ----
}
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,1398 ****
--- 1424,1434 ----
}
}
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,1415 ****
--- 1442,1452 ----
}
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,1430 ****
--- 1458,1468 ----
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,1472 ****
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_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);
} else {
LIR_Opr tmp = new_register(T_LONG);
__ move(offset, tmp);
! addr = new LIR_Address(src.result(), tmp, type);
}
#else
! addr = new LIR_Address(src.result(), offset->as_jint(), type);
#endif
} else {
! addr = new LIR_Address(src.result(), offset, type);
}
// Because we want a 2-arg form of xchg and xadd
__ move(data, dst);
--- 1485,1517 ----
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_op, (jint)c, type);
} else {
LIR_Opr tmp = new_register(T_LONG);
__ move(offset, tmp);
! addr = new LIR_Address(src_op, tmp, type);
}
#else
! addr = new LIR_Address(src_op, offset->as_jint(), type);
#endif
} else {
! 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 >