From b72f33052414a26ef528c0e865fa8593d3d5ae5c Mon Sep 17 00:00:00 2001 From: iveresov Date: Tue, 12 Oct 2010 23:51:20 -0700 Subject: [PATCH] 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 --- src/cpu/sparc/vm/assembler_sparc.hpp | 6 ++++++ src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp | 18 ++++++++++++++---- src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp | 2 +- src/cpu/x86/vm/c1_LIRAssembler_x86.cpp | 2 -- src/cpu/x86/vm/c1_LIRGenerator_x86.cpp | 2 +- src/share/vm/c1/c1_LIRGenerator.cpp | 1 + 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/cpu/sparc/vm/assembler_sparc.hpp b/src/cpu/sparc/vm/assembler_sparc.hpp index 7d56342c5..c8317fd37 100644 --- a/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/src/cpu/sparc/vm/assembler_sparc.hpp @@ -825,6 +825,12 @@ class Assembler : public AbstractAssembler { // test if -4096 <= x <= 4095 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 ASI_PRIMARY = 0x80, ASI_PRIMARY_LITTLE = 0x88 diff --git a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp index 4eb6680df..effc007d7 100644 --- a/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp +++ b/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp @@ -425,8 +425,13 @@ void G1PreBarrierStub::emit_code(LIR_Assembler* ce) { Register pre_val_reg = pre_val()->as_register(); ce->mem2reg(addr(), pre_val(), T_OBJECT, patch_code(), info(), false); - __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, - pre_val_reg, _continuation); + if (__ is_in_wdisp16_range(_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(); __ 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."); Register addr_reg = addr()->as_pointer_register(); Register new_val_reg = new_val()->as_register(); - __ br_on_reg_cond(Assembler::rc_z, /*annul*/false, Assembler::pt, - new_val_reg, _continuation); + if (__ is_in_wdisp16_range(_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(); __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_post_barrier_slow_id)); diff --git a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp index 2566f3f82..c5385a984 100644 --- a/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp +++ b/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp @@ -664,7 +664,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { // Use temps to avoid kills LIR_Opr t1 = FrameMap::G1_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 obj.load_item(); diff --git a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp index fa0ef0c8b..e9ca3d885 100644 --- a/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @@ -1941,8 +1941,6 @@ void LIR_Assembler::emit_compare_and_swap(LIR_OpCompareAndSwap* op) { __ cmpxchgptr(newval, Address(addr, 0)); } else if (op->code() == lir_cas_int) { __ cmpxchgl(newval, Address(addr, 0)); - } else { - LP64_ONLY(__ cmpxchgq(newval, Address(addr, 0))); } #ifdef _LP64 } else if (op->code() == lir_cas_long) { diff --git a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp index dd8bc8d99..c9a26e7b1 100644 --- a/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp +++ b/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp @@ -765,7 +765,7 @@ void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { ShouldNotReachHere(); } - LIR_Opr addr = new_pointer_register(); + LIR_Opr addr = (type == objectType) ? new_register(T_OBJECT) : new_pointer_register(); LIR_Address* a; if(offset.result()->is_constant()) { a = new LIR_Address(obj.result(), diff --git a/src/share/vm/c1/c1_LIRGenerator.cpp b/src/share/vm/c1/c1_LIRGenerator.cpp index 332f193e2..dffc85c97 100644 --- a/src/share/vm/c1/c1_LIRGenerator.cpp +++ b/src/share/vm/c1/c1_LIRGenerator.cpp @@ -1350,6 +1350,7 @@ void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_Opr addr = ptr; } 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_shift_res = new_pointer_register(); -- GitLab