src/hotspot/cpu/sparc/stubGenerator_sparc.cpp
branchepsilon-gc-branch
changeset 56406 e629240491c7
parent 56348 f3b0961adb3c
parent 49484 ee8fa73b90f9
child 56448 76d86de267b9
--- a/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Mon Mar 26 17:27:47 2018 +0200
+++ b/src/hotspot/cpu/sparc/stubGenerator_sparc.cpp	Tue Apr 10 11:14:50 2018 +0200
@@ -24,8 +24,8 @@
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetAssembler.hpp"
 #include "interpreter/interpreter.hpp"
 #include "nativeInst_sparc.hpp"
 #include "oops/instanceOop.hpp"
@@ -823,127 +823,6 @@
       __ delayed()->nop();
   }
 
-  //
-  //  Generate pre-write barrier for array.
-  //
-  //  Input:
-  //     addr     - register containing starting address
-  //     count    - register containing element count
-  //     tmp      - scratch register
-  //
-  //  The input registers are overwritten.
-  //
-  void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) {
-    BarrierSet* bs = Universe::heap()->barrier_set();
-    switch (bs->kind()) {
-      case BarrierSet::G1BarrierSet:
-        // With G1, don't generate the call if we statically know that the target in uninitialized
-        if (!dest_uninitialized) {
-          Register tmp = O5;
-          assert_different_registers(addr, count, tmp);
-          Label filtered;
-          // Is marking active?
-          if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
-            __ ld(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);
-          } else {
-            guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1,
-                      "Assumption");
-            __ ldsb(G2, in_bytes(JavaThread::satb_mark_queue_offset() + SATBMarkQueue::byte_offset_of_active()), tmp);
-          }
-          // Is marking active?
-          __ cmp_and_br_short(tmp, G0, Assembler::equal, Assembler::pt, filtered);
-
-          __ save_frame(0);
-          // Save the necessary global regs... will be used after.
-          if (addr->is_global()) {
-            __ mov(addr, L0);
-          }
-          if (count->is_global()) {
-            __ mov(count, L1);
-          }
-          __ mov(addr->after_save(), O0);
-          // Get the count into O1
-          __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre));
-          __ delayed()->mov(count->after_save(), O1);
-          if (addr->is_global()) {
-            __ mov(L0, addr);
-          }
-          if (count->is_global()) {
-            __ mov(L1, count);
-          }
-          __ restore();
-
-          __ bind(filtered);
-          DEBUG_ONLY(__ set(0xDEADC0DE, tmp);) // we have killed tmp
-        }
-        break;
-      case BarrierSet::CardTableModRef:
-      case BarrierSet::Epsilon:
-        break;
-      default:
-        ShouldNotReachHere();
-    }
-  }
-  //
-  //  Generate post-write barrier for array.
-  //
-  //  Input:
-  //     addr     - register containing starting address
-  //     count    - register containing element count
-  //     tmp      - scratch register
-  //
-  //  The input registers are overwritten.
-  //
-  void gen_write_ref_array_post_barrier(Register addr, Register count,
-                                        Register tmp) {
-    BarrierSet* bs = Universe::heap()->barrier_set();
-
-    switch (bs->kind()) {
-      case BarrierSet::G1BarrierSet:
-        {
-          // Get some new fresh output registers.
-          __ save_frame(0);
-          __ mov(addr->after_save(), O0);
-          __ call(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post));
-          __ delayed()->mov(count->after_save(), O1);
-          __ restore();
-        }
-        break;
-      case BarrierSet::CardTableModRef:
-        {
-          CardTableModRefBS* ctbs = barrier_set_cast<CardTableModRefBS>(bs);
-          CardTable* ct = ctbs->card_table();
-          assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
-          assert_different_registers(addr, count, tmp);
-
-          Label L_loop, L_done;
-
-          __ cmp_and_br_short(count, 0, Assembler::equal, Assembler::pt, L_done); // zero count - nothing to do
-
-          __ sll_ptr(count, LogBytesPerHeapOop, count);
-          __ sub(count, BytesPerHeapOop, count);
-          __ add(count, addr, count);
-          // Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
-          __ srl_ptr(addr, CardTable::card_shift, addr);
-          __ srl_ptr(count, CardTable::card_shift, count);
-          __ sub(count, addr, count);
-          AddressLiteral rs(ct->byte_map_base());
-          __ set(rs, tmp);
-        __ BIND(L_loop);
-          __ stb(G0, tmp, addr);
-          __ subcc(count, 1, count);
-          __ brx(Assembler::greaterEqual, false, Assembler::pt, L_loop);
-          __ delayed()->add(addr, 1, addr);
-        __ BIND(L_done);
-        }
-        break;
-      case BarrierSet::ModRef:
-      case BarrierSet::Epsilon:
-        break;
-      default:
-        ShouldNotReachHere();
-    }
-  }
 
   //
   // Generate main code for disjoint arraycopy
@@ -2390,18 +2269,25 @@
       BLOCK_COMMENT("Entry:");
     }
 
-    // save arguments for barrier generation
-    __ mov(to, G1);
-    __ mov(count, G5);
-    gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
+    DecoratorSet decorators = ARRAYCOPY_DISJOINT;
+    if (dest_uninitialized) {
+      decorators |= AS_DEST_NOT_INITIALIZED;
+    }
+    if (aligned) {
+      decorators |= ARRAYCOPY_ALIGNED;
+    }
+
+    BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+    bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
+
     assert_clean_int(count, O3);     // Make sure 'count' is clean int.
     if (UseCompressedOops) {
       generate_disjoint_int_copy_core(aligned);
     } else {
       generate_disjoint_long_copy_core(aligned);
     }
-    // O0 is used as temp register
-    gen_write_ref_array_post_barrier(G1, G5, O0);
+
+    bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, from, to, count);
 
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);
@@ -2440,10 +2326,16 @@
 
     array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
 
-    // save arguments for barrier generation
-    __ mov(to, G1);
-    __ mov(count, G5);
-    gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
+    DecoratorSet decorators = 0;
+    if (dest_uninitialized) {
+      decorators |= AS_DEST_NOT_INITIALIZED;
+    }
+    if (aligned) {
+      decorators |= ARRAYCOPY_ALIGNED;
+    }
+
+    BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+    bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
 
     if (UseCompressedOops) {
       generate_conjoint_int_copy_core(aligned);
@@ -2451,8 +2343,7 @@
       generate_conjoint_long_copy_core(aligned);
     }
 
-    // O0 is used as temp register
-    gen_write_ref_array_post_barrier(G1, G5, O0);
+    bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, from, to, count);
 
     // O3, O4 are used as temp registers
     inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4);
@@ -2554,9 +2445,16 @@
       // caller can pass a 64-bit byte count here (from generic stub)
       BLOCK_COMMENT("Entry:");
     }
-    gen_write_ref_array_pre_barrier(O1_to, O2_count, dest_uninitialized);
-
-    Label load_element, store_element, do_card_marks, fail, done;
+
+    DecoratorSet decorators = ARRAYCOPY_CHECKCAST;
+    if (dest_uninitialized) {
+      decorators |= AS_DEST_NOT_INITIALIZED;
+    }
+
+    BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler();
+    bs->arraycopy_prologue(_masm, decorators, T_OBJECT, O0_from, O1_to, O2_count);
+
+    Label load_element, store_element, do_epilogue, fail, done;
     __ addcc(O2_count, 0, G1_remain);   // initialize loop index, and test it
     __ brx(Assembler::notZero, false, Assembler::pt, load_element);
     __ delayed()->mov(G0, O5_offset);   // offset from start of arrays
@@ -2578,7 +2476,7 @@
     __ deccc(G1_remain);                // decrement the count
     __ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop
     __ inc(O5_offset, heapOopSize);     // step to next offset
-    __ brx(Assembler::zero, true, Assembler::pt, do_card_marks);
+    __ brx(Assembler::zero, true, Assembler::pt, do_epilogue);
     __ delayed()->set(0, O0);           // return -1 on success
 
     // ======== loop entry is here ========
@@ -2602,8 +2500,8 @@
     __ brx(Assembler::zero, false, Assembler::pt, done);
     __ delayed()->not1(O2_count, O0);   // report (-1^K) to caller
 
-    __ BIND(do_card_marks);
-    gen_write_ref_array_post_barrier(O1_to, O2_count, O3);   // store check on O1[0..O2]
+    __ BIND(do_epilogue);
+    bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, O0_from, O1_to, O2_count);
 
     __ BIND(done);
     inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4);