# HG changeset patch # Parent f5c9d4ff794afac5692eec23f486a4fc00f56461 diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/aarch64.ad --- a/src/hotspot/cpu/aarch64/aarch64.ad Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/aarch64.ad Mon May 06 16:07:41 2019 -0400 @@ -1002,6 +1002,8 @@ #include "opto/addnode.hpp" #if INCLUDE_SHENANDOAHGC #include "gc/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc/shenandoah/shenandoahBarrierSet.hpp" +#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" #endif class CallStubImpl { @@ -4383,13 +4385,13 @@ %} - 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. - __ cmpxchg_oop($mem$$Register, tmp, $newval$$Register, - /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); %} // The only difference between aarch64_enc_cmpxchg and @@ -4413,13 +4415,14 @@ %} - 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. - __ cmpxchg_oop($mem$$Register, tmp, $newval$$Register, - /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, + $res$$Register); %} // auxiliary used for CompareAndSwapX to set result register @@ -9694,11 +9697,9 @@ format %{ "cmpxchg_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_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); %} @@ -9732,14 +9733,12 @@ format %{ "cmpxchgw_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. - __ cmpxchg_oop($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); @@ -9814,11 +9813,9 @@ 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); %} @@ -9852,14 +9849,12 @@ 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. - __ cmpxchg_oop($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); @@ -9970,8 +9965,8 @@ ins_encode %{ Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop($mem$$Register, tmp, $newval$$Register, - /*acquire*/ false, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register); %} ins_pipe(pipe_slow); %} @@ -10003,8 +9998,8 @@ ins_encode %{ Register tmp = $tmp$$Register; __ mov(tmp, $oldval$$Register); // Must not clobber oldval. - __ cmpxchg_oop($mem$$Register, tmp, $newval$$Register, - /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register); %} ins_pipe(pipe_slow); %} @@ -10102,14 +10097,12 @@ effect(TEMP tmp, KILL cr); format %{ "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, 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. - __ cmpxchg_oop($mem$$Register, tmp, $newval$$Register, - /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); - __ csetw($res$$Register, Assembler::EQ); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); %} ins_pipe(pipe_slow); %} @@ -10139,14 +10132,12 @@ effect(TEMP tmp, KILL cr); format %{ "cmpxchg_oop_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. - __ cmpxchg_oop($mem$$Register, tmp, $newval$$Register, - /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); - __ csetw($res$$Register, Assembler::EQ); + ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, + /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); %} ins_pipe(pipe_slow); %} diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Mon May 06 16:07:41 2019 -0400 @@ -1572,11 +1572,17 @@ Label succeed, fail, around; if (op->code() == lir_cas_obj) { - assert(op->tmp1()->is_valid(), "must be"); - assert(op->tmp1()->is_register(), "tmp1 must be register"); - Register t1 = op->tmp1()->as_register(); - Register t2 = op->tmp2()->as_register(); - __ cmpxchg_oop(addr, cmpval, newval, /*acquire*/ false, /*release*/ true, /*weak*/ false, true, t1, t2); + if (UseCompressedOops) { + Register t1 = op->tmp1()->as_register(); + assert(op->tmp1()->is_valid(), "must be"); + __ encode_heap_oop(t1, cmpval); + cmpval = t1; + __ encode_heap_oop(rscratch2, newval); + newval = rscratch2; + casw(addr, newval, cmpval); + } else { + casl(addr, newval, cmpval); + } assert(op->tmp1()->is_valid(), "must be"); } else if (op->code() == lir_cas_int) { casw(addr, newval, cmpval); } else { diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.cpp Mon May 06 16:07:41 2019 -0400 @@ -236,22 +236,3 @@ void BarrierSetAssembler::resolve_for_write(MacroAssembler* masm, DecoratorSet decorators, Register obj) { // Default to no-op. } - -void BarrierSetAssembler::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, - Register result) { - 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); - } -} diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetAssembler_aarch64.hpp Mon May 06 16:07:41 2019 -0400 @@ -71,11 +71,6 @@ virtual void resolve_for_read(MacroAssembler* masm, DecoratorSet decorators, Register obj); virtual void resolve_for_write(MacroAssembler* masm, DecoratorSet decorators, Register obj); - virtual 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); - virtual void barrier_stubs_init() {} }; diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.cpp Mon May 06 16:07:41 2019 -0400 @@ -426,34 +426,14 @@ } 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) { - BarrierSetAssembler::cmpxchg_oop(masm, addr, expected, new_val, acquire, release, weak, encode, - tmp1, tmp2, tmp3, result); - 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; @@ -466,35 +446,38 @@ __ 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 diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp Mon May 06 16:07:41 2019 -0400 @@ -27,8 +27,11 @@ #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSetAssembler.hpp" #ifdef COMPILER1 -#include "c1/c1_LIRAssembler.hpp" -#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp" +class LIR_Assembler; +class ShenandoahPreBarrierStub; +class ShenandoahWriteBarrierStub; +class StubAssembler; +class StubCodeGenerator; #endif class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { @@ -58,7 +61,6 @@ 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, bool c_abi, bool do_cset_test); @@ -69,6 +71,8 @@ static bool is_shenandoah_wb_C_call(address call); + 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); @@ -95,9 +99,7 @@ virtual void resolve_for_write(MacroAssembler* masm, DecoratorSet decorators, Register obj); virtual 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, - Register result); + bool acquire, bool release, bool weak, bool is_cae, Register result); virtual void barrier_stubs_init(); }; diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetC1_aarch64.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoahBarrierSetC1_aarch64.cpp Mon May 06 16:07:41 2019 -0400 @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. All rights reserved. + * + * 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 "precompiled.hpp" +#include "c1/c1_LIRAssembler.hpp" +#include "c1/c1_MacroAssembler.hpp" +#include "gc/shenandoah/shenandoahBarrierSet.hpp" +#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(); + + 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 +#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 (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)); + 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(); + + if (access.is_oop()) { + value_opr = storeval_barrier(access, value_opr, access.access_emit_info(), true); + } + + assert(type == T_INT || type == T_OBJECT || type == T_ARRAY LP64_ONLY( || type == T_LONG ), "unexpected type"); + LIR_Opr tmp = gen->new_register(T_INT); + __ xchg(access.resolved_addr(), value_opr, result, tmp); + + return result; +} diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp Mon May 06 16:07:41 2019 -0400 @@ -2399,14 +2399,6 @@ } -void MacroAssembler::cmpxchg_oop(Register addr, Register expected, Register new_val, - bool acquire, bool release, bool weak, bool encode, - Register tmp1, Register tmp2, - Register tmp3, Register result) { - BarrierSetAssembler* bsa = BarrierSet::barrier_set()->barrier_set_assembler(); - bsa->cmpxchg_oop(this, addr, expected, new_val, acquire, release, weak, encode, tmp1, tmp2, tmp3, result); -} - static bool different(Register a, RegisterOrConstant b, Register c) { if (b.is_constant()) return a != c; diff -r f5c9d4ff794a src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp Mon May 06 16:07:41 2019 -0400 @@ -1021,11 +1021,6 @@ bool acquire, bool release, bool weak, Register result); - void cmpxchg_oop(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); - private: void compare_eq(Register rn, Register rm, enum operand_size size); diff -r f5c9d4ff794a src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Mon May 06 16:07:41 2019 -0400 @@ -1925,10 +1925,21 @@ assert(newval != addr, "new value and addr must be in different registers"); if ( op->code() == lir_cas_obj) { - Register tmp1 = op->tmp1()->as_register(); - Register tmp2 = op->tmp2()->as_register(); - __ cmpxchg_oop(NULL, Address(addr, 0), cmpval, newval, true, true, tmp1, tmp2); - } else { +#ifdef _LP64 + if (UseCompressedOops) { + __ encode_heap_oop(cmpval); + __ mov(rscratch1, newval); + __ encode_heap_oop(rscratch1); + __ lock(); + // cmpval (rax) is implicitly used by this instruction + __ cmpxchgl(rscratch1, Address(addr, 0)); + } else +#endif + { + __ lock(); + __ cmpxchgptr(newval, Address(addr, 0)); + } + } else { assert(op->code() == lir_cas_int, "lir_cas_int expected"); if (os::is_MP()) { __ lock(); @@ -3990,8 +4001,17 @@ } else if (data->is_oop()) { assert (code == lir_xchg, "xadd for oops"); Register obj = data->as_register(); - assert (tmp->is_register(), "should be register"); - __ xchg_oop(obj, as_Address(src->as_address_ptr()), tmp->as_register()); +#ifdef _LP64 + if (UseCompressedOops) { + __ encode_heap_oop(obj); + __ xchgl(obj, as_Address(src->as_address_ptr())); + __ decode_heap_oop(obj); + } else { + __ xchgptr(obj, as_Address(src->as_address_ptr())); + } +#else + __ xchgl(obj, as_Address(src->as_address_ptr())); +#endif } else if (data->type() == T_LONG) { #ifdef _LP64 assert(data->as_register_lo() == data->as_register_hi(), "should be a single register"); diff -r f5c9d4ff794a src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp Mon May 06 16:07:41 2019 -0400 @@ -330,50 +330,3 @@ void BarrierSetAssembler::resolve_for_write(MacroAssembler* masm, DecoratorSet decorators, Register obj) { // Default to no-op } - -void BarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, DecoratorSet decorators, - Register res, Address addr, Register cmpval, Register newval, - bool exchange, bool encode, Register tmp1, Register tmp2) { -#ifdef _LP64 - if (UseCompressedOops) { - if (encode) { - __ encode_heap_oop(cmpval); - __ mov(rscratch1, newval); - __ encode_heap_oop(rscratch1); - newval = rscratch1; - } - if (os::is_MP()) { - __ lock(); - } - // cmpval (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); - } -} - -void BarrierSetAssembler::xchg_oop(MacroAssembler* masm, DecoratorSet decorators, - Register obj, Address addr, Register tmp) { -#ifdef _LP64 - if (UseCompressedOops) { - __ encode_heap_oop(obj); - __ xchgl(obj, addr); - __ decode_heap_oop(obj); - } else { - __ xchgptr(obj, addr); - } -#else - __ xchgl(obj, addr); -#endif -} diff -r f5c9d4ff794a src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp --- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp Mon May 06 16:07:41 2019 -0400 @@ -81,12 +81,6 @@ virtual void resolve_for_read(MacroAssembler* masm, DecoratorSet decorators, Register obj); virtual void resolve_for_write(MacroAssembler* masm, DecoratorSet decorators, Register obj); - virtual void cmpxchg_oop(MacroAssembler* masm, DecoratorSet decorators, - Register res, Address addr, Register oldval, Register newval, - bool exchange, bool encode, Register tmp1, Register tmp2); - virtual void xchg_oop(MacroAssembler* masm, DecoratorSet decorators, - Register obj, Address addr, Register tmp); - virtual void barrier_stubs_init() {} }; diff -r f5c9d4ff794a src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp Mon May 06 16:07:41 2019 -0400 @@ -591,41 +591,21 @@ // Special Shenandoah CAS implementation that handles false negatives // due to concurrent evacuation. #ifndef _LP64 -void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, DecoratorSet decorators, +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, DecoratorSet decorators, +void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm, Register res, Address addr, Register oldval, Register newval, - bool exchange, bool encode, Register tmp1, Register tmp2) { - - if (!ShenandoahCASBarrier) { - BarrierSetAssembler::cmpxchg_oop(masm, decorators, res, addr, oldval, newval, exchange, encode, tmp1, tmp2); - 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); @@ -704,12 +684,6 @@ } #endif // LP64 -void ShenandoahBarrierSetAssembler::xchg_oop(MacroAssembler* masm, DecoratorSet decorators, - Register obj, Address addr, Register tmp) { - storeval_barrier(masm, obj, tmp); - BarrierSetAssembler::xchg_oop(masm, decorators, obj, addr, tmp); -} - void ShenandoahBarrierSetAssembler::save_vector_registers(MacroAssembler* masm) { int num_xmm_regs = LP64_ONLY(16) NOT_LP64(8); if (UseAVX > 2) { diff -r f5c9d4ff794a src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp --- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp Mon May 06 16:07:41 2019 -0400 @@ -27,8 +27,11 @@ #include "asm/macroAssembler.hpp" #include "gc/shared/barrierSetAssembler.hpp" #ifdef COMPILER1 -#include "c1/c1_LIRAssembler.hpp" -#include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp" +class LIR_Assembler; +class ShenandoahPreBarrierStub; +class ShenandoahWriteBarrierStub; +class StubAssembler; +class StubCodeGenerator; #endif class ShenandoahBarrierSetAssembler: public BarrierSetAssembler { @@ -62,7 +65,6 @@ 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, bool c_abi, bool do_cset_test); @@ -76,18 +78,16 @@ static bool is_shenandoah_wb_C_call(address call); + 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); void generate_c1_pre_barrier_runtime_stub(StubAssembler* sasm); #endif - virtual void cmpxchg_oop(MacroAssembler* masm, DecoratorSet decorators, + virtual void cmpxchg_oop(MacroAssembler* masm, Register res, Address addr, Register oldval, Register newval, - bool exchange, bool encode, Register tmp1, Register tmp2); - virtual void xchg_oop(MacroAssembler* masm, DecoratorSet decorators, - Register obj, Address addr, Register tmp); - + 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, diff -r f5c9d4ff794a src/hotspot/cpu/x86/macroAssembler_x86.cpp --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Mon May 06 16:07:41 2019 -0400 @@ -3738,17 +3738,6 @@ movl(as_Address(ArrayAddress(page, index)), tmp); } -void MacroAssembler::cmpxchg_oop(Register res, Address addr, Register cmpval, Register newval, - bool exchange, bool encode, Register tmp1, Register tmp2) { - BarrierSetAssembler* bsa = BarrierSet::barrier_set()->barrier_set_assembler(); - bsa->cmpxchg_oop(this, IN_HEAP, res, addr, cmpval, newval, exchange, encode, tmp1, tmp2); -} - -void MacroAssembler::xchg_oop(Register obj, Address addr, Register tmp) { - BarrierSetAssembler* bsa = BarrierSet::barrier_set()->barrier_set_assembler(); - bsa->xchg_oop(this, IN_HEAP, obj, addr, tmp); -} - void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg) { if (SafepointMechanism::uses_thread_local_poll()) { #ifdef _LP64 diff -r f5c9d4ff794a src/hotspot/cpu/x86/macroAssembler_x86.hpp --- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp Mon May 06 16:07:41 2019 -0400 @@ -769,11 +769,6 @@ void cmpxchgptr(Register reg, Address adr); - void cmpxchg_oop(Register res, Address addr, Register oldval, Register newval, - bool exchange, bool encode, Register tmp1, Register tmp2); - - void xchg_oop(Register obj, Address addr, Register tmp); - void locked_cmpxchgptr(Register reg, AddressLiteral adr); diff -r f5c9d4ff794a src/hotspot/cpu/x86/x86_64.ad --- a/src/hotspot/cpu/x86/x86_64.ad Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/cpu/x86/x86_64.ad Mon May 06 16:07:41 2019 -0400 @@ -544,6 +544,7 @@ #endif #if INCLUDE_SHENANDOAHGC #include "gc/shenandoah/shenandoahBrooksPointer.hpp" +#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" #endif %} @@ -7616,7 +7617,7 @@ rax_RegP oldval, rRegP newval, rFlagsReg cr) %{ - predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); + predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); @@ -7642,7 +7643,7 @@ rax_RegP oldval, rRegP newval, rFlagsReg cr) %{ - predicate(VM_Version::supports_cx8() && UseShenandoahGC && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); + predicate(VM_Version::supports_cx8() && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval))); effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); @@ -7650,9 +7651,9 @@ format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} ins_encode %{ - __ cmpxchg_oop($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + 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 ); @@ -7760,7 +7761,7 @@ memory mem_ptr, rax_RegN oldval, rRegN newval, rFlagsReg cr) %{ - predicate(!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); + predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); effect(KILL cr, KILL oldval); @@ -7785,7 +7786,7 @@ rRegP tmp1, rRegP tmp2, rax_RegN oldval, rRegN newval, rFlagsReg cr) %{ - predicate(UseShenandoahGC && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); + predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval))); effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); @@ -7793,9 +7794,9 @@ format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} ins_encode %{ - __ cmpxchg_oop($res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + 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 ); @@ -7883,7 +7884,7 @@ memory mem_ptr, rax_RegN oldval, rRegN newval, rFlagsReg cr) %{ - predicate(!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); + predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); effect(KILL cr); @@ -7902,16 +7903,16 @@ rax_RegN oldval, rRegN newval, rRegP tmp1, rRegP tmp2, rFlagsReg cr) %{ - predicate(UseShenandoahGC && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); + predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval))); effect(TEMP tmp1, TEMP tmp2, KILL cr); format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} ins_encode %{ - __ cmpxchg_oop(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + 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 ); @@ -7922,7 +7923,7 @@ rax_RegP oldval, rRegP newval, rFlagsReg cr) %{ - predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); + predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); effect(KILL cr); @@ -7942,7 +7943,7 @@ rRegP tmp1, rRegP tmp2, rFlagsReg cr) %{ - predicate(VM_Version::supports_cx8() && UseShenandoahGC && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); + predicate(VM_Version::supports_cx8() && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval))); effect(KILL cr, TEMP tmp1, TEMP tmp2); ins_cost(1000); @@ -7950,9 +7951,9 @@ format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} ins_encode %{ - __ cmpxchg_oop(NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, + 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 ); diff -r f5c9d4ff794a src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp --- a/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/c1/shenandoahBarrierSetC1.hpp Mon May 06 16:07:41 2019 -0400 @@ -117,6 +117,64 @@ #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, NULL) // 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) { + assert(_addr->is_valid(), "used"); + assert(_cmp_value->is_valid(), "used"); + assert(_new_value->is_valid(), "used"); + if (_info) state->do_info(_info); + state->do_input(_addr); + state->do_temp(_addr); + state->do_input(_cmp_value); + state->do_temp(_cmp_value); + 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; @@ -137,8 +195,10 @@ virtual void store_at(LIRAccess& access, LIR_Opr value); virtual void load_at(LIRAccess& access, LIR_Opr result); + virtual LIR_Opr atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value); + virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value); + virtual LIR_Opr atomic_cmpxchg_at(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value); - virtual LIR_Opr atomic_xchg_at(LIRAccess& access, LIRItem& value); virtual LIR_Opr atomic_add_at(LIRAccess& access, LIRItem& value); diff -r f5c9d4ff794a src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.cpp Mon May 06 16:07:41 2019 -0400 @@ -80,6 +80,11 @@ { } +ShenandoahBarrierSetAssembler* ShenandoahBarrierSet::assembler() { + BarrierSetAssembler* const bsa = BarrierSet::barrier_set()->barrier_set_assembler(); + return reinterpret_cast(bsa); +} + void ShenandoahBarrierSet::print_on(outputStream* st) const { st->print("ShenandoahBarrierSet"); } diff -r f5c9d4ff794a src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Fri May 03 16:42:40 2019 +0200 +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Mon May 06 16:07:41 2019 -0400 @@ -29,6 +29,8 @@ #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahSATBMarkQueueSet.hpp" +class ShenandoahBarrierSetAssembler; + class ShenandoahBarrierSet: public BarrierSet { private: enum ArrayCopyStoreValMode { @@ -44,6 +46,8 @@ public: ShenandoahBarrierSet(ShenandoahHeap* heap); + static ShenandoahBarrierSetAssembler* assembler(); + inline static ShenandoahBarrierSet* barrier_set() { return barrier_set_cast(BarrierSet::barrier_set()); }