--- old/src/hotspot/share/c1/c1_Runtime1.cpp 2018-03-08 13:22:56.946563378 +0100 +++ new/src/hotspot/share/c1/c1_Runtime1.cpp 2018-03-08 13:22:56.762565691 +0100 @@ -1402,13 +1402,8 @@ Klass* klass_oop = src->klass(); if (klass_oop != dst->klass()) return ac_failed; TypeArrayKlass* klass = TypeArrayKlass::cast(klass_oop); - const int l2es = klass->log2_element_size(); - const int ihs = klass->array_header_in_bytes() / wordSize; - char* src_addr = (char*) ((oopDesc**)src + ihs) + (src_pos << l2es); - char* dst_addr = (char*) ((oopDesc**)dst + ihs) + (dst_pos << l2es); - // Potential problem: memmove is not guaranteed to be word atomic - // Revisit in Merlin - return HeapAccess<>::arraycopy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length << l2es) ? ac_ok : ac_failed; + 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); --- old/src/hotspot/share/gc/shared/barrierSet.hpp 2018-03-08 13:22:57.603555122 +0100 +++ new/src/hotspot/share/gc/shared/barrierSet.hpp 2018-03-08 13:22:57.379557937 +0100 @@ -190,7 +190,7 @@ template static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { - return Raw::arraycopy(src, dst, length); + return Raw::arraycopy(src_obj, dst_obj, src, dst, length); } // Heap oop accesses. These accessors get resolved when --- old/src/hotspot/share/oops/access.inline.hpp 2018-03-08 13:22:58.196547670 +0100 +++ new/src/hotspot/share/oops/access.inline.hpp 2018-03-08 13:22:58.000550133 +0100 @@ -763,7 +763,7 @@ HasDecorator::value, bool>::type arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) { typedef RawAccessBarrier Raw; - return Raw::arraycopy(src, dst, length); + return Raw::arraycopy(src_obj, dst_obj, src, dst, length); } template --- old/src/hotspot/share/oops/accessBackend.cpp 2018-03-08 13:22:58.776540381 +0100 +++ new/src/hotspot/share/oops/accessBackend.cpp 2018-03-08 13:22:58.578542869 +0100 @@ -105,11 +105,6 @@ } template<> - void arraycopy_conjoint(char* src, char* dst, size_t length) { - Copy::conjoint_jbytes(src, dst, length); - } - - template<> void arraycopy_conjoint(jbyte* src, jbyte* dst, size_t length) { Copy::conjoint_jbytes(src, dst, length); } @@ -158,21 +153,41 @@ } template<> + void arraycopy_conjoint_atomic(jboolean* src, jboolean* dst, size_t length) { + Copy::conjoint_jbytes_atomic(reinterpret_cast(src), reinterpret_cast(dst), length); + } + + template<> void arraycopy_conjoint_atomic(jbyte* src, jbyte* dst, size_t length) { Copy::conjoint_jbytes_atomic(src, dst, length); } template<> + void arraycopy_conjoint_atomic(jchar* src, jchar* dst, size_t length) { + Copy::conjoint_jshorts_atomic(reinterpret_cast(src), reinterpret_cast(dst), length); + } + + template<> void arraycopy_conjoint_atomic(jshort* src, jshort* dst, size_t length) { Copy::conjoint_jshorts_atomic(src, dst, length); } template<> + void arraycopy_conjoint_atomic(jfloat* src, jfloat* dst, size_t length) { + Copy::conjoint_jints_atomic(reinterpret_cast(src), reinterpret_cast(dst), length); + } + + template<> void arraycopy_conjoint_atomic(jint* src, jint* dst, size_t length) { Copy::conjoint_jints_atomic(src, dst, length); } template<> + void arraycopy_conjoint_atomic(jdouble* src, jdouble* dst, size_t length) { + Copy::conjoint_jlongs_atomic(reinterpret_cast(src), reinterpret_cast(dst), length); + } + + template<> void arraycopy_conjoint_atomic(jlong* src, jlong* dst, size_t length) { Copy::conjoint_jlongs_atomic(src, dst, length); } --- old/src/hotspot/share/oops/accessBackend.hpp 2018-03-08 13:22:59.340533293 +0100 +++ new/src/hotspot/share/oops/accessBackend.hpp 2018-03-08 13:22:59.146535731 +0100 @@ -335,7 +335,7 @@ } template - static bool arraycopy(T* src, T* dst, size_t length); + static bool arraycopy(arrayOop s, arrayOop d, T* src, T* dst, size_t length); template static void oop_store(void* addr, T value); --- old/src/hotspot/share/oops/accessBackend.inline.hpp 2018-03-08 13:22:59.927525916 +0100 +++ new/src/hotspot/share/oops/accessBackend.inline.hpp 2018-03-08 13:22:59.731528379 +0100 @@ -118,7 +118,7 @@ template template inline bool RawAccessBarrier::oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { - return arraycopy(src, dst, length); + return arraycopy(src_obj, dst_obj, src, dst, length); } template @@ -257,7 +257,7 @@ template static inline typename EnableIf< HasDecorator::value>::type - arraycopy(T* src, T* dst, size_t length) { + arraycopy(arrayOop s, arrayOop d, T* src, T* dst, size_t length) { // We do not check for ARRAYCOPY_ATOMIC for oops, because they are unconditionally always atomic. if (HasDecorator::value) { AccessInternal::arraycopy_arrayof_conjoint_oops(src, dst, length); @@ -271,7 +271,7 @@ template static inline typename EnableIf< !HasDecorator::value>::type - arraycopy(T* src, T* dst, size_t length) { + arraycopy(arrayOop s, arrayOop d, T* src, T* dst, size_t length) { if (HasDecorator::value) { AccessInternal::arraycopy_arrayof_conjoint(src, dst, length); } else if (HasDecorator::value && sizeof(T) == HeapWordSize) { @@ -293,8 +293,8 @@ template template -inline bool RawAccessBarrier::arraycopy(T* src, T* dst, size_t length) { - RawAccessBarrierArrayCopy::arraycopy(src, dst, length); +inline bool RawAccessBarrier::arraycopy(arrayOop s, arrayOop d, T* src, T* dst, size_t length) { + RawAccessBarrierArrayCopy::arraycopy(s, d, src, dst, length); return true; } --- old/src/hotspot/share/oops/typeArrayKlass.cpp 2018-03-08 13:23:00.568517861 +0100 +++ new/src/hotspot/share/oops/typeArrayKlass.cpp 2018-03-08 13:23:00.350520600 +0100 @@ -149,12 +149,37 @@ if (length == 0) return; - // This is an attempt to make the copy_array fast. - int l2es = log2_element_size(); - int ihs = array_header_in_bytes() / wordSize; - char* src = (char*) ((oop*)s + ihs) + ((size_t)src_pos << l2es); - char* dst = (char*) ((oop*)d + ihs) + ((size_t)dst_pos << l2es); - HeapAccess<>::arraycopy(s, d, src, dst, (size_t)length << l2es); + typeArrayOop src = typeArrayOop(s); + typeArrayOop dst = typeArrayOop(d); + + switch (element_type()) { + case T_BOOLEAN: + HeapAccess::arraycopy(s, d, src->bool_at_addr(src_pos), dst->bool_at_addr(dst_pos), length); + break; + case T_CHAR: + HeapAccess::arraycopy(s, d, src->char_at_addr(src_pos), dst->char_at_addr(dst_pos), length); + break; + case T_FLOAT: + HeapAccess::arraycopy(s, d, src->float_at_addr(src_pos), dst->float_at_addr(dst_pos), length); + break; + case T_DOUBLE: + HeapAccess::arraycopy(s, d, src->double_at_addr(src_pos), dst->double_at_addr(dst_pos), length); + break; + case T_BYTE: + HeapAccess::arraycopy(s, d, src->byte_at_addr(src_pos), dst->byte_at_addr(dst_pos), length); + break; + case T_SHORT: + HeapAccess::arraycopy(s, d, src->short_at_addr(src_pos), dst->short_at_addr(dst_pos), length); + break; + case T_INT: + HeapAccess::arraycopy(s, d, src->int_at_addr(src_pos), dst->int_at_addr(dst_pos), length); + break; + case T_LONG: + HeapAccess::arraycopy(s, d, src->long_at_addr(src_pos), dst->long_at_addr(dst_pos), length); + break; + default: + ShouldNotReachHere(); + } }