8217016: Shenandoah: Streamline generation of CAS barriers

Reviewed-by: roland
This commit is contained in:
Roman Kennke 2019-01-26 01:21:33 +01:00
parent cb960e9a30
commit d271630fb2
9 changed files with 110 additions and 150 deletions

View File

@ -423,45 +423,14 @@ void ShenandoahBarrierSetAssembler::resolve(MacroAssembler* masm, DecoratorSet d
}
void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
bool acquire, bool release, bool weak, bool encode,
Register tmp1, Register tmp2, Register tmp3,
bool acquire, bool release, bool weak, bool is_cae,
Register result) {
if (!ShenandoahCASBarrier) {
if (UseCompressedOops) {
if (encode) {
__ encode_heap_oop(tmp1, expected);
expected = tmp1;
__ encode_heap_oop(tmp3, new_val);
new_val = tmp3;
}
__ cmpxchg(addr, expected, new_val, Assembler::word, /* acquire*/ true, /* release*/ true, /* weak*/ false, rscratch1);
__ membar(__ AnyAny);
} else {
__ cmpxchg(addr, expected, new_val, Assembler::xword, /* acquire*/ true, /* release*/ true, /* weak*/ false, rscratch1);
__ membar(__ AnyAny);
}
return;
}
if (encode) {
storeval_barrier(masm, new_val, tmp3);
}
if (UseCompressedOops) {
if (encode) {
__ encode_heap_oop(tmp1, expected);
expected = tmp1;
__ encode_heap_oop(tmp2, new_val);
new_val = tmp2;
}
}
bool is_cae = (result != noreg);
Register tmp = rscratch2;
bool is_narrow = UseCompressedOops;
Assembler::operand_size size = is_narrow ? Assembler::word : Assembler::xword;
if (! is_cae) result = rscratch1;
assert_different_registers(addr, expected, new_val, result, tmp3);
assert_different_registers(addr, expected, new_val, result, tmp);
Label retry, done, fail;
@ -474,35 +443,38 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, Register a
__ cmp(result, expected);
}
__ br(Assembler::NE, fail);
__ store_exclusive(tmp3, new_val, addr, size, release);
__ store_exclusive(tmp, new_val, addr, size, release);
if (weak) {
__ cmpw(tmp3, 0u); // If the store fails, return NE to our caller
__ cmpw(tmp, 0u); // If the store fails, return NE to our caller
} else {
__ cbnzw(tmp3, retry);
__ cbnzw(tmp, retry);
}
__ b(done);
__ bind(fail);
// Check if rb(expected)==rb(result)
// Shuffle registers so that we have memory value ready for next expected.
__ mov(tmp3, expected);
__ mov(tmp, expected);
__ mov(expected, result);
if (is_narrow) {
__ decode_heap_oop(result, result);
__ decode_heap_oop(tmp3, tmp3);
__ decode_heap_oop(tmp, tmp);
}
read_barrier_impl(masm, result);
read_barrier_impl(masm, tmp3);
__ cmp(result, tmp3);
read_barrier_impl(masm, tmp);
__ cmp(result, tmp);
// Retry with expected now being the value we just loaded from addr.
__ br(Assembler::EQ, retry);
if (is_narrow && is_cae) {
if (is_cae && is_narrow) {
// For cmp-and-exchange and narrow oops, we need to restore
// the compressed old-value. We moved it to 'expected' a few lines up.
__ mov(result, expected);
}
__ bind(done);
if (!is_cae) {
__ cset(result, Assembler::EQ);
}
}
#ifdef COMPILER1

View File

@ -60,7 +60,6 @@ private:
void read_barrier_not_null_impl(MacroAssembler* masm, Register dst);
void write_barrier(MacroAssembler* masm, Register dst);
void write_barrier_impl(MacroAssembler* masm, Register dst);
void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp);
void asm_acmp_barrier(MacroAssembler* masm, Register op1, Register op2);
address generate_shenandoah_wb(StubCodeGenerator* cgen);
@ -68,6 +67,8 @@ private:
public:
static address shenandoah_wb();
void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp);
#ifdef COMPILER1
void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub);
void gen_write_barrier_stub(LIR_Assembler* ce, ShenandoahWriteBarrierStub* stub);
@ -92,9 +93,7 @@ public:
Label& slow_case);
void cmpxchg_oop(MacroAssembler* masm, Register addr, Register expected, Register new_val,
bool acquire, bool release, bool weak, bool encode,
Register tmp1, Register tmp2, Register tmp3 = rscratch2,
Register result = noreg);
bool acquire, bool release, bool weak, bool is_cae, Register result);
virtual void barrier_stubs_init();
};

View File

@ -28,15 +28,30 @@
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#define __ masm->masm()->
void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) {
Register addr = _addr->as_register_lo();
Register newval = _new_value->as_register();
Register cmpval = _cmp_value->as_register();
Register tmp1 = _tmp1->as_register();
Register tmp2 = _tmp2->as_register();
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, true, tmp1, tmp2);
Register result = result_opr()->as_register();
ShenandoahBarrierSet::assembler()->storeval_barrier(masm->masm(), newval, rscratch2);
if (UseCompressedOops) {
__ encode_heap_oop(tmp1, cmpval);
cmpval = tmp1;
__ encode_heap_oop(tmp2, newval);
newval = tmp2;
}
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, result);
}
#undef __
#ifdef ASSERT
#define __ gen->lir(__FILE__, __LINE__)->
#else
@ -58,13 +73,9 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LI
LIR_Opr t1 = gen->new_register(T_OBJECT);
LIR_Opr t2 = gen->new_register(T_OBJECT);
LIR_Opr addr = access.resolved_addr()->as_address_ptr()->base();
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2,
LIR_OprFact::illegalOpr));
LIR_Opr result = gen->new_register(T_INT);
__ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
result, T_INT);
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result));
return result;
}
}

View File

@ -26,22 +26,22 @@ source_hpp %{
%}
encode %{
enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
MacroAssembler _masm(&cbuf);
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
/*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
%}
enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{
enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
MacroAssembler _masm(&cbuf);
guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
/*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
%}
%}
@ -66,11 +66,9 @@ instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, i
format %{
"cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp),
aarch64_enc_cset_eq(res));
ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res));
ins_pipe(pipe_slow);
%}
@ -84,14 +82,12 @@ instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, i
format %{
"cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
__ cset($res$$Register, Assembler::EQ);
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -107,11 +103,9 @@ instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval
format %{
"cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp),
aarch64_enc_cset_eq(res));
ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res));
ins_pipe(pipe_slow);
%}
@ -126,14 +120,12 @@ instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval
format %{
"cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
"cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg);
__ cset($res$$Register, Assembler::EQ);
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
%}
ins_pipe(pipe_slow);
@ -150,7 +142,7 @@ instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldva
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ false, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register);
/*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -166,7 +158,7 @@ instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldva
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register);
/*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -183,7 +175,7 @@ instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN ol
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ true, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register);
/*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -200,7 +192,7 @@ instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP ol
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register);
/*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -217,8 +209,7 @@ instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldva
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
__ csetw($res$$Register, Assembler::EQ);
/*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -229,14 +220,12 @@ instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldva
effect(TEMP tmp, KILL cr);
format %{
"cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
"csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
%}
ins_encode %{
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
__ csetw($res$$Register, Assembler::EQ);
/*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -254,8 +243,7 @@ instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN ol
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
__ csetw($res$$Register, Assembler::EQ);
/*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
%}
ins_pipe(pipe_slow);
%}
@ -273,9 +261,7 @@ instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP ol
Register tmp = $tmp$$Register;
__ mov(tmp, $oldval$$Register); // Must not clobber oldval.
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
/*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg);
__ csetw($res$$Register, Assembler::EQ);
/*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
%}
ins_pipe(pipe_slow);
%}

View File

@ -592,64 +592,19 @@ void ShenandoahBarrierSetAssembler::resolve(MacroAssembler* masm, DecoratorSet d
#ifndef _LP64
void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
Register res, Address addr, Register oldval, Register newval,
bool exchange, bool encode, Register tmp1, Register tmp2) {
bool exchange, Register tmp1, Register tmp2) {
// Shenandoah has no 32-bit version for this.
Unimplemented();
}
#else
void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
Register res, Address addr, Register oldval, Register newval,
bool exchange, bool encode, Register tmp1, Register tmp2) {
if (!ShenandoahCASBarrier) {
#ifdef _LP64
if (UseCompressedOops) {
if (encode) {
__ encode_heap_oop(oldval);
__ mov(rscratch1, newval);
__ encode_heap_oop(rscratch1);
newval = rscratch1;
}
if (os::is_MP()) {
__ lock();
}
// oldval (rax) is implicitly used by this instruction
__ cmpxchgl(newval, addr);
} else
#endif
{
if (os::is_MP()) {
__ lock();
}
__ cmpxchgptr(newval, addr);
}
if (!exchange) {
assert(res != NULL, "need result register");
__ setb(Assembler::equal, res);
__ movzbl(res, res);
}
return;
}
bool exchange, Register tmp1, Register tmp2) {
assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled");
assert(oldval == rax, "must be in rax for implicit use in cmpxchg");
Label retry, done;
// Apply storeval barrier to newval.
if (encode) {
storeval_barrier(masm, newval, tmp1);
}
if (UseCompressedOops) {
if (encode) {
__ encode_heap_oop(oldval);
__ mov(rscratch1, newval);
__ encode_heap_oop(rscratch1);
newval = rscratch1;
}
}
// Remember oldval for retry logic below
if (UseCompressedOops) {
__ movl(tmp1, oldval);

View File

@ -64,7 +64,6 @@ private:
void write_barrier(MacroAssembler* masm, Register dst);
void write_barrier_impl(MacroAssembler* masm, Register dst);
void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp);
void storeval_barrier_impl(MacroAssembler* masm, Register dst, Register tmp);
address generate_shenandoah_wb(StubCodeGenerator* cgen);
@ -75,6 +74,7 @@ private:
public:
static address shenandoah_wb();
void storeval_barrier(MacroAssembler* masm, Register dst, Register tmp);
#ifdef COMPILER1
void gen_pre_barrier_stub(LIR_Assembler* ce, ShenandoahPreBarrierStub* stub);
void gen_write_barrier_stub(LIR_Assembler* ce, ShenandoahWriteBarrierStub* stub);
@ -83,7 +83,7 @@ public:
void cmpxchg_oop(MacroAssembler* masm,
Register res, Address addr, Register oldval, Register newval,
bool exchange, bool encode, Register tmp1, Register tmp2);
bool exchange, Register tmp1, Register tmp2);
virtual void arraycopy_prologue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
Register src, Register dst, Register count);
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,

View File

@ -28,20 +28,36 @@
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#define __ masm->masm()->
void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) {
Register addr = _addr->as_register_lo();
Register newval = _new_value->as_register();
Register cmpval = _cmp_value->as_register();
Register tmp1 = _tmp1->as_register();
Register tmp2 = _tmp2->as_register();
Register result = result_opr()->as_register();
assert(cmpval == rax, "wrong register");
assert(newval != NULL, "new val must be register");
assert(cmpval != newval, "cmp and new values must be in different registers");
assert(cmpval != addr, "cmp and addr must be in different registers");
assert(newval != addr, "new value and addr must be in different registers");
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), NULL, Address(addr, 0), cmpval, newval, true, true, tmp1, tmp2);
// Apply storeval barrier to newval.
ShenandoahBarrierSet::assembler()->storeval_barrier(masm->masm(), newval, tmp1);
if (UseCompressedOops) {
__ encode_heap_oop(cmpval);
__ mov(rscratch1, newval);
__ encode_heap_oop(rscratch1);
newval = rscratch1;
}
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), result, Address(addr, 0), cmpval, newval, false, tmp1, tmp2);
}
#undef __
#ifdef ASSERT
#define __ gen->lir(__FILE__, __LINE__)->
#else
@ -63,12 +79,9 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LI
LIR_Opr t1 = gen->new_register(T_OBJECT);
LIR_Opr t2 = gen->new_register(T_OBJECT);
LIR_Opr addr = access.resolved_addr()->as_address_ptr()->base();
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, LIR_OprFact::illegalOpr));
LIR_Opr result = gen->new_register(T_INT);
__ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0),
result, T_INT);
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result));
return result;
}
}

View File

@ -83,7 +83,7 @@ instruct compareAndSwapP_shenandoah(rRegI res,
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
$res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
false, // swap
false, $tmp1$$Register, $tmp2$$Register
$tmp1$$Register, $tmp2$$Register
);
%}
ins_pipe( pipe_cmpxchg );
@ -104,7 +104,7 @@ instruct compareAndSwapN_shenandoah(rRegI res,
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
$res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
false, // swap
false, $tmp1$$Register, $tmp2$$Register
$tmp1$$Register, $tmp2$$Register
);
%}
ins_pipe( pipe_cmpxchg );
@ -123,7 +123,7 @@ instruct compareAndExchangeN_shenandoah(memory mem_ptr,
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
true, // exchange
false, $tmp1$$Register, $tmp2$$Register
$tmp1$$Register, $tmp2$$Register
);
%}
ins_pipe( pipe_cmpxchg );
@ -145,7 +145,7 @@ instruct compareAndExchangeP_shenandoah(memory mem_ptr,
ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm,
NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
true, // exchange
false, $tmp1$$Register, $tmp2$$Register
$tmp1$$Register, $tmp2$$Register
);
%}
ins_pipe( pipe_cmpxchg );

View File

@ -777,11 +777,19 @@ Node* ShenandoahBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop()));
load_store = kit->gvn().transform(new ShenandoahCompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo));
if (ShenandoahCASBarrier) {
load_store = kit->gvn().transform(new ShenandoahCompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo));
} else {
load_store = kit->gvn().transform(new CompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo));
}
} else
#endif
{
load_store = kit->gvn().transform(new ShenandoahCompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo));
if (ShenandoahCASBarrier) {
load_store = kit->gvn().transform(new ShenandoahCompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo));
} else {
load_store = kit->gvn().transform(new CompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo));
}
}
access.set_raw_access(load_store);
@ -815,18 +823,34 @@ Node* ShenandoahBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAcces
if (adr->bottom_type()->is_ptr_to_narrowoop()) {
Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop()));
Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop()));
if (is_weak_cas) {
load_store = kit->gvn().transform(new ShenandoahWeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
if (ShenandoahCASBarrier) {
if (is_weak_cas) {
load_store = kit->gvn().transform(new ShenandoahWeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
} else {
load_store = kit->gvn().transform(new ShenandoahCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
}
} else {
load_store = kit->gvn().transform(new ShenandoahCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
if (is_weak_cas) {
load_store = kit->gvn().transform(new WeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
} else {
load_store = kit->gvn().transform(new CompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo));
}
}
} else
#endif
{
if (is_weak_cas) {
load_store = kit->gvn().transform(new ShenandoahWeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
if (ShenandoahCASBarrier) {
if (is_weak_cas) {
load_store = kit->gvn().transform(new ShenandoahWeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
} else {
load_store = kit->gvn().transform(new ShenandoahCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
}
} else {
load_store = kit->gvn().transform(new ShenandoahCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
if (is_weak_cas) {
load_store = kit->gvn().transform(new WeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
} else {
load_store = kit->gvn().transform(new CompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo));
}
}
}
access.set_raw_access(load_store);