< 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 >