< prev index next >

src/hotspot/cpu/sparc/stubGenerator_sparc.cpp

8198949_arraycopy

*** 22,33 **** * */ #include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" ! #include "gc/shared/cardTable.hpp" ! #include "gc/shared/cardTableModRefBS.hpp" #include "interpreter/interpreter.hpp" #include "nativeInst_sparc.hpp" #include "oops/instanceOop.hpp" #include "oops/method.hpp" #include "oops/objArrayKlass.hpp" --- 22,33 ---- * */ #include "precompiled.hpp" #include "asm/macroAssembler.inline.hpp" ! #include "gc/shared/barrierSet.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,949 **** else __ 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::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: - 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: - break; - default: - ShouldNotReachHere(); - } - } // // Generate main code for disjoint arraycopy // typedef void (StubGenerator::*CopyLoopFunc)(Register from, Register to, Register count, int count_dec, --- 821,830 ---- ***************
*** 2386,2407 **** *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); 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); // O3, O4 are used as temp registers inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4); __ retl(); __ delayed()->mov(G0, O0); // return 0 --- 2267,2293 ---- *entry = __ pc(); // caller can pass a 64-bit byte count here BLOCK_COMMENT("Entry:"); } ! BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen(); ! DecoratorSet decorators = ARRAYCOPY_DISJOINT; ! if (dest_uninitialized) { ! decorators |= AS_DEST_NOT_INITIALIZED; ! ! } ! if (aligned) { ! decorators |= ARRAYCOPY_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); } ! 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 ***************
*** 2436,2458 **** 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); ! 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); // O3, O4 are used as temp registers inc_counter_np(SharedRuntime::_oop_array_copy_ctr, O3, O4); __ retl(); __ delayed()->mov(G0, O0); // return 0 --- 2322,2346 ---- BLOCK_COMMENT("Entry:"); } array_overlap_test(nooverlap_target, LogBytesPerHeapOop); ! BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen(); ! DecoratorSet decorators = 0; ! if (dest_uninitialized) { ! decorators |= AS_DEST_NOT_INITIALIZED; ! } ! if (aligned) { ! decorators |= ARRAYCOPY_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); } ! 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 ***************
*** 2550,2562 **** 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; __ 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. --- 2438,2457 ---- if (entry != NULL) { *entry = __ pc(); // caller can pass a 64-bit byte count here (from generic stub) BLOCK_COMMENT("Entry:"); } ! BarrierSetCodeGen *bs = Universe::heap()->barrier_set()->code_gen(); ! DecoratorSet decorators = ARRAYCOPY_CHECKCAST; ! if (dest_uninitialized) { ! decorators |= AS_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. ***************
*** 2574,2584 **** __ 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); __ 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 --- 2469,2479 ---- __ 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_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 ***************
*** 2598,2609 **** __ 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(done); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr, O3, O4); __ retl(); __ delayed()->nop(); // return value in 00 --- 2493,2504 ---- __ 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_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 >