< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page

        

*** 924,933 **** --- 924,935 ---- // This is a block of C++ code which provides values, functions, and // definitions necessary in the rest of the architecture description source_hpp %{ + #include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp" + class CallStubImpl { //-------------------------------------------------------------- //---< Used for optimization in Compile::shorten_branches >--- //--------------------------------------------------------------
*** 4266,4275 **** --- 4268,4286 ---- __ 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) %{ + 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_shenandoah($mem$$Register, tmp, $newval$$Register, + Assembler::xword, /*acquire*/ false, /*release*/ true, /*weak*/ false); + %} + // 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) %{
*** 4284,4293 **** --- 4295,4313 ---- 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) %{ + 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_shenandoah($mem$$Register, tmp, $newval$$Register, + Assembler::xword, /*acquire*/ true, /*release*/ true, /*weak*/ false); + %} + // 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);
*** 5732,5743 **** // 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); --- 5752,5763 ---- // 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);
*** 8437,8447 **** 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 --- 8457,8514 ---- 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
*** 9287,9296 **** --- 9354,9377 ---- %} ins_pipe(ialu_reg); %} + instruct shenandoahRB(iRegPNoSp dst, iRegP src, rFlagsReg cr) %{ + match(Set dst (ShenandoahReadBarrier src)); + format %{ "shenandoah_rb $dst,$src" %} + ins_encode %{ + #if INCLUDE_ALL_GCS + Register s = $src$$Register; + Register d = $dst$$Register; + __ ldr(d, Address(s, ShenandoahBrooksPointer::byte_offset())); + #else + ShouldNotReachHere(); + #endif + %} + ins_pipe(pipe_class_memory); + %} // Convert oop pointer into compressed form instruct encodeHeapOop(iRegNNoSp dst, iRegP src, rFlagsReg cr) %{ predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); match(Set dst (EncodeP src));
*** 9561,9570 **** --- 9642,9652 ---- 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);
*** 9577,9588 **** --- 9659,9690 ---- 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" + "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_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);
*** 9595,9604 **** --- 9697,9728 ---- 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" + "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, Assembler::word, /*acquire*/ false, /*release*/ true, /*weak*/ false); + __ cset($res$$Register, Assembler::EQ); + %} + + ins_pipe(pipe_slow); + %} // alternative CompareAndSwapX when we are eliding barriers instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
*** 9638,9648 **** 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); --- 9762,9772 ---- 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);
*** 9655,9667 **** 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); --- 9779,9810 ---- 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" + "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_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);
*** 9674,9683 **** --- 9817,9848 ---- 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" + "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" + %} + + ins_encode %{ + Register tmp = $tmp$$Register; + __ mov(tmp, $oldval$$Register); // Must not clobber oldval. + __ cmpxchg_oop_shenandoah($mem$$Register, tmp, $newval$$Register, Assembler::word, /*acquire*/ true, /*release*/ true, /*weak*/ false); + __ cset($res$$Register, Assembler::EQ); + %} + + ins_pipe(pipe_slow); + %} instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{ match(Set prev (GetAndSetI mem newv)); format %{ "atomic_xchgw $prev, $newv, [$mem]" %} ins_encode %{
< prev index next >