提交 b72f3305 编写于 作者: I iveresov

6991512: G1 barriers fail with 64bit C1

Summary: Fix compare-and-swap intrinsic problem with G1 post-barriers and issue with branch ranges in G1 stubs on sparc
Reviewed-by: never, kvn
上级 1e2faee8
...@@ -825,6 +825,12 @@ class Assembler : public AbstractAssembler { ...@@ -825,6 +825,12 @@ class Assembler : public AbstractAssembler {
// test if -4096 <= x <= 4095 // test if -4096 <= x <= 4095
static bool is_simm13(int x) { return is_simm(x, 13); } static bool is_simm13(int x) { return is_simm(x, 13); }
// test if label is in simm16 range in words (wdisp16).
bool is_in_wdisp16_range(Label& L) {
intptr_t d = intptr_t(pc()) - intptr_t(target(L));
return is_simm(d, 18);
}
enum ASIs { // page 72, v9 enum ASIs { // page 72, v9
ASI_PRIMARY = 0x80, ASI_PRIMARY = 0x80,
ASI_PRIMARY_LITTLE = 0x88 ASI_PRIMARY_LITTLE = 0x88
......
...@@ -425,8 +425,13 @@ void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { ...@@ -425,8 +425,13 @@ void G1PreBarrierStub::emit_code(LIR_Assembler* ce) {
Register pre_val_reg = pre_val()->as_register(); Register pre_val_reg = pre_val()->as_register();
ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false);
__ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, if (__ is_in_wdisp16_range(_continuation)) {
pre_val_reg, _continuation); __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
pre_val_reg, _continuation);
} else {
__ cmp(pre_val_reg, G0);
__ brx(Assembler::equal, false, Assembler::pn, _continuation);
}
__ delayed()->nop(); __ delayed()->nop();
__ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id)); __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
...@@ -452,8 +457,13 @@ void G1PostBarrierStub::emit_code(LIR_Assembler* ce) { ...@@ -452,8 +457,13 @@ void G1PostBarrierStub::emit_code(LIR_Assembler* ce) {
assert(new_val()->is_register(), "Precondition."); assert(new_val()->is_register(), "Precondition.");
Register addr_reg = addr()->as_pointer_register(); Register addr_reg = addr()->as_pointer_register();
Register new_val_reg = new_val()->as_register(); Register new_val_reg = new_val()->as_register();
__ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, if (__ is_in_wdisp16_range(_continuation)) {
new_val_reg, _continuation); __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt,
new_val_reg, _continuation);
} else {
__ cmp(new_val_reg, G0);
__ brx(Assembler::equal, false, Assembler::pn, _continuation);
}
__ delayed()->nop(); __ delayed()->nop();
__ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id)); __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id));
......
...@@ -664,7 +664,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { ...@@ -664,7 +664,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
// Use temps to avoid kills // Use temps to avoid kills
LIR_Opr t1 = FrameMap::G1_opr; LIR_Opr t1 = FrameMap::G1_opr;
LIR_Opr t2 = FrameMap::G3_opr; LIR_Opr t2 = FrameMap::G3_opr;
LIR_Opr addr = new_pointer_register(); LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
// get address of field // get address of field
obj.load_item(); obj.load_item();
......
...@@ -1941,8 +1941,6 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { ...@@ -1941,8 +1941,6 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) {
__ cmpxchgptr(newval, Address(addr, 0)); __ cmpxchgptr(newval, Address(addr, 0));
} else if (op->code() == lir_cas_int) { } else if (op->code() == lir_cas_int) {
__ cmpxchgl(newval, Address(addr, 0)); __ cmpxchgl(newval, Address(addr, 0));
} else {
LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0)));
} }
#ifdef _LP64 #ifdef _LP64
} else if (op->code() == lir_cas_long) { } else if (op->code() == lir_cas_long) {
......
...@@ -765,7 +765,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { ...@@ -765,7 +765,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
ShouldNotReachHere(); ShouldNotReachHere();
} }
LIR_Opr addr = new_pointer_register(); LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register();
LIR_Address* a; LIR_Address* a;
if(offset.result()->is_constant()) { if(offset.result()->is_constant()) {
a = new LIR_Address(obj.result(), a = new LIR_Address(obj.result(),
......
...@@ -1350,6 +1350,7 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr ...@@ -1350,6 +1350,7 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr
addr = ptr; addr = ptr;
} }
assert(addr->is_register(), "must be a register at this point"); assert(addr->is_register(), "must be a register at this point");
assert(addr->type() == T_OBJECT, "addr should point to an object");
LIR_Opr xor_res = new_pointer_register(); LIR_Opr xor_res = new_pointer_register();
LIR_Opr xor_shift_res = new_pointer_register(); LIR_Opr xor_shift_res = new_pointer_register();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册