< prev index next >

src/hotspot/cpu/x86/x86_64.ad

Print this page

        

@@ -1,7 +1,7 @@
 //
-// Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2003, 2018, Oracle and/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.

@@ -540,10 +540,20 @@
 
 source_hpp %{
 #if INCLUDE_ZGC
 #include "gc/z/zBarrierSetAssembler.hpp"
 #endif
+#if INCLUDE_SHENANDOAHGC
+#include "gc/shenandoah/shenandoahBrooksPointer.hpp"
+#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
+#else
+// This is normally available through shenandoah_globals.hpp, but if Shenandoah
+// compilation is disabled, there is no such header. Fake the constants for predicates
+// to work. This workaround would be removed as we backport more stuff, including
+// the split shenandoah_x86_64.ad.
+#define ShenandoahCASBarrier false
+#endif
 %}
 
 //----------SOURCE BLOCK-------------------------------------------------------
 // This is a block of C++ code which provides values, functions, and
 // definitions necessary in the rest of the architecture description

@@ -6709,10 +6719,63 @@
     __ movl($dst$$Register, $src$$Register);
   %}
   ins_pipe(ialu_reg_reg); // XXX
 %}
 
+instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{
+  match(Set dst (ShenandoahReadBarrier src));
+  effect(DEF dst, USE src);
+  ins_cost(125); // XXX
+  format %{ "shenandoah_rb $dst, $src" %}
+  ins_encode %{
+#if INCLUDE_SHENANDOAHGC
+    Register d = $dst$$Register;
+    Register s = $src$$Register;
+    __ movptr(d, Address(s, ShenandoahBrooksPointer::byte_offset()));
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{
+  predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0));
+  match(Set dst (ShenandoahReadBarrier (DecodeN src)));
+  effect(DEF dst, USE src);
+  ins_cost(125); // XXX
+  format %{ "shenandoah_rb $dst, $src" %}
+  ins_encode %{
+#if INCLUDE_SHENANDOAHGC
+    Register d = $dst$$Register;
+    Register s = $src$$Register;
+    __ movptr(d, Address(r12, s, Address::times_1, ShenandoahBrooksPointer::byte_offset()));
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{
+  predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
+  match(Set dst (ShenandoahReadBarrier (DecodeN src)));
+  effect(DEF dst, USE src);
+  ins_cost(125); // XXX
+  format %{ "shenandoah_rb $dst, $src" %}
+  ins_encode %{
+#if INCLUDE_SHENANDOAHGC
+    Register d = $dst$$Register;
+    Register s = $src$$Register;
+    __ movptr(d, Address(r12, s, Address::times_8, ShenandoahBrooksPointer::byte_offset()));
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
 // Convert oop pointer into compressed form
 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
   match(Set dst (EncodeP src));
   effect(KILL cr);

@@ -7558,11 +7621,11 @@
 instruct compareAndSwapP(rRegI res,
                          memory mem_ptr,
                          rax_RegP oldval, rRegP newval,
                          rFlagsReg cr)
 %{
-  predicate(VM_Version::supports_cx8());
+  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);
 
   format %{ "cmpxchgq $mem_ptr,$newval\t# "

@@ -7578,10 +7641,36 @@
              REX_reg_breg(res, res), // movzbl
              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
   ins_pipe( pipe_cmpxchg );
 %}
 
+instruct compareAndSwapP_shenandoah(rRegI res,
+                                    memory mem_ptr,
+                                    rRegP tmp1, rRegP tmp2,
+                                    rax_RegP oldval, rRegP newval,
+                                    rFlagsReg cr)
+%{
+  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);
+
+  format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
+
+  ins_encode %{
+#if INCLUDE_SHENANDOAHGC
+    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
+            false, // swap
+            $tmp1$$Register, $tmp2$$Register
+    );
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
 instruct compareAndSwapL(rRegI res,
                          memory mem_ptr,
                          rax_RegL oldval, rRegL newval,
                          rFlagsReg cr)
 %{

@@ -7680,10 +7769,11 @@
 
 instruct compareAndSwapN(rRegI res,
                           memory mem_ptr,
                           rax_RegN oldval, rRegN newval,
                           rFlagsReg cr) %{
+  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);
 
   format %{ "cmpxchgl $mem_ptr,$newval\t# "

@@ -7699,10 +7789,35 @@
              REX_reg_breg(res, res), // movzbl
              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
   ins_pipe( pipe_cmpxchg );
 %}
 
+instruct compareAndSwapN_shenandoah(rRegI res,
+                                    memory mem_ptr,
+                                    rRegP tmp1, rRegP tmp2,
+                                    rax_RegN oldval, rRegN newval,
+                                    rFlagsReg cr) %{
+  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);
+
+  format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
+
+  ins_encode %{
+#if INCLUDE_SHENANDOAHGC
+    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
+            false, // swap
+            $tmp1$$Register, $tmp2$$Register
+    );
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
 instruct compareAndExchangeB(
                          memory mem_ptr,
                          rax_RegI oldval, rRegI newval,
                          rFlagsReg cr)
 %{

@@ -7781,10 +7896,11 @@
 
 instruct compareAndExchangeN(
                           memory mem_ptr,
                           rax_RegN oldval, rRegN newval,
                           rFlagsReg cr) %{
+  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);
 
   format %{ "cmpxchgl $mem_ptr,$newval\t# "
             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}

@@ -7795,16 +7911,39 @@
              reg_mem(newval, mem_ptr)  // lock cmpxchg
           );
   ins_pipe( pipe_cmpxchg );
 %}
 
+instruct compareAndExchangeN_shenandoah(memory mem_ptr,
+                                        rax_RegN oldval, rRegN newval,
+                                        rRegP tmp1, rRegP tmp2,
+                                        rFlagsReg cr) %{
+  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 %{
+#if INCLUDE_SHENANDOAHGC
+    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
+            true, // exchange
+            $tmp1$$Register, $tmp2$$Register
+    );
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
 instruct compareAndExchangeP(
                          memory mem_ptr,
                          rax_RegP oldval, rRegP newval,
                          rFlagsReg cr)
 %{
-  predicate(VM_Version::supports_cx8());
+  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);
 
   format %{ "cmpxchgq $mem_ptr,$newval\t# "
             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}

@@ -7815,10 +7954,35 @@
              reg_mem(newval, mem_ptr)  // lock cmpxchg
           );
   ins_pipe( pipe_cmpxchg );
 %}
 
+instruct compareAndExchangeP_shenandoah(memory mem_ptr,
+                                        rax_RegP oldval, rRegP newval,
+                                        rRegP tmp1, rRegP tmp2,
+                                        rFlagsReg cr)
+%{
+  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);
+
+  format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
+
+  ins_encode %{
+#if INCLUDE_SHENANDOAHGC
+    ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
+            true,  // exchange
+            $tmp1$$Register, $tmp2$$Register
+    );
+#else
+    ShouldNotReachHere();
+#endif
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
   predicate(n->as_LoadStore()->result_not_used());
   match(Set dummy (GetAndAddB mem add));
   effect(KILL cr);
   format %{ "ADDB  [$mem],$add" %}
< prev index next >