8384080: Shenandoah: Simplify C1 CAS barriers

Reviewed-by: kdnilsen, rkennke
This commit is contained in:
Aleksey Shipilev 2026-05-12 12:00:35 +00:00
parent a72fb7452a
commit 9255eb2fd4
6 changed files with 71 additions and 566 deletions

View File

@ -1,122 +0,0 @@
/*
* Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "compiler/compilerDefinitions.inline.hpp"
#include "gc/shared/gc_globals.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.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();
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*/ true, /*release*/ true, /*is_cae*/ false, result);
// The membar here is necessary to prevent reordering between the
// release store in the CAS above and a subsequent volatile load.
// See also: LIR_Assembler::casw, LIR_Assembler::casl.
__ membar(__ AnyAny);
}
#undef __
#ifdef ASSERT
#define __ gen->lir(__FILE__, __LINE__)->
#else
#define __ gen->lir()->
#endif
LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) {
BasicType bt = access.type();
if (access.is_oop()) {
LIRGenerator *gen = access.gen();
if (ShenandoahSATBBarrier) {
pre_barrier(gen, access.access_emit_info(), access.decorators(), access.resolved_addr(),
LIR_OprFact::illegalOpr /* pre_val */);
}
if (ShenandoahCASBarrier) {
cmp_value.load_item();
new_value.load_item();
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();
LIR_Opr result = gen->new_register(T_INT);
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result));
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), new_value.result());
}
return result;
}
}
return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
}
LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) {
LIRGenerator* gen = access.gen();
BasicType type = access.type();
LIR_Opr result = gen->new_register(type);
value.load_item();
LIR_Opr value_opr = value.result();
assert(type == T_INT || is_reference_type(type) LP64_ONLY( || type == T_LONG ), "unexpected type");
LIR_Opr tmp = gen->new_register(T_INT);
__ xchg(access.resolved_addr(), value_opr, result, tmp);
if (access.is_oop()) {
result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), access.decorators());
LIR_Opr tmp = gen->new_register(type);
__ move(result, tmp);
result = tmp;
if (ShenandoahSATBBarrier) {
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr,
result /* pre_val */);
}
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), result);
}
}
return result;
}

View File

@ -1,145 +0,0 @@
/*
* Copyright (c) 2018, 2023, Red Hat, Inc. All rights reserved.
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "asm/macroAssembler.inline.hpp"
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#define __ masm->masm()->
void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler *masm) {
__ block_comment("LIR_OpShenandoahCompareAndSwap (shenandaohgc) {");
Register addr = _addr->as_register_lo();
Register new_val = _new_value->as_register();
Register cmp_val = _cmp_value->as_register();
Register tmp1 = _tmp1->as_register();
Register tmp2 = _tmp2->as_register();
Register result = result_opr()->as_register();
if (UseCompressedOops) {
__ encode_heap_oop(cmp_val, cmp_val);
__ encode_heap_oop(new_val, new_val);
}
// There might be a volatile load before this Unsafe CAS.
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ sync();
} else {
__ lwsync();
}
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), addr, cmp_val, new_val, tmp1, tmp2,
false, result);
if (UseCompressedOops) {
__ decode_heap_oop(cmp_val);
__ decode_heap_oop(new_val);
}
if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
__ isync();
} else {
__ sync();
}
__ block_comment("} LIR_OpShenandoahCompareAndSwap (shenandaohgc)");
}
#undef __
#ifdef ASSERT
#define __ gen->lir(__FILE__, __LINE__)->
#else
#define __ gen->lir()->
#endif
LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess &access, LIRItem &cmp_value, LIRItem &new_value) {
BasicType bt = access.type();
if (access.is_oop()) {
LIRGenerator* gen = access.gen();
if (ShenandoahSATBBarrier) {
pre_barrier(gen, access.access_emit_info(), access.decorators(), access.resolved_addr(),
LIR_OprFact::illegalOpr);
}
if (ShenandoahCASBarrier) {
cmp_value.load_item();
new_value.load_item();
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();
LIR_Opr result = gen->new_register(T_INT);
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result));
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), new_value.result());
}
return result;
}
}
return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
}
LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess &access, LIRItem &value) {
LIRGenerator* gen = access.gen();
BasicType type = access.type();
LIR_Opr result = gen->new_register(type);
value.load_item();
LIR_Opr value_opr = value.result();
assert(type == T_INT || is_reference_type(type) LP64_ONLY( || type == T_LONG ), "unexpected type");
LIR_Opr tmp_xchg = gen->new_register(T_INT);
__ xchg(access.resolved_addr(), value_opr, result, tmp_xchg);
if (access.is_oop()) {
result = load_reference_barrier_impl(access.gen(), result, LIR_OprFact::addressConst(0),
access.decorators());
LIR_Opr tmp_barrier = gen->new_register(type);
__ move(result, tmp_barrier);
result = tmp_barrier;
if (ShenandoahSATBBarrier) {
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr, result);
}
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), result);
}
}
return result;
}

View File

@ -1,118 +0,0 @@
/*
* Copyright (c) 2018, 2019, Red Hat, Inc. All rights reserved.
* Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "gc/shared/gc_globals.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.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();
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 */ Assembler::aq,
/* release */ Assembler::rl, /* is_cae */ false, result);
}
#undef __
#ifdef ASSERT
#define __ gen->lir(__FILE__, __LINE__)->
#else
#define __ gen->lir()->
#endif
LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) {
BasicType bt = access.type();
if (access.is_oop()) {
LIRGenerator *gen = access.gen();
if (ShenandoahSATBBarrier) {
pre_barrier(gen, access.access_emit_info(), access.decorators(), access.resolved_addr(),
LIR_OprFact::illegalOpr /* pre_val */);
}
if (ShenandoahCASBarrier) {
cmp_value.load_item();
new_value.load_item();
LIR_Opr tmp1 = gen->new_register(T_OBJECT);
LIR_Opr tmp2 = gen->new_register(T_OBJECT);
LIR_Opr addr = access.resolved_addr()->as_address_ptr()->base();
LIR_Opr result = gen->new_register(T_INT);
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), tmp1, tmp2, result));
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), new_value.result());
}
return result;
}
}
return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
}
LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) {
LIRGenerator* gen = access.gen();
BasicType type = access.type();
LIR_Opr result = gen->new_register(type);
value.load_item();
LIR_Opr value_opr = value.result();
assert(type == T_INT || is_reference_type(type) LP64_ONLY( || type == T_LONG ), "unexpected type");
LIR_Opr tmp = gen->new_register(T_INT);
__ xchg(access.resolved_addr(), value_opr, result, tmp);
if (access.is_oop()) {
result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), access.decorators());
LIR_Opr tmp_opr = gen->new_register(type);
__ move(result, tmp_opr);
result = tmp_opr;
if (ShenandoahSATBBarrier) {
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr,
result /* pre_val */);
}
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), result);
}
}
return result;
}

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "c1/c1_LIRAssembler.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "gc/shared/gc_globals.hpp"
#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp"
#include "gc/shenandoah/shenandoahBarrierSet.hpp"
#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
#define __ masm->masm()->
void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) {
Register addr = _addr->is_single_cpu() ? _addr->as_register() : _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 != noreg, "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");
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
#define __ gen->lir()->
#endif
LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) {
if (access.is_oop()) {
LIRGenerator* gen = access.gen();
if (ShenandoahSATBBarrier) {
pre_barrier(gen, access.access_emit_info(), access.decorators(), access.resolved_addr(),
LIR_OprFact::illegalOpr /* pre_val */);
}
if (ShenandoahCASBarrier) {
cmp_value.load_item_force(FrameMap::rax_oop_opr);
new_value.load_item();
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();
LIR_Opr result = gen->new_register(T_INT);
__ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result));
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), new_value.result());
}
return result;
}
}
return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
}
LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) {
LIRGenerator* gen = access.gen();
BasicType type = access.type();
LIR_Opr result = gen->new_register(type);
value.load_item();
LIR_Opr value_opr = value.result();
// Because we want a 2-arg form of xchg and xadd
__ move(value_opr, result);
assert(type == T_INT || is_reference_type(type) || type == T_LONG, "unexpected type");
__ xchg(access.resolved_addr(), result, result, LIR_OprFact::illegalOpr);
if (access.is_oop()) {
result = load_reference_barrier(access.gen(), result, LIR_OprFact::addressConst(0), access.decorators());
LIR_Opr tmp = gen->new_register(type);
__ move(result, tmp);
result = tmp;
if (ShenandoahSATBBarrier) {
pre_barrier(access.gen(), access.access_emit_info(), access.decorators(), LIR_OprFact::illegalOpr,
result /* pre_val */);
}
if (ShenandoahCardBarrier) {
post_barrier(access, access.resolved_addr(), result);
}
}
return result;
}

View File

@ -203,7 +203,7 @@ void ShenandoahBarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value)
bool precise = is_array || on_anonymous;
LIR_Opr post_addr = precise ? access.resolved_addr() : access.base().opr();
post_barrier(access, post_addr, value);
post_barrier(access, post_addr);
}
}
@ -318,7 +318,7 @@ bool ShenandoahBarrierSetC1::generate_c1_runtime_stubs(BufferBlob* buffer_blob)
return true;
}
void ShenandoahBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Opr new_val) {
void ShenandoahBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr) {
assert(ShenandoahCardBarrier, "Should have been checked by caller");
DecoratorSet decorators = access.decorators();
@ -372,3 +372,71 @@ void ShenandoahBarrierSetC1::post_barrier(LIRAccess& access, LIR_Opr addr, LIR_O
__ move(dirty, card_addr);
}
}
LIR_Opr ShenandoahBarrierSetC1::atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value) {
if (!access.is_oop()) {
return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
}
LIRGenerator* gen = access.gen();
LIR_Opr tmp = gen->new_register(T_OBJECT);
LIR_Opr addr = access.resolved_addr();
// Handle the previous value through SATB, as we are about to perform the store.
__ load(addr->as_address_ptr(), tmp);
if (ShenandoahSATBBarrier) {
pre_barrier(gen, access.access_emit_info(), access.decorators(),
/* addr_opr (unused) = */ LIR_OprFact::illegalOpr,
/* pre_val = */ tmp);
}
// Perform LRB on location to fix it up for this and all following accesses.
// This guarantees there are no false negatives due to concurrent evacuation,
// and the value loaded later by CAS is sanitized by some LRB, or is null.
if (ShenandoahLoadRefBarrier) {
load_reference_barrier(gen, /* obj = */ tmp, /* addr = */ addr, access.decorators());
}
LIR_Opr result = BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value);
if (ShenandoahCardBarrier) {
post_barrier(access, /* addr = */ addr);
}
return result;
}
LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value) {
if (!access.is_oop()) {
return BarrierSetC1::atomic_xchg_at_resolved(access, value);
}
LIRGenerator* gen = access.gen();
LIR_Opr tmp = gen->new_register(T_OBJECT);
LIR_Opr addr = access.resolved_addr();
// Handle the previous value through SATB, as we are about to perform the store.
__ load(addr->as_address_ptr(), tmp);
if (ShenandoahSATBBarrier) {
pre_barrier(gen, access.access_emit_info(), access.decorators(),
/* addr_opr (unused) = */ LIR_OprFact::illegalOpr,
/* pre_val = */ tmp);
}
// Perform LRB on location to fix it up for this and all following accesses.
// This is purely opportunistic: we would not have any false negatives here.
// This guarantees the value loaded later by XCHG is sanitized by some LRB, or is null.
if (ShenandoahLoadRefBarrier) {
load_reference_barrier(gen, /* obj = */ tmp, /* addr = */ addr, access.decorators());
}
LIR_Opr result = BarrierSetC1::atomic_xchg_at_resolved(access, value);
if (ShenandoahCardBarrier) {
post_barrier(access, /* addr = */ addr);
}
return result;
}

View File

@ -136,61 +136,6 @@ public:
#endif // PRODUCT
};
class LIR_OpShenandoahCompareAndSwap : public LIR_Op {
friend class LIR_OpVisitState;
private:
LIR_Opr _addr;
LIR_Opr _cmp_value;
LIR_Opr _new_value;
LIR_Opr _tmp1;
LIR_Opr _tmp2;
public:
LIR_OpShenandoahCompareAndSwap(LIR_Opr addr, LIR_Opr cmp_value, LIR_Opr new_value,
LIR_Opr t1, LIR_Opr t2, LIR_Opr result)
: LIR_Op(lir_none, result, nullptr) // no info
, _addr(addr)
, _cmp_value(cmp_value)
, _new_value(new_value)
, _tmp1(t1)
, _tmp2(t2) { }
LIR_Opr addr() const { return _addr; }
LIR_Opr cmp_value() const { return _cmp_value; }
LIR_Opr new_value() const { return _new_value; }
LIR_Opr tmp1() const { return _tmp1; }
LIR_Opr tmp2() const { return _tmp2; }
virtual void visit(LIR_OpVisitState* state) {
if (_info) state->do_info(_info);
assert(_addr->is_valid(), "used"); state->do_input(_addr);
state->do_temp(_addr);
assert(_cmp_value->is_valid(), "used"); state->do_input(_cmp_value);
state->do_temp(_cmp_value);
assert(_new_value->is_valid(), "used"); state->do_input(_new_value);
state->do_temp(_new_value);
if (_tmp1->is_valid()) state->do_temp(_tmp1);
if (_tmp2->is_valid()) state->do_temp(_tmp2);
if (_result->is_valid()) state->do_output(_result);
}
virtual void emit_code(LIR_Assembler* masm);
virtual void print_instr(outputStream* out) const {
addr()->print(out); out->print(" ");
cmp_value()->print(out); out->print(" ");
new_value()->print(out); out->print(" ");
tmp1()->print(out); out->print(" ");
tmp2()->print(out); out->print(" ");
}
#ifndef PRODUCT
virtual const char* name() const {
return "shenandoah_cas_obj";
}
#endif // PRODUCT
};
class ShenandoahBarrierSetC1 : public BarrierSetC1 {
private:
CodeBlob* _pre_barrier_c1_runtime_code_blob;
@ -245,7 +190,7 @@ protected:
virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value);
void post_barrier(LIRAccess& access, LIR_Opr addr, LIR_Opr new_val);
void post_barrier(LIRAccess& access, LIR_Opr addr);
public: