< prev index next >

src/cpu/sparc/vm/stubGenerator_sparc.cpp

Print this page
rev 12906 : [mq]: gc_interface

@@ -22,10 +22,11 @@
  *
  */
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
+#include "gc/shared/barrierSetCodeGen.hpp"
 #include "interpreter/interpreter.hpp"
 #include "nativeInst_sparc.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/method.hpp"
 #include "oops/objArrayKlass.hpp"

@@ -821,112 +822,10 @@
         __ brx(Assembler::greaterEqualUnsigned, false, Assembler::pt, (*NOLp));
       __ 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::G1SATBCTLogging:
-        // With G1, don't generate the call if we statically know that the target in uninitialized
-        if (!dest_uninitialized) {
-          __ 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();
-        }
-        break;
-      case BarrierSet::CardTableForRS:
-      case BarrierSet::CardTableExtension:
-      case BarrierSet::ModRef:
-        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::G1SATBCTLogging:
-        {
-          // 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::CardTableForRS:
-      case BarrierSet::CardTableExtension:
-        {
-          CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs);
-          assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
-          assert_different_registers(addr, count, tmp);
-
-          Label L_loop;
-
-          __ 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, CardTableModRefBS::card_shift, addr);
-          __ srl_ptr(count, CardTableModRefBS::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);
-        }
-        break;
-      case BarrierSet::ModRef:
-        break;
-      default:
-        ShouldNotReachHere();
-    }
-  }
-
-  //
   // Generate main code for disjoint arraycopy
   //
   typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec,
                                               Label& L_loop, bool use_prefetch, bool use_bis);
 

@@ -2370,22 +2269,27 @@
       *entry = __ pc();
       // caller can pass a 64-bit byte count here
       BLOCK_COMMENT("Entry:");
     }
 
-    // save arguments for barrier generation
-    __ mov(to, G1);
-    __ mov(count, G5);
-    gen_write_ref_array_pre_barrier(G1, G5, dest_uninitialized);
+    BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen();
+    DecoratorSet decorators = DEST_COVARIANT | DEST_DISJOINT;
+    if (dest_uninitialized) {
+      decorators |= DEST_NOT_INITIALIZED;
+
+    }
+    if (aligned) {
+      decorators |= ACCESS_ALIGNED;
+    }
+    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);
     __ retl();
     __ delayed()->mov(G0, O0); // return 0

@@ -2420,23 +2324,25 @@
       BLOCK_COMMENT("Entry:");
     }
 
     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);
-
+    BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen();
+    DecoratorSet decorators = DEST_COVARIANT | DEST_CONJOINT;
+    if (dest_uninitialized) {
+      decorators |= DEST_NOT_INITIALIZED;
+    }
+    if (aligned) {
+      decorators |= ACCESS_ALIGNED;
+    }
+    bs->arraycopy_prologue(_masm, decorators, T_OBJECT, from, to, count);
     if (UseCompressedOops) {
       generate_conjoint_int_copy_core(aligned);
     } else {
       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);
     __ retl();
     __ delayed()->mov(G0, O0); // return 0

@@ -2534,13 +2440,20 @@
     if (entry != NULL) {
       *entry = __ pc();
       // 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;
+    BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen();
+    DecoratorSet decorators = DEST_DISJOINT;
+    if (dest_uninitialized) {
+      decorators |= DEST_NOT_INITIALIZED;
+    }
+
+    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
 
     // Empty array:  Nothing to do.

@@ -2558,11 +2471,11 @@
 
     __ BIND(store_element);
     __ 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 ========
     __ BIND(load_element);
     __ load_heap_oop(O0_from, O5_offset, G3_oop);  // load the oop

@@ -2582,12 +2495,12 @@
     __ BIND(fail);
     __ subcc(O2_count, G1_remain, O2_count);
     __ 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);
     __ retl();
     __ delayed()->nop();             // return value in 00
< prev index next >