< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page

        

*** 925,934 **** --- 925,937 ---- // definitions necessary in the rest of the architecture description source_hpp %{ #include "opto/addnode.hpp" + #if INCLUDE_ALL_GCS + #include "shenandoahBarrierSetAssembler_aarch64.hpp" + #endif class CallStubImpl { //-------------------------------------------------------------- //---< Used for optimization in Compile::shorten_branches >---
*** 2796,2805 **** --- 2799,2817 ---- __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, Assembler::word, /*acquire*/ false, /*release*/ true); %} + 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. + ShenandoahBarrierSetAssembler::bsasm()->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 // aarch64_enc_cmpxchg_acq is that we use load-acquire in the // CompareAndSwap sequence to serve as a barrier on acquiring a // lock. enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
*** 2814,2823 **** --- 2826,2845 ---- guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register, Assembler::word, /*acquire*/ true, /*release*/ true); %} + 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. + ShenandoahBarrierSetAssembler::bsasm()->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 enc_class aarch64_enc_cset_eq(iRegINoSp res) %{ MacroAssembler _masm(&cbuf); Register res_reg = as_Register($res$$reg); __ cset(res_reg, Assembler::EQ);
*** 4212,4223 **** // Card Table Byte Map Base operand immByteMapBase() %{ // Get base of card map ! predicate((jbyte*)n->get_ptr() == ! ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); match(ConP); op_cost(0); format %{ %} interface(CONST_INTER); --- 4234,4245 ---- // Card Table Byte Map Base operand immByteMapBase() %{ // Get base of card map ! predicate(!UseShenandoahGC && // TODO: Should really check for BS::is_a, see JDK-8193193 ! (jbyte*)n->get_ptr() == ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base); match(ConP); op_cost(0); format %{ %} interface(CONST_INTER);
*** 6937,6947 **** predicate(!needs_releasing_store(n)); ins_cost(INSN_COST); format %{ "str $src, $mem\t# ptr" %} ! ins_encode(aarch64_enc_str(src, mem)); ins_pipe(istore_reg_mem); %} // Store Pointer --- 6959,7015 ---- predicate(!needs_releasing_store(n)); ins_cost(INSN_COST); format %{ "str $src, $mem\t# ptr" %} ! ins_encode %{ ! int opcode = $mem->opcode(); ! Register base = as_Register($mem$$base); ! int index = $mem$$index; ! int size = $mem$$scale; ! int disp = $mem$$disp; ! Register reg = as_Register($src$$reg); ! ! // we sometimes get asked to store the stack pointer into the ! // current thread -- we cannot do that directly on AArch64 ! if (reg == r31_sp) { ! MacroAssembler _masm(&cbuf); ! assert(as_Register($mem$$base) == rthread, "unexpected store for sp"); ! __ mov(rscratch2, sp); ! reg = rscratch2; ! } ! Address::extend scale; ! ! // Hooboy, this is fugly. We need a way to communicate to the ! // encoder that the index needs to be sign extended, so we have to ! // enumerate all the cases. ! switch (opcode) { ! case INDINDEXSCALEDOFFSETI2L: ! case INDINDEXSCALEDI2L: ! case INDINDEXSCALEDOFFSETI2LN: ! case INDINDEXSCALEDI2LN: ! case INDINDEXOFFSETI2L: ! case INDINDEXOFFSETI2LN: ! scale = Address::sxtw(size); ! break; ! default: ! scale = Address::lsl(size); ! } ! Address adr; ! if (index == -1) { ! adr = Address(base, disp); ! } else { ! if (disp == 0) { ! adr = Address(base, as_Register(index), scale); ! } else { ! __ lea(rscratch1, Address(base, disp)); ! adr = Address(rscratch1, as_Register(index), scale); ! } ! } ! ! __ str(reg, adr); ! %} ins_pipe(istore_reg_mem); %} // Store Pointer
*** 8061,8070 **** --- 8129,8139 ---- ins_pipe(pipe_slow); %} instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ + predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR); match(Set res (CompareAndSwapP mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); effect(KILL cr);
*** 8077,8088 **** --- 8146,8175 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + + predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); + match(Set res (CompareAndSwapP mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchg_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + %} + + ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res)); + + ins_pipe(pipe_slow); + %} + instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ + predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR); match(Set res (CompareAndSwapN mem (Binary oldval newval))); ins_cost(2 * VOLATILE_REF_COST); effect(KILL cr);
*** 8095,8104 **** --- 8182,8211 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + + predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); + match(Set res (CompareAndSwapN mem (Binary oldval newval))); + ins_cost(2 * VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); + %} + + ins_pipe(pipe_slow); + %} // alternative CompareAndSwapX when we are eliding barriers instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
*** 8138,8148 **** ins_pipe(pipe_slow); %} instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ ! predicate(needs_acquiring_load_exclusive(n)); match(Set res (CompareAndSwapP mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(KILL cr); --- 8245,8255 ---- ins_pipe(pipe_slow); %} instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{ ! predicate(needs_acquiring_load_exclusive(n) && (!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR)); match(Set res (CompareAndSwapP mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(KILL cr);
*** 8155,8167 **** aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ ! predicate(needs_acquiring_load_exclusive(n)); match(Set res (CompareAndSwapN mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(KILL cr); --- 8262,8291 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ + + predicate(needs_acquiring_load_exclusive(n) && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); + match(Set res (CompareAndSwapP mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + %} + + ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res)); + + ins_pipe(pipe_slow); + %} + instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{ ! predicate(needs_acquiring_load_exclusive(n) && (!UseShenandoahGC || !ShenandoahCASBarrier|| n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR)); match(Set res (CompareAndSwapN mem (Binary oldval newval))); ins_cost(VOLATILE_REF_COST); effect(KILL cr);
*** 8174,8183 **** --- 8298,8327 ---- aarch64_enc_cset_eq(res)); ins_pipe(pipe_slow); %} + instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ + + predicate(needs_acquiring_load_exclusive(n) && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR); + match(Set res (CompareAndSwapN mem (Binary oldval newval))); + ins_cost(VOLATILE_REF_COST); + + effect(TEMP tmp, KILL cr); + + format %{ + "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); + %} + + ins_pipe(pipe_slow); + %} instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ match(Set prev (GetAndSetI mem newv)); ins_cost(2 * VOLATILE_REF_COST); format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
< prev index next >