8199696: Remove Runtime1::arraycopy
authoreosterlund
Tue, 20 Mar 2018 11:41:17 +0100
changeset 49470 a273b521a559
parent 49469 1708db7f94c6
child 49471 bed9f0842578
8199696: Remove Runtime1::arraycopy Reviewed-by: kvn, mdoerr
src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
src/hotspot/share/c1/c1_Runtime1.cpp
src/hotspot/share/c1/c1_Runtime1.hpp
--- 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);