mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
6991512: G1 barriers fail with 64bit C1
Fix compare-and-swap intrinsic problem with G1 post-barriers and issue with branch ranges in G1 stubs on sparc Reviewed-by: never, kvn
This commit is contained in:
parent
e870866699
commit
28a13e88e7
6 changed files with 23 additions and 8 deletions
|
@ -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) {
|
||||||
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) {
|
||||||
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) {
|
||||||
// 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) {
|
||||||
__ 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) {
|
||||||
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
|
||||||
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();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue