# HG changeset patch # User eosterlund # Date 1521542477 -3600 # Node ID a273b521a5592286a3cd2d4338e0e3aa301a1c76 # Parent 1708db7f94c6ef231509de0fdeb561e4d27deebc 8199696: Remove Runtime1::arraycopy Reviewed-by: kvn, mdoerr diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp --- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -2174,8 +2174,8 @@ __ stp(length, src_pos, Address(sp, 2*BytesPerWord)); __ str(src, Address(sp, 4*BytesPerWord)); - address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); address copyfunc_addr = StubRoutines::generic_arraycopy(); + assert(copyfunc_addr != NULL, "generic arraycopy stub required"); // The arguments are in java calling convention so we shift them // to C convention @@ -2188,17 +2188,12 @@ assert_different_registers(c_rarg3, j_rarg4); __ mov(c_rarg3, j_rarg3); __ mov(c_rarg4, j_rarg4); - if (copyfunc_addr == NULL) { // Use C version if stub was not generated - __ mov(rscratch1, RuntimeAddress(C_entry)); - __ blrt(rscratch1, 5, 0, 1); - } else { #ifndef PRODUCT - if (PrintC1Statistics) { - __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); - } + if (PrintC1Statistics) { + __ incrementw(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); + } #endif - __ far_call(RuntimeAddress(copyfunc_addr)); - } + __ far_call(RuntimeAddress(copyfunc_addr)); __ cbz(r0, *stub->continuation()); @@ -2208,14 +2203,12 @@ __ ldp(length, src_pos, Address(sp, 2*BytesPerWord)); __ ldr(src, Address(sp, 4*BytesPerWord)); - if (copyfunc_addr != NULL) { - // r0 is -1^K where K == partial copied count - __ eonw(rscratch1, r0, 0); - // adjust length down and src/end pos up by partial copied count - __ subw(length, length, rscratch1); - __ addw(src_pos, src_pos, rscratch1); - __ addw(dst_pos, dst_pos, rscratch1); - } + // r0 is -1^K where K == partial copied count + __ eonw(rscratch1, r0, 0); + // adjust length down and src/end pos up by partial copied count + __ subw(length, length, rscratch1); + __ addw(src_pos, src_pos, rscratch1); + __ addw(dst_pos, dst_pos, rscratch1); __ b(*stub->entry()); __ bind(*stub->continuation()); diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp --- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -2777,17 +2777,14 @@ #endif // AARCH64 address copyfunc_addr = StubRoutines::generic_arraycopy(); - if (copyfunc_addr == NULL) { // Use C version if stub was not generated - __ call(CAST_FROM_FN_PTR(address, Runtime1::arraycopy)); - } else { + assert(copyfunc_addr != NULL, "generic arraycopy stub required"); #ifndef PRODUCT - if (PrintC1Statistics) { - __ inc_counter((address)&Runtime1::_generic_arraycopystub_cnt, tmp, tmp2); - } + if (PrintC1Statistics) { + __ inc_counter((address)&Runtime1::_generic_arraycopystub_cnt, tmp, tmp2); + } #endif // !PRODUCT - // the stub is in the code cache so close enough - __ call(copyfunc_addr, relocInfo::runtime_call_type); - } + // the stub is in the code cache so close enough + __ call(copyfunc_addr, relocInfo::runtime_call_type); #ifdef AARCH64 __ raw_pop(length, ZR); @@ -2797,15 +2794,11 @@ __ cbz_32(R0, *stub->continuation()); - if (copyfunc_addr != NULL) { - __ mvn_32(tmp, R0); - restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only - __ sub_32(length, length, tmp); - __ add_32(src_pos, src_pos, tmp); - __ add_32(dst_pos, dst_pos, tmp); - } else { - restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only - } + __ mvn_32(tmp, R0); + restore_from_reserved_area(R0, R1, R2, R3); // load saved arguments in slow case only + __ sub_32(length, length, tmp); + __ add_32(src_pos, src_pos, tmp); + __ add_32(dst_pos, dst_pos, tmp); __ b(*stub->entry()); diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp --- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -1858,34 +1858,31 @@ if (op->expected_type() == NULL) { assert(src->is_nonvolatile() && src_pos->is_nonvolatile() && dst->is_nonvolatile() && dst_pos->is_nonvolatile() && length->is_nonvolatile(), "must preserve"); + address copyfunc_addr = StubRoutines::generic_arraycopy(); + assert(copyfunc_addr != NULL, "generic arraycopy stub required"); + // 3 parms are int. Convert to long. __ mr(R3_ARG1, src); __ extsw(R4_ARG2, src_pos); __ mr(R5_ARG3, dst); __ extsw(R6_ARG4, dst_pos); __ extsw(R7_ARG5, length); - address copyfunc_addr = StubRoutines::generic_arraycopy(); - - if (copyfunc_addr == NULL) { // Use C version if stub was not generated. - address entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); - __ call_c_with_frame_resize(entry, frame_resize); - } else { + #ifndef PRODUCT - if (PrintC1Statistics) { - address counter = (address)&Runtime1::_generic_arraycopystub_cnt; - int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true); - __ lwz(R11_scratch1, simm16_offs, tmp); - __ addi(R11_scratch1, R11_scratch1, 1); - __ stw(R11_scratch1, simm16_offs, tmp); - } + if (PrintC1Statistics) { + address counter = (address)&Runtime1::_generic_arraycopystub_cnt; + int simm16_offs = __ load_const_optimized(tmp, counter, tmp2, true); + __ lwz(R11_scratch1, simm16_offs, tmp); + __ addi(R11_scratch1, R11_scratch1, 1); + __ stw(R11_scratch1, simm16_offs, tmp); + } #endif - __ call_c_with_frame_resize(copyfunc_addr, /*stub does not need resized frame*/ 0); - - __ nand(tmp, R3_RET, R3_RET); - __ subf(length, tmp, length); - __ add(src_pos, tmp, src_pos); - __ add(dst_pos, tmp, dst_pos); - } + __ call_c_with_frame_resize(copyfunc_addr, /*stub does not need resized frame*/ 0); + + __ nand(tmp, R3_RET, R3_RET); + __ subf(length, tmp, length); + __ add(src_pos, tmp, src_pos); + __ add(dst_pos, tmp, dst_pos); __ cmpwi(CCR0, R3_RET, 0); __ bc_far_optimized(Assembler::bcondCRbiIs1, __ bi0(CCR0, Assembler::less), *stub->entry()); diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp --- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -1895,6 +1895,15 @@ // If we don't know anything, just go through the generic arraycopy. if (default_type == NULL) { + address copyfunc_addr = StubRoutines::generic_arraycopy(); + + if (copyfunc_addr == NULL) { + // Take a slow path for generic arraycopy. + __ branch_optimized(Assembler::bcondAlways, *stub->entry()); + __ bind(*stub->continuation()); + return; + } + Label done; // Save outgoing arguments in callee saved registers (C convention) in case // a call to System.arraycopy is needed. @@ -1915,10 +1924,6 @@ __ z_lgfr(dst_pos, dst_pos); __ z_lgfr(length, length); - address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); - - address copyfunc_addr = StubRoutines::generic_arraycopy(); - // Pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint. // The arguments are in the corresponding registers. @@ -1927,25 +1932,19 @@ assert(Z_ARG3 == dst, "assumption"); assert(Z_ARG4 == dst_pos, "assumption"); assert(Z_ARG5 == length, "assumption"); - if (copyfunc_addr == NULL) { // Use C version if stub was not generated. - emit_call_c(C_entry); - } else { #ifndef PRODUCT - if (PrintC1Statistics) { - __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_generic_arraycopystub_cnt); - __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch); - } + if (PrintC1Statistics) { + __ load_const_optimized(Z_R1_scratch, (address)&Runtime1::_generic_arraycopystub_cnt); + __ add2mem_32(Address(Z_R1_scratch), 1, Z_R0_scratch); + } #endif - emit_call_c(copyfunc_addr); - } + emit_call_c(copyfunc_addr); CHECK_BAILOUT(); __ compare32_and_branch(Z_RET, (intptr_t)0, Assembler::bcondEqual, *stub->continuation()); - if (copyfunc_addr != NULL) { - __ z_lgr(tmp, Z_RET); - __ z_xilf(tmp, -1); - } + __ z_lgr(tmp, Z_RET); + __ z_xilf(tmp, -1); // Restore values from callee saved registers so they are where the stub // expects them. @@ -1955,11 +1954,9 @@ __ lgr_if_needed(dst_pos, callee_saved_dst_pos); __ lgr_if_needed(length, callee_saved_length); - if (copyfunc_addr != NULL) { - __ z_sr(length, tmp); - __ z_ar(src_pos, tmp); - __ z_ar(dst_pos, tmp); - } + __ z_sr(length, tmp); + __ z_ar(src_pos, tmp); + __ z_ar(dst_pos, tmp); __ branch_optimized(Assembler::bcondAlways, *stub->entry()); __ bind(*stub->continuation()); diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp --- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -1879,29 +1879,21 @@ __ mov(dst_pos, O3); __ mov(length, O4); address copyfunc_addr = StubRoutines::generic_arraycopy(); - - if (copyfunc_addr == NULL) { // Use C version if stub was not generated - __ call_VM_leaf(tmp, CAST_FROM_FN_PTR(address, Runtime1::arraycopy)); - } else { + assert(copyfunc_addr != NULL, "generic arraycopy stub required"); + #ifndef PRODUCT - if (PrintC1Statistics) { - address counter = (address)&Runtime1::_generic_arraycopystub_cnt; - __ inc_counter(counter, G1, G3); - } -#endif - __ call_VM_leaf(tmp, copyfunc_addr); + if (PrintC1Statistics) { + address counter = (address)&Runtime1::_generic_arraycopystub_cnt; + __ inc_counter(counter, G1, G3); } - - if (copyfunc_addr != NULL) { - __ xor3(O0, -1, tmp); - __ sub(length, tmp, length); - __ add(src_pos, tmp, src_pos); - __ cmp_zero_and_br(Assembler::less, O0, *stub->entry()); - __ delayed()->add(dst_pos, tmp, dst_pos); - } else { - __ cmp_zero_and_br(Assembler::less, O0, *stub->entry()); - __ delayed()->nop(); - } +#endif + __ call_VM_leaf(tmp, copyfunc_addr); + + __ xor3(O0, -1, tmp); + __ sub(length, tmp, length); + __ add(src_pos, tmp, src_pos); + __ cmp_zero_and_br(Assembler::less, O0, *stub->entry()); + __ delayed()->add(dst_pos, tmp, dst_pos); __ bind(*stub->continuation()); return; } diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp --- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -3058,9 +3058,8 @@ store_parameter(src, 4); NOT_LP64(assert(src == rcx && src_pos == rdx, "mismatch in calling convention");) - address C_entry = CAST_FROM_FN_PTR(address, Runtime1::arraycopy); - address copyfunc_addr = StubRoutines::generic_arraycopy(); + assert(copyfunc_addr != NULL, "generic arraycopy stub required"); // pass arguments: may push as this is not a safepoint; SP must be fix at each safepoint #ifdef _LP64 @@ -3078,29 +3077,21 @@ // Allocate abi space for args but be sure to keep stack aligned __ subptr(rsp, 6*wordSize); store_parameter(j_rarg4, 4); - if (copyfunc_addr == NULL) { // Use C version if stub was not generated - __ call(RuntimeAddress(C_entry)); - } else { #ifndef PRODUCT - if (PrintC1Statistics) { - __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); - } + if (PrintC1Statistics) { + __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); + } #endif - __ call(RuntimeAddress(copyfunc_addr)); - } + __ call(RuntimeAddress(copyfunc_addr)); __ addptr(rsp, 6*wordSize); #else __ mov(c_rarg4, j_rarg4); - if (copyfunc_addr == NULL) { // Use C version if stub was not generated - __ call(RuntimeAddress(C_entry)); - } else { #ifndef PRODUCT - if (PrintC1Statistics) { - __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); - } + if (PrintC1Statistics) { + __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); + } #endif - __ call(RuntimeAddress(copyfunc_addr)); - } + __ call(RuntimeAddress(copyfunc_addr)); #endif // _WIN64 #else __ push(length); @@ -3109,26 +3100,20 @@ __ push(src_pos); __ push(src); - if (copyfunc_addr == NULL) { // Use C version if stub was not generated - __ call_VM_leaf(C_entry, 5); // removes pushed parameter from the stack - } else { #ifndef PRODUCT - if (PrintC1Statistics) { - __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); - } + if (PrintC1Statistics) { + __ incrementl(ExternalAddress((address)&Runtime1::_generic_arraycopystub_cnt)); + } #endif - __ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack - } + __ call_VM_leaf(copyfunc_addr, 5); // removes pushed parameter from the stack #endif // _LP64 __ cmpl(rax, 0); __ jcc(Assembler::equal, *stub->continuation()); - if (copyfunc_addr != NULL) { - __ mov(tmp, rax); - __ xorl(tmp, -1); - } + __ mov(tmp, rax); + __ xorl(tmp, -1); // Reload values from the stack so they are where the stub // expects them. @@ -3138,11 +3123,9 @@ __ movptr (src_pos, Address(rsp, 3*BytesPerWord)); __ movptr (src, Address(rsp, 4*BytesPerWord)); - if (copyfunc_addr != NULL) { - __ subl(length, tmp); - __ addl(src_pos, tmp); - __ addl(dst_pos, tmp); - } + __ subl(length, tmp); + __ addl(src_pos, tmp); + __ addl(dst_pos, tmp); __ jmp(*stub->entry()); __ bind(*stub->continuation()); diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/share/c1/c1_Runtime1.cpp --- a/src/hotspot/share/c1/c1_Runtime1.cpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/share/c1/c1_Runtime1.cpp Tue Mar 20 11:41:17 2018 +0100 @@ -1358,67 +1358,6 @@ JRT_END -// Array copy return codes. -enum { - ac_failed = -1, // arraycopy failed - ac_ok = 0 // arraycopy succeeded -}; - - -// Below length is the # elements copied. -template int obj_arraycopy_work(oopDesc* src, T* src_addr, - oopDesc* dst, T* dst_addr, - int length) { - if (src == dst) { - // same object, no check - HeapAccess<>::oop_arraycopy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length); - return ac_ok; - } else { - Klass* bound = ObjArrayKlass::cast(dst->klass())->element_klass(); - Klass* stype = ObjArrayKlass::cast(src->klass())->element_klass(); - if (stype == bound || stype->is_subtype_of(bound)) { - // Elements are guaranteed to be subtypes, so no check necessary - HeapAccess::oop_arraycopy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length); - return ac_ok; - } - } - return ac_failed; -} - -// fast and direct copy of arrays; returning -1, means that an exception may be thrown -// and we did not copy anything -JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length)) -#ifndef PRODUCT - _generic_arraycopy_cnt++; // Slow-path oop array copy -#endif - - if (src == NULL || dst == NULL || src_pos < 0 || dst_pos < 0 || length < 0) return ac_failed; - if (!dst->is_array() || !src->is_array()) return ac_failed; - if ((unsigned int) arrayOop(src)->length() < (unsigned int)src_pos + (unsigned int)length) return ac_failed; - if ((unsigned int) arrayOop(dst)->length() < (unsigned int)dst_pos + (unsigned int)length) return ac_failed; - - if (length == 0) return ac_ok; - if (src->is_typeArray()) { - Klass* klass_oop = src->klass(); - if (klass_oop != dst->klass()) return ac_failed; - TypeArrayKlass* klass = TypeArrayKlass::cast(klass_oop); - klass->copy_array(arrayOop(src), src_pos, arrayOop(dst), dst_pos, length, Thread::current()); - return ac_ok; - } else if (src->is_objArray() && dst->is_objArray()) { - if (UseCompressedOops) { - narrowOop *src_addr = objArrayOop(src)->obj_at_addr(src_pos); - narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos); - return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); - } else { - oop *src_addr = objArrayOop(src)->obj_at_addr(src_pos); - oop *dst_addr = objArrayOop(dst)->obj_at_addr(dst_pos); - return obj_arraycopy_work(src, src_addr, dst, dst_addr, length); - } - } - return ac_failed; -JRT_END - - JRT_LEAF(int, Runtime1::is_instance_of(oopDesc* mirror, oopDesc* obj)) // had to return int instead of bool, otherwise there may be a mismatch // between the C calling convention and the Java one. diff -r 1708db7f94c6 -r a273b521a559 src/hotspot/share/c1/c1_Runtime1.hpp --- a/src/hotspot/share/c1/c1_Runtime1.hpp Wed Mar 21 08:18:54 2018 +0100 +++ b/src/hotspot/share/c1/c1_Runtime1.hpp Tue Mar 20 11:41:17 2018 +0100 @@ -186,7 +186,6 @@ #endif // directly accessible leaf routine - static int arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length); static int is_instance_of(oopDesc* mirror, oopDesc* obj); static void predicate_failed_trap(JavaThread* thread);