< prev index next >

src/hotspot/cpu/s390/stubGenerator_s390.cpp

8198949_arraycopy
  */
 
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "registerSaver_s390.hpp"
-#include "gc/shared/cardTable.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/barrierSetCodeGen.hpp"
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interp_masm.hpp"
 #include "nativeInst_s390.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/objArrayKlass.hpp"

@@ -684,192 +684,10 address start = 0; return start; } - // Generate pre-write barrier for array. - // - // Input: - // addr - register containing starting address - // count - register containing element count - // - // The input registers are overwritten. - void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) { - - BarrierSet* const 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 is uninitialized. - if (!dest_uninitialized) { - // Is marking active? - Label filtered; - assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame() - assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame() - Register Rtmp1 = Z_R0_scratch; - const int active_offset = in_bytes(JavaThread::satb_mark_queue_offset() + - SATBMarkQueue::byte_offset_of_active()); - if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { - __ load_and_test_int(Rtmp1, Address(Z_thread, active_offset)); - } else { - guarantee(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); - __ load_and_test_byte(Rtmp1, Address(Z_thread, active_offset)); - } - __ z_bre(filtered); // Activity indicator is zero, so there is no marking going on currently. - - // __ push_frame_abi160(0); // implicitly done in save_live_registers() - (void) RegisterSaver::save_live_registers(_masm, RegisterSaver::arg_registers); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), addr, count); - (void) RegisterSaver::restore_live_registers(_masm, RegisterSaver::arg_registers); - // __ pop_frame(); // implicitly done in restore_live_registers() - - __ bind(filtered); - } - break; - case BarrierSet::CardTableModRef: - case BarrierSet::ModRef: - break; - default: - ShouldNotReachHere(); - } - } - - // Generate post-write barrier for array. - // - // Input: - // addr - register containing starting address - // count - register containing element count - // - // The input registers are overwritten. - void gen_write_ref_array_post_barrier(Register addr, Register count, bool branchToEnd) { - BarrierSet* const bs = Universe::heap()->barrier_set(); - switch (bs->kind()) { - case BarrierSet::G1BarrierSet: - { - if (branchToEnd) { - assert_different_registers(addr, Z_R0_scratch); // would be destroyed by push_frame() - assert_different_registers(count, Z_R0_scratch); // would be destroyed by push_frame() - // __ push_frame_abi160(0); // implicitly done in save_live_registers() - (void) RegisterSaver::save_live_registers(_masm, RegisterSaver::arg_registers); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), addr, count); - (void) RegisterSaver::restore_live_registers(_masm, RegisterSaver::arg_registers); - // __ pop_frame(); // implicitly done in restore_live_registers() - } else { - // Tail call: call c and return to stub caller. - address entry_point = CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post); - __ lgr_if_needed(Z_ARG1, addr); - __ lgr_if_needed(Z_ARG2, count); - __ load_const(Z_R1, entry_point); - __ z_br(Z_R1); // Branch without linking, callee will return to stub caller. - } - } - break; - case BarrierSet::CardTableModRef: - // These cases formerly known as - // void array_store_check(Register addr, Register count, bool branchToEnd). - { - NearLabel doXC, done; - 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(Z_R0, Z_R1, addr, count); - - // Nothing to do if count <= 0. - if (branchToEnd) { - __ compare64_and_branch(count, (intptr_t) 0, Assembler::bcondNotHigh, done); - } else { - __ z_ltgr(count, count); - __ z_bcr(Assembler::bcondNotPositive, Z_R14); - } - - // Note: We can't combine the shifts. We could lose a carry - // from calculating the array end address. - // count = (count-1)*BytesPerHeapOop + addr - // Count holds addr of last oop in array then. - __ z_sllg(count, count, LogBytesPerHeapOop); - __ add2reg_with_index(count, -BytesPerHeapOop, count, addr); - - // Get base address of card table. - __ load_const_optimized(Z_R1, (address)ct->byte_map_base()); - - // count = (count>>shift) - (addr>>shift) - __ z_srlg(addr, addr, CardTable::card_shift); - __ z_srlg(count, count, CardTable::card_shift); - - // Prefetch first elements of card table for update. - if (VM_Version::has_Prefetch()) { - __ z_pfd(0x02, 0, addr, Z_R1); - } - - // Special case: clear just one byte. - __ clear_reg(Z_R0, true, false); // Used for doOneByte. - __ z_sgr(count, addr); // Count = n-1 now, CC used for brc below. - __ z_stc(Z_R0, 0, addr, Z_R1); // Must preserve CC from z_sgr. - if (branchToEnd) { - __ z_brz(done); - } else { - __ z_bcr(Assembler::bcondZero, Z_R14); - } - - __ z_cghi(count, 255); - __ z_brnh(doXC); - - // MVCLE: clear a long area. - // Start addr of card table range = base + addr. - // # bytes in card table range = (count + 1) - __ add2reg_with_index(Z_R0, 0, Z_R1, addr); - __ add2reg(Z_R1, 1, count); - - // dirty hack: - // There are just two callers. Both pass - // count in Z_ARG3 = Z_R4 - // addr in Z_ARG2 = Z_R3 - // ==> use Z_ARG2 as src len reg = 0 - // Z_ARG1 as src addr (ignored) - assert(count == Z_ARG3, "count: unexpected register number"); - assert(addr == Z_ARG2, "addr: unexpected register number"); - __ clear_reg(Z_ARG2, true, false); - - __ MacroAssembler::move_long_ext(Z_R0, Z_ARG1, 0); - - if (branchToEnd) { - __ z_bru(done); - } else { - __ z_bcr(Assembler::bcondAlways, Z_R14); - } - - // XC: clear a short area. - Label XC_template; // Instr template, never exec directly! - __ bind(XC_template); - __ z_xc(0, 0, addr, 0, addr); - - __ bind(doXC); - // start addr of card table range = base + addr - // end addr of card table range = base + addr + count - __ add2reg_with_index(addr, 0, Z_R1, addr); - - if (VM_Version::has_ExecuteExtensions()) { - __ z_exrl(count, XC_template); // Execute XC with var. len. - } else { - __ z_larl(Z_R1, XC_template); - __ z_ex(count, 0, Z_R0, Z_R1); // Execute XC with var. len. - } - if (!branchToEnd) { - __ z_br(Z_R14); - } - - __ bind(done); - } - break; - case BarrierSet::ModRef: - if (!branchToEnd) { __ z_br(Z_R14); } - break; - default: - ShouldNotReachHere(); - } - } - - // This is to test that the count register contains a positive int value. // Required because C2 does not respect int to long conversion for stub calls. void assert_positive_int(Register count) { #ifdef ASSERT __ z_srag(Z_R0, count, 31); // Just leave the sign (must be zero) in Z_R0.
@@ -1480,15 +1298,23 // This is the zarch specific stub generator for oop array copy. // Refer to generate_disjoint_copy for a list of prereqs and features. unsigned int start_off = __ offset(); // Remember stub start address (is rtn value). unsigned int size = UseCompressedOops ? 4 : 8; - gen_write_ref_array_pre_barrier(Z_ARG2, Z_ARG3, dest_uninitialized); + 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, Z_ARG1, Z_ARG2, Z_ARG3); generate_disjoint_copy(aligned, size, true, true); - gen_write_ref_array_post_barrier(Z_ARG2, Z_ARG3, false); + bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, Z_ARG2, Z_ARG3, true); return __ addr_at(start_off); }
@@ -1563,15 +1389,23 : StubRoutines::oop_disjoint_arraycopy(dest_uninitialized); // Branch to disjoint_copy (if applicable) before pre_barrier to avoid double pre_barrier. array_overlap_test(nooverlap_target, shift); // Branch away to nooverlap_target if disjoint. - gen_write_ref_array_pre_barrier(Z_ARG2, Z_ARG3, dest_uninitialized); + 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, Z_ARG1, Z_ARG2, Z_ARG3); generate_conjoint_copy(aligned, size, true); // Must preserve ARG2, ARG3. - gen_write_ref_array_post_barrier(Z_ARG2, Z_ARG3, false); + bs->arraycopy_epilogue(_masm, decorators, T_OBJECT, Z_ARG2, Z_ARG3, true); return __ addr_at(start_off); }
< prev index next >