< prev index next >

src/hotspot/cpu/x86/gc/shenandoah/shenandoah_x86_64.ad

Print this page
*** 20,92 ***
  // or visit www.oracle.com if you need additional information or have any
  // questions.
  //
  //
  
! source_hpp %{
! #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
! #include "gc/shenandoah/c2/shenandoahSupport.hpp"
  %}
  
  instruct compareAndSwapP_shenandoah(rRegI res,
!                                     memory mem_ptr,
                                      rRegP tmp1, rRegP tmp2,
                                      rax_RegP oldval, rRegP newval,
                                      rFlagsReg cr)
  %{
!   match(Set res (ShenandoahCompareAndSwapP mem_ptr (Binary oldval newval)));
!   match(Set res (ShenandoahWeakCompareAndSwapP mem_ptr (Binary oldval newval)));
!   effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
  
!   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
  
    ins_encode %{
!     ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm,
!                                                    $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
!                                                    false, // swap
!                                                    $tmp1$$Register, $tmp2$$Register
!                                                    );
    %}
    ins_pipe( pipe_cmpxchg );
  %}
  
  instruct compareAndSwapN_shenandoah(rRegI res,
!                                     memory mem_ptr,
                                      rRegP tmp1, rRegP tmp2,
                                      rax_RegN oldval, rRegN newval,
                                      rFlagsReg cr) %{
!   match(Set res (ShenandoahCompareAndSwapN mem_ptr (Binary oldval newval)));
!   match(Set res (ShenandoahWeakCompareAndSwapN mem_ptr (Binary oldval newval)));
!   effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
  
!   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
  
    ins_encode %{
!     ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm,
!                                                    $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
!                                                    false, // swap
!                                                    $tmp1$$Register, $tmp2$$Register
!                                                    );
    %}
    ins_pipe( pipe_cmpxchg );
  %}
  
! instruct compareAndExchangeN_shenandoah(memory mem_ptr,
                                          rax_RegN oldval, rRegN newval,
!                                         rRegP tmp1, rRegP tmp2,
                                          rFlagsReg cr) %{
!   match(Set oldval (ShenandoahCompareAndExchangeN mem_ptr (Binary oldval newval)));
!   effect(TEMP tmp1, TEMP tmp2, KILL cr);
  
!   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
  
    ins_encode %{
!     ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm,
!                                                    noreg, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
!                                                    true, // exchange
!                                                    $tmp1$$Register, $tmp2$$Register
!                                                    );
    %}
    ins_pipe( pipe_cmpxchg );
  %}
  
! instruct compareAndExchangeP_shenandoah(memory mem_ptr,
                                          rax_RegP oldval, rRegP newval,
                                          rRegP tmp1, rRegP tmp2,
                                          rFlagsReg cr)
  %{
!   match(Set oldval (ShenandoahCompareAndExchangeP mem_ptr (Binary oldval newval)));
    effect(KILL cr, TEMP tmp1, TEMP tmp2);
    ins_cost(1000);
  
!   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
  
    ins_encode %{
!     ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm,
!                                                    noreg, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
!                                                    true,  // exchange
!                                                    $tmp1$$Register, $tmp2$$Register
!                                                    );
    %}
    ins_pipe( pipe_cmpxchg );
  %}
--- 20,381 ---
  // or visit www.oracle.com if you need additional information or have any
  // questions.
  //
  //
  
! source %{
! #include "gc/shenandoah/shenandoahBarrierSet.hpp"
! #include "gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp"
+ #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
  %}
  
+ // ---------------------------------- LOADS ---------------------------------------
+ //
+ 
+ instruct loadP_shenandoah(rRegP dst, memory mem, rRegP tmp, rFlagsReg cr)
+ %{
+   match(Set dst (LoadP mem));
+   predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0);
+   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
+   // The main load is a candidate to implement implicit null checks.
+   ins_is_late_expanded_null_check_candidate(true);
+   format %{ "movq    $dst, $mem\t# ptr" %}
+   ins_encode %{
+     ShenandoahBarrierSet::assembler()->load_c2(this, masm,
+       $dst$$Register,
+       $mem$$Address,
+       /* narrow = */ false,
+       $tmp$$Register
+     );
+   %}
+   ins_cost(125);
+   ins_pipe(ialu_reg_mem);
+ %}
+ 
+ instruct loadN_shenandoah(rRegN dst, memory mem, rRegP tmp, rFlagsReg cr)
+ %{
+   match(Set dst (LoadN mem));
+   predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0);
+   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
+   // The main load is a candidate to implement implicit null checks.
+   ins_is_late_expanded_null_check_candidate(true);
+   format %{ "movl    $dst, $mem\t# compressed ptr" %}
+   ins_encode %{
+     ShenandoahBarrierSet::assembler()->load_c2(this, masm,
+       $dst$$Register,
+       $mem$$Address,
+       /* narrow = */ true,
+       $tmp$$Register
+     );
+   %}
+   ins_cost(125);
+   ins_pipe(ialu_reg_mem);
+ %}
+ 
+ // ---------------------------- LOAD SPECIALIZATIONS ------------------------
+ // These rules match x86.ad match rules with barrier_data() == 0.
+ // For these cases, Shenandoah does not care about applying the GC barriers:
+ // this applies to everywhere we do not expose the untreated oop to the rest
+ // of the system.
+ //
+ 
+ instruct testP_mem_shenandoah(rFlagsReg cr, memory op, immP0 zero)
+ %{
+   predicate((!UseCompressedOops || (CompressedOops::base() != nullptr)) &&
+             UseShenandoahGC && n->in(1)->as_Load()->barrier_data() != 0);
+   match(Set cr (CmpP (LoadP op) zero));
+ 
+   ins_cost(500); // XXX
+   format %{ "testq   $op, 0xffffffffffffffff\t# ptr" %}
+   ins_encode %{
+     __ testq($op$$Address, 0xFFFFFFFF);
+   %}
+   ins_pipe(ialu_cr_reg_imm);
+ %}
+ 
+ instruct testP_mem_reg0_shenandoah(rFlagsReg cr, memory mem, immP0 zero)
+ %{
+   predicate(UseCompressedOops && (CompressedOops::base() == nullptr) &&
+             UseShenandoahGC && n->in(1)->as_Load()->barrier_data() != 0);
+   match(Set cr (CmpP (LoadP mem) zero));
+ 
+   format %{ "cmpq    R12, $mem\t# ptr (R12_heapbase==0)" %}
+   ins_encode %{
+     __ cmpq(r12, $mem$$Address);
+   %}
+   ins_pipe(ialu_cr_reg_mem);
+ %}
+ 
+ instruct compN_rReg_mem_shenandoah(rFlagsRegU cr, rRegN src, memory mem)
+ %{
+   predicate(UseShenandoahGC && n->in(2)->as_Load()->barrier_data() != 0);
+   match(Set cr (CmpN src (LoadN mem)));
+ 
+   format %{ "cmpl    $src, $mem\t# compressed ptr" %}
+   ins_encode %{
+     __ cmpl($src$$Register, $mem$$Address);
+   %}
+   ins_pipe(ialu_cr_reg_mem);
+ %}
+ 
+ instruct testN_mem_shenandoah(rFlagsReg cr, memory mem, immN0 zero)
+ %{
+   predicate(CompressedOops::base() != nullptr &&
+             UseShenandoahGC && n->in(1)->as_Load()->barrier_data() != 0);
+   match(Set cr (CmpN (LoadN mem) zero));
+ 
+   ins_cost(500); // XXX
+   format %{ "testl   $mem, 0xffffffff\t# compressed ptr" %}
+   ins_encode %{
+     __ cmpl($mem$$Address, (int)0xFFFFFFFF);
+   %}
+   ins_pipe(ialu_cr_reg_mem);
+ %}
+ 
+ instruct testN_mem_reg0_shenandoah(rFlagsReg cr, memory mem, immN0 zero)
+ %{
+   predicate(CompressedOops::base() == nullptr &&
+             UseShenandoahGC && n->in(1)->as_Load()->barrier_data() != 0);
+   match(Set cr (CmpN (LoadN mem) zero));
+ 
+   format %{ "cmpl    R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
+   ins_encode %{
+     __ cmpl(r12, $mem$$Address);
+   %}
+   ins_pipe(ialu_cr_reg_mem);
+ %}
+ 
+ // ---------------------------------- STORES ---------------------------------------
+ //
+ 
+ instruct storeP_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr)
+ %{
+   match(Set mem (StoreP mem src));
+   predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
+   effect(TEMP tmp, KILL cr);
+   ins_cost(125); // XXX
+   format %{ "movq    $mem, $src\t# ptr" %}
+   ins_encode %{
+     ShenandoahBarrierSet::assembler()->store_c2(this, masm,
+       $mem$$Address,  /* dst_narrow = */ false,
+       $src$$Register, /* src_narrow = */ false,
+       $tmp$$Register);
+   %}
+   ins_pipe(ialu_mem_reg);
+ %}
+ 
+ instruct storeN_shenandoah(memory mem, rRegN src, rRegP tmp, rFlagsReg cr)
+ %{
+   match(Set mem (StoreN mem src));
+   predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
+   effect(TEMP tmp, KILL cr);
+   ins_cost(125); // XXX
+   format %{ "movl    $mem, $src\t# ptr" %}
+   ins_encode %{
+     ShenandoahBarrierSet::assembler()->store_c2(this, masm,
+       $mem$$Address,  /* dst_narrow = */ true,
+       $src$$Register, /* src_narrow = */ true,
+       $tmp$$Register);
+   %}
+   ins_pipe(ialu_mem_reg);
+ %}
+ 
+ instruct encodePAndStoreN_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr)
+ %{
+   match(Set mem (StoreN mem (EncodeP src)));
+   predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
+   effect(TEMP tmp, KILL cr);
+   ins_cost(125); // XXX
+   format %{ "encode_heap_oop $src\n\t"
+             "movl   $mem, $src\t# ptr" %}
+   ins_encode %{
+     ShenandoahBarrierSet::assembler()->store_c2(this, masm, 
+       $mem$$Address,  /* dst_narrow = */ true,
+       $src$$Register, /* src_narrow = */ false,
+       $tmp$$Register);
+   %}
+   ins_pipe(ialu_mem_reg);
+ %}
+ 
+ // ---------------------------------- LOAD-STORES ---------------------------------------
+ //
+ 
  instruct compareAndSwapP_shenandoah(rRegI res,
!                                     indirect mem,
                                      rRegP tmp1, rRegP tmp2,
                                      rax_RegP oldval, rRegP newval,
                                      rFlagsReg cr)
  %{
!   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
!   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
!   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
+   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
  
!   format %{ "shenandoah_cas_oop $mem,$newval" %}
  
    ins_encode %{
!     guarantee(!UseCompressedOops, "must not be compressed oops");
!     if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) {
!       __ movptr($tmp1$$Register, $oldval$$Register);
!       ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
!                                                          noreg /* addr */,
+                                                          $tmp1$$Register /* pre_val */,
+                                                          $tmp2$$Register /* tmp */);
+     }
+     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
+                                                       $res$$Register, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register,
+                                                       /*exchange*/ false);
+     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
+                                                        $mem$$Register /* addr */,
+                                                        $tmp1$$Register /* addr_tmp */,
+                                                        $tmp2$$Register /* tmp */);
    %}
    ins_pipe( pipe_cmpxchg );
  %}
  
  instruct compareAndSwapN_shenandoah(rRegI res,
!                                     indirect mem,
                                      rRegP tmp1, rRegP tmp2,
                                      rax_RegN oldval, rRegN newval,
                                      rFlagsReg cr) %{
!   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
!   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
!   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
+   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
  
!   format %{ "shenandoah_cas_oop $mem,$newval" %}
  
    ins_encode %{
!     guarantee(UseCompressedOops, "must be compressed oops");
!     if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) {
!       __ movl($tmp1$$Register, $oldval$$Register);
!       __ decode_heap_oop($tmp1$$Register);
!       ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
+                                                          noreg /* addr */,
+                                                          $tmp1$$Register /* pre_val */,
+                                                          $tmp2$$Register /* tmp */);
+     }
+     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
+                                                       $res$$Register, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register,
+                                                       /*exchange*/ false);
+     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
+                                                        $mem$$Register /* addr */,
+                                                        $tmp1$$Register /* addr_tmp */,
+                                                        $tmp2$$Register /* tmp */);
    %}
    ins_pipe( pipe_cmpxchg );
  %}
  
! instruct compareAndExchangeN_shenandoah(indirect mem,
                                          rax_RegN oldval, rRegN newval,
!                                         rRegP tmp1, rRegP tmp2, rRegP tmp3,
                                          rFlagsReg cr) %{
!   match(Set oldval (CompareAndExchangeN mem (Binary oldval newval)));
!   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
+   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
  
!   format %{ "shenandoah_cas_oop $mem,$newval" %}
  
    ins_encode %{
!     guarantee(UseCompressedOops, "must be compressed oops");
!     if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) {
!       __ movl($tmp1$$Register, $oldval$$Register);
!       __ decode_heap_oop($tmp1$$Register);
!       ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
+                                                          noreg /* addr */,
+                                                          $tmp1$$Register /* pre_val */,
+                                                          $tmp2$$Register /* tmp */);
+     }
+     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
+                                                       noreg, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register,
+                                                       /*exchange*/ true);
+     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
+                                                            $oldval$$Register /* obj */,
+                                                            $mem$$Register /* addr */,
+                                                            $tmp1$$Register /* tmp1 */,
+                                                            $tmp2$$Register /* tmp2 */,
+                                                            $tmp3$$Register /* tmp3 */,
+                                                            true /* narrow */);
+     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
+                                                        $mem$$Register /* addr */,
+                                                        $tmp1$$Register /* addr_tmp */,
+                                                        $tmp2$$Register /* tmp */);
    %}
    ins_pipe( pipe_cmpxchg );
  %}
  
! instruct compareAndExchangeP_shenandoah(indirect mem,
                                          rax_RegP oldval, rRegP newval,
                                          rRegP tmp1, rRegP tmp2,
                                          rFlagsReg cr)
  %{
!   match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
+   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
    effect(KILL cr, TEMP tmp1, TEMP tmp2);
    ins_cost(1000);
  
!   format %{ "shenandoah_cas_oop $mem,$newval" %}
  
    ins_encode %{
!     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
!                                                        noreg /* addr */,
!                                                        $oldval$$Register /* pre_val */,
!                                                        $tmp2$$Register /* tmp */);
!     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
+                                                       noreg, $mem$$Address, $oldval$$Register, $newval$$Register, $tmp1$$Register, $tmp2$$Register,
+                                                       /*exchange*/ true);
+     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
+                                                            $oldval$$Register /* obj */,
+                                                            $mem$$Register /* addr */,
+                                                            noreg /* tmp1 */,
+                                                            $tmp1$$Register /* tmp2 */,
+                                                            $tmp2$$Register /* tmp3 */,
+                                                            false /* narrow */);
+     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
+                                                        $mem$$Register /* addr */,
+                                                        $tmp1$$Register /* addr_tmp */,
+                                                        $tmp2$$Register /* tmp */);
    %}
    ins_pipe( pipe_cmpxchg );
  %}
+ 
+ instruct getAndSetP_shenandoah(indirect mem, rRegP newval, rRegP tmp1, rRegP tmp2, rFlagsReg cr)
+ %{
+   match(Set newval (GetAndSetP mem newval));
+   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
+   effect(TEMP tmp1, TEMP tmp2, KILL cr);
+   format %{ "xchgq    $newval, $mem" %}
+   ins_encode %{
+     assert_different_registers($mem$$Register, $newval$$Register);
+     __ xchgq($newval$$Register, Address($mem$$Register, 0));
+     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
+                                                        noreg /* addr */,
+                                                        $newval$$Register /* pre_val */,
+                                                        $tmp1$$Register /* tmp */);
+     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
+                                                            $newval$$Register /* obj */,
+                                                            $mem$$Register /* addr */,
+                                                            noreg /* tmp1 */,
+                                                            $tmp1$$Register /* tmp2 */,
+                                                            $tmp2$$Register /* tmp3 */,
+                                                            false /* narrow */);
+     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
+                                                        $mem$$Register /* addr */,
+                                                        $tmp1$$Register /* addr_tmp */,
+                                                        $tmp2$$Register /* tmp */);
+   %}
+   ins_pipe(pipe_cmpxchg);
+ %}
+ 
+ instruct getAndSetN_shenandoah(indirect mem, rRegN newval, rRegP tmp1, rRegP tmp2, rRegP tmp3, rFlagsReg cr)
+ %{
+   match(Set newval (GetAndSetN mem newval));
+   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
+   effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, KILL cr);
+   format %{ "xchgq    $newval, $mem" %}
+   ins_encode %{
+     assert_different_registers($mem$$Register, $newval$$Register);
+     __ xchgl($newval$$Register, Address($mem$$Register, 0));
+     if (ShenandoahSATBBarrierStubC2::needs_barrier(this)) {
+       __ movl($tmp1$$Register, $newval$$Register);
+       __ decode_heap_oop($tmp1$$Register);
+       ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
+                                                          noreg /* addr */,
+                                                          $tmp1$$Register /* pre_val */,
+                                                          $tmp2$$Register /* tmp */);
+     }
+     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
+                                                            $newval$$Register /* obj */,
+                                                            $mem$$Register /* addr */,
+                                                            $tmp1$$Register /* tmp1 */,
+                                                            $tmp2$$Register /* tmp2 */,
+                                                            $tmp3$$Register /* tmp3 */,
+                                                            true /* narrow */);
+     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
+                                                        $mem$$Register /* addr */,
+                                                        $tmp1$$Register /* addr_tmp */,
+                                                        $tmp2$$Register /* tmp */);
+   %}
+   ins_pipe(pipe_cmpxchg);
+ %}
+ 
< prev index next >