mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-16 08:29:34 +00:00
8384080: Shenandoah: Simplify C1 CAS barriers
Reviewed-by: kdnilsen, rkennke
This commit is contained in:
parent
a72fb7452a
commit
9255eb2fd4
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user