8183533: AArch64: redundent registers saving in arraycopy stubs

Remove redundent registers saving in gen_write_ref_array_pre_barrier() and gen_write_ref_array_post_barrier().

Reviewed-by: aph
This commit is contained in:
Zhongwei Yao 2017-07-17 10:32:30 +08:00 committed by Ningsheng Jian
parent f82f128416
commit 39baf390e7

View File

@ -620,19 +620,21 @@ class StubGenerator: public StubCodeGenerator {
// Generate code for an array write pre barrier // Generate code for an array write pre barrier
// //
// addr - starting address // addr - starting address
// count - element count // count - element count
// tmp - scratch register // tmp - scratch register
// saved_regs - registers to be saved before calling static_write_ref_array_pre
// //
// Destroy no registers except rscratch1 and rscratch2 // Callers must specify which registers to preserve in saved_regs.
// Clobbers: r0-r18, v0-v7, v16-v31, except saved_regs.
// //
void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized) { void gen_write_ref_array_pre_barrier(Register addr, Register count, bool dest_uninitialized, RegSet saved_regs) {
BarrierSet* bs = Universe::heap()->barrier_set(); BarrierSet* bs = Universe::heap()->barrier_set();
switch (bs->kind()) { switch (bs->kind()) {
case BarrierSet::G1SATBCTLogging: case BarrierSet::G1SATBCTLogging:
// With G1, don't generate the call if we statically know that the target in uninitialized // With G1, don't generate the call if we statically know that the target in uninitialized
if (!dest_uninitialized) { if (!dest_uninitialized) {
__ push_call_clobbered_registers(); __ push(saved_regs, sp);
if (count == c_rarg0) { if (count == c_rarg0) {
if (addr == c_rarg1) { if (addr == c_rarg1) {
// exactly backwards!! // exactly backwards!!
@ -648,7 +650,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg1, count); __ mov(c_rarg1, count);
} }
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2); __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), 2);
__ pop_call_clobbered_registers(); __ pop(saved_regs, sp);
break; break;
case BarrierSet::CardTableForRS: case BarrierSet::CardTableForRS:
case BarrierSet::CardTableExtension: case BarrierSet::CardTableExtension:
@ -665,20 +667,23 @@ class StubGenerator: public StubCodeGenerator {
// Generate code for an array write post barrier // Generate code for an array write post barrier
// //
// Input: // Input:
// start - register containing starting address of destination array // start - register containing starting address of destination array
// end - register containing ending address of destination array // end - register containing ending address of destination array
// scratch - scratch register // scratch - scratch register
// saved_regs - registers to be saved before calling static_write_ref_array_post
// //
// The input registers are overwritten. // The input registers are overwritten.
// The ending address is inclusive. // The ending address is inclusive.
void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch) { // Callers must specify which registers to preserve in saved_regs.
// Clobbers: r0-r18, v0-v7, v16-v31, except saved_regs.
void gen_write_ref_array_post_barrier(Register start, Register end, Register scratch, RegSet saved_regs) {
assert_different_registers(start, end, scratch); assert_different_registers(start, end, scratch);
BarrierSet* bs = Universe::heap()->barrier_set(); BarrierSet* bs = Universe::heap()->barrier_set();
switch (bs->kind()) { switch (bs->kind()) {
case BarrierSet::G1SATBCTLogging: case BarrierSet::G1SATBCTLogging:
{ {
__ push_call_clobbered_registers(); __ push(saved_regs, sp);
// must compute element count unless barrier set interface is changed (other platforms supply count) // must compute element count unless barrier set interface is changed (other platforms supply count)
assert_different_registers(start, end, scratch); assert_different_registers(start, end, scratch);
__ lea(scratch, Address(end, BytesPerHeapOop)); __ lea(scratch, Address(end, BytesPerHeapOop));
@ -687,7 +692,7 @@ class StubGenerator: public StubCodeGenerator {
__ mov(c_rarg0, start); __ mov(c_rarg0, start);
__ mov(c_rarg1, scratch); __ mov(c_rarg1, scratch);
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2); __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), 2);
__ pop_call_clobbered_registers(); __ pop(saved_regs, sp);
} }
break; break;
case BarrierSet::CardTableForRS: case BarrierSet::CardTableForRS:
@ -822,7 +827,7 @@ class StubGenerator: public StubCodeGenerator {
Label again, drain; Label again, drain;
const char *stub_name; const char *stub_name;
if (direction == copy_forwards) if (direction == copy_forwards)
stub_name = "foward_copy_longs"; stub_name = "forward_copy_longs";
else else
stub_name = "backward_copy_longs"; stub_name = "backward_copy_longs";
StubCodeMark mark(this, "StubRoutines", stub_name); StubCodeMark mark(this, "StubRoutines", stub_name);
@ -1439,6 +1444,7 @@ class StubGenerator: public StubCodeGenerator {
address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address *entry, address generate_disjoint_copy(size_t size, bool aligned, bool is_oop, address *entry,
const char *name, bool dest_uninitialized = false) { const char *name, bool dest_uninitialized = false) {
Register s = c_rarg0, d = c_rarg1, count = c_rarg2; Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
RegSet saved_reg = RegSet::of(s, d, count);
__ align(CodeEntryAlignment); __ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name); StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc(); address start = __ pc();
@ -1451,9 +1457,9 @@ class StubGenerator: public StubCodeGenerator {
} }
if (is_oop) { if (is_oop) {
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized, saved_reg);
// save regs before copy_memory
__ push(RegSet::of(d, count), sp); __ push(RegSet::of(d, count), sp);
// no registers are destroyed by this call
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized);
} }
copy_memory(aligned, s, d, count, rscratch1, size); copy_memory(aligned, s, d, count, rscratch1, size);
if (is_oop) { if (is_oop) {
@ -1462,7 +1468,7 @@ class StubGenerator: public StubCodeGenerator {
verify_oop_array(size, d, count, r16); verify_oop_array(size, d, count, r16);
__ sub(count, count, 1); // make an inclusive end pointer __ sub(count, count, 1); // make an inclusive end pointer
__ lea(count, Address(d, count, Address::lsl(exact_log2(size)))); __ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
gen_write_ref_array_post_barrier(d, count, rscratch1); gen_write_ref_array_post_barrier(d, count, rscratch1, RegSet());
} }
__ leave(); __ leave();
__ mov(r0, zr); // return 0 __ mov(r0, zr); // return 0
@ -1495,7 +1501,7 @@ class StubGenerator: public StubCodeGenerator {
address *entry, const char *name, address *entry, const char *name,
bool dest_uninitialized = false) { bool dest_uninitialized = false) {
Register s = c_rarg0, d = c_rarg1, count = c_rarg2; Register s = c_rarg0, d = c_rarg1, count = c_rarg2;
RegSet saved_regs = RegSet::of(s, d, count);
StubCodeMark mark(this, "StubRoutines", name); StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc(); address start = __ pc();
__ enter(); __ enter();
@ -1512,9 +1518,9 @@ class StubGenerator: public StubCodeGenerator {
__ br(Assembler::HS, nooverlap_target); __ br(Assembler::HS, nooverlap_target);
if (is_oop) { if (is_oop) {
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized, saved_regs);
// save regs before copy_memory
__ push(RegSet::of(d, count), sp); __ push(RegSet::of(d, count), sp);
// no registers are destroyed by this call
gen_write_ref_array_pre_barrier(d, count, dest_uninitialized);
} }
copy_memory(aligned, s, d, count, rscratch1, -size); copy_memory(aligned, s, d, count, rscratch1, -size);
if (is_oop) { if (is_oop) {
@ -1523,7 +1529,7 @@ class StubGenerator: public StubCodeGenerator {
verify_oop_array(size, d, count, r16); verify_oop_array(size, d, count, r16);
__ sub(count, count, 1); // make an inclusive end pointer __ sub(count, count, 1); // make an inclusive end pointer
__ lea(count, Address(d, count, Address::lsl(exact_log2(size)))); __ lea(count, Address(d, count, Address::lsl(exact_log2(size))));
gen_write_ref_array_post_barrier(d, count, rscratch1); gen_write_ref_array_post_barrier(d, count, rscratch1, RegSet());
} }
__ leave(); __ leave();
__ mov(r0, zr); // return 0 __ mov(r0, zr); // return 0
@ -1805,6 +1811,9 @@ class StubGenerator: public StubCodeGenerator {
const Register ckoff = c_rarg3; // super_check_offset const Register ckoff = c_rarg3; // super_check_offset
const Register ckval = c_rarg4; // super_klass const Register ckval = c_rarg4; // super_klass
RegSet wb_pre_saved_regs = RegSet::range(c_rarg0, c_rarg4);
RegSet wb_post_saved_regs = RegSet::of(count);
// Registers used as temps (r18, r19, r20 are save-on-entry) // Registers used as temps (r18, r19, r20 are save-on-entry)
const Register count_save = r21; // orig elementscount const Register count_save = r21; // orig elementscount
const Register start_to = r20; // destination array start address const Register start_to = r20; // destination array start address
@ -1862,7 +1871,7 @@ class StubGenerator: public StubCodeGenerator {
} }
#endif //ASSERT #endif //ASSERT
gen_write_ref_array_pre_barrier(to, count, dest_uninitialized); gen_write_ref_array_pre_barrier(to, count, dest_uninitialized, wb_pre_saved_regs);
// save the original count // save the original count
__ mov(count_save, count); __ mov(count_save, count);
@ -1906,7 +1915,7 @@ class StubGenerator: public StubCodeGenerator {
__ BIND(L_do_card_marks); __ BIND(L_do_card_marks);
__ add(to, to, -heapOopSize); // make an inclusive end pointer __ add(to, to, -heapOopSize); // make an inclusive end pointer
gen_write_ref_array_post_barrier(start_to, to, rscratch1); gen_write_ref_array_post_barrier(start_to, to, rscratch1, wb_post_saved_regs);
__ bind(L_done_pop); __ bind(L_done_pop);
__ pop(RegSet::of(r18, r19, r20, r21), sp); __ pop(RegSet::of(r18, r19, r20, r21), sp);