--- 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());
--- 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());
--- 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());
--- 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());
--- 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;
}
--- 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());
--- 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 <class T> 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<ARRAYCOPY_DISJOINT>::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<narrowOop>(src_pos);
- narrowOop *dst_addr = objArrayOop(dst)->obj_at_addr<narrowOop>(dst_pos);
- return obj_arraycopy_work(src, src_addr, dst, dst_addr, length);
- } else {
- oop *src_addr = objArrayOop(src)->obj_at_addr<oop>(src_pos);
- oop *dst_addr = objArrayOop(dst)->obj_at_addr<oop>(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.
--- 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);