--- a/src/hotspot/share/classfile/javaClasses.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -310,7 +310,8 @@
Handle h_obj = basic_create(length, is_latin1, CHECK_NH);
if (length > 0) {
if (!has_multibyte) {
- strncpy((char*)value(h_obj())->byte_at_addr(0), utf8_str, length);
+ const jbyte* src = reinterpret_cast<const jbyte*>(utf8_str);
+ ArrayAccess<>::arraycopy_from_native(src, value(h_obj()), typeArrayOopDesc::element_offset<jbyte>(0), length);
} else if (is_latin1) {
UTF8::convert_to_unicode(utf8_str, value(h_obj())->byte_at_addr(0), length);
} else {
@@ -356,7 +357,8 @@
Handle h_obj = basic_create(length, is_latin1, CHECK_NH);
if (length > 0) {
if (!has_multibyte) {
- strncpy((char*)value(h_obj())->byte_at_addr(0), utf8_str, length);
+ const jbyte* src = reinterpret_cast<const jbyte*>(utf8_str);
+ ArrayAccess<>::arraycopy_from_native(src, value(h_obj()), typeArrayOopDesc::element_offset<jbyte>(0), length);
} else if (is_latin1) {
UTF8::convert_to_unicode(utf8_str, value(h_obj())->byte_at_addr(0), length);
} else {
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -87,8 +87,8 @@
assert(src != NULL, "No Manifest data");
typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_NH);
typeArrayHandle bufhandle(THREAD, buf);
- char* dst = (char*)(buf->byte_at_addr(0));
- memcpy(dst, src, (size_t)size);
+ ArrayAccess<>::arraycopy_from_native(reinterpret_cast<const jbyte*>(src),
+ buf, typeArrayOopDesc::element_offset<jbyte>(0), size);
Handle bais = JavaCalls::construct_new_instance(SystemDictionary::ByteArrayInputStream_klass(),
vmSymbols::byte_array_void_signature(),
--- a/src/hotspot/share/gc/shared/barrierSet.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/barrierSet.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -213,8 +213,12 @@
}
template <typename T>
- static void arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
- Raw::arraycopy(src_obj, dst_obj, src, dst, length);
+ static void arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ Raw::arraycopy(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
// Heap oop accesses. These accessors get resolved when
@@ -257,8 +261,12 @@
}
template <typename T>
- static bool oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
- return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
+ static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ return Raw::oop_arraycopy(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
// Off-heap oop accesses. These accessors get resolved when
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -83,7 +83,9 @@
static oop oop_atomic_xchg_in_heap(oop new_value, T* addr);
template <typename T>
- static bool oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
+ static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length);
static void clone_in_heap(oop src, oop dst, size_t size);
--- a/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -91,35 +91,41 @@
template <DecoratorSet decorators, typename BarrierSetT>
template <typename T>
inline bool ModRefBarrierSet::AccessBarrier<decorators, BarrierSetT>::
-oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
BarrierSetT *bs = barrier_set_cast<BarrierSetT>(barrier_set());
+ src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
+ dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
+
if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
// Optimized covariant case
- bs->write_ref_array_pre(dst, length,
+ bs->write_ref_array_pre(dst_raw, length,
HasDecorator<decorators, AS_DEST_NOT_INITIALIZED>::value);
- Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
- bs->write_ref_array((HeapWord*)dst, length);
+ Raw::oop_arraycopy(NULL, 0, src_raw, NULL, 0, dst_raw, length);
+ bs->write_ref_array((HeapWord*)dst_raw, length);
} else {
+ assert(dst_obj != NULL, "better have an actual oop");
Klass* bound = objArrayOop(dst_obj)->element_klass();
- T* from = src;
+ T* from = const_cast<T*>(src_raw);
T* end = from + length;
- for (T* p = dst; from < end; from++, p++) {
+ for (T* p = dst_raw; from < end; from++, p++) {
T element = *from;
if (oopDesc::is_instanceof_or_null(CompressedOops::decode(element), bound)) {
bs->template write_ref_field_pre<decorators>(p);
*p = element;
} else {
// We must do a barrier to cover the partial copy.
- const size_t pd = pointer_delta(p, dst, (size_t)heapOopSize);
+ const size_t pd = pointer_delta(p, dst_raw, (size_t)heapOopSize);
// pointer delta is scaled to number of elements (length field in
// objArrayOop) which we assume is 32 bit.
assert(pd == (size_t)(int)pd, "length field overflow");
- bs->write_ref_array((HeapWord*)dst, pd);
+ bs->write_ref_array((HeapWord*)dst_raw, pd);
return false;
}
}
- bs->write_ref_array((HeapWord*)dst, length);
+ bs->write_ref_array((HeapWord*)dst_raw, length);
}
return true;
}
--- a/src/hotspot/share/oops/access.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/access.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -55,7 +55,7 @@
// * atomic_cmpxchg_at: Atomically compare-and-swap a new value at an internal pointer address if previous value matched the compared value.
// * atomic_xchg: Atomically swap a new value at an address if previous value matched the compared value.
// * atomic_xchg_at: Atomically swap a new value at an internal pointer address if previous value matched the compared value.
-// * arraycopy: Copy data from one heap array to another heap array.
+// * arraycopy: Copy data from one heap array to another heap array. The ArrayAccess class has convenience functions for this.
// * clone: Clone the contents of an object to a newly allocated object.
// * resolve: Resolve a stable to-space invariant oop that is guaranteed not to relocate its payload until a subsequent thread transition.
// * equals: Object equality, e.g. when different copies of the same objects are in use (from-space vs. to-space)
@@ -130,6 +130,29 @@
static const DecoratorSet atomic_xchg_mo_decorators = MO_SEQ_CST;
static const DecoratorSet atomic_cmpxchg_mo_decorators = MO_RELAXED | MO_SEQ_CST;
+protected:
+ template <typename T>
+ static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | IN_HEAP_ARRAY |
+ AS_DECORATOR_MASK>();
+ return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
+ }
+
+ template <typename T>
+ static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | IN_HEAP_ARRAY |
+ AS_DECORATOR_MASK>();
+ AccessInternal::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
+ }
+
public:
// Primitive heap accesses
static inline AccessInternal::LoadAtProxy<decorators> load_at(oop base, ptrdiff_t offset) {
@@ -155,13 +178,6 @@
return AccessInternal::atomic_xchg_at<decorators>(new_value, base, offset);
}
- template <typename T>
- static inline void arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
- verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |
- AS_DECORATOR_MASK>();
- AccessInternal::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
- }
-
// Oop heap accesses
static inline AccessInternal::OopLoadAtProxy<decorators> oop_load_at(oop base, ptrdiff_t offset) {
verify_heap_oop_decorators<load_mo_decorators>();
@@ -193,12 +209,6 @@
return AccessInternal::atomic_xchg_at<decorators | INTERNAL_VALUE_IS_OOP>(new_oop_value, base, offset);
}
- template <typename T>
- static inline bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
- verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP | AS_DECORATOR_MASK>();
- return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, dst_obj, src, dst, length);
- }
-
// Clone an object from src to dst
static inline void clone(oop src, oop dst, size_t size) {
verify_decorators<IN_HEAP>();
@@ -288,6 +298,55 @@
template <DecoratorSet decorators = INTERNAL_EMPTY>
class RootAccess: public Access<IN_ROOT | decorators> {};
+// Helper for array access.
+template <DecoratorSet decorators = INTERNAL_EMPTY>
+class ArrayAccess: public HeapAccess<IN_HEAP_ARRAY | decorators> {
+ typedef HeapAccess<IN_HEAP_ARRAY | decorators> AccessT;
+public:
+ template <typename T>
+ static inline void arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
+ arrayOop dst_obj, size_t dst_offset_in_bytes,
+ size_t length) {
+ AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const T*>(NULL),
+ dst_obj, dst_offset_in_bytes, reinterpret_cast<T*>(NULL),
+ length);
+ }
+
+ template <typename T>
+ static inline void arraycopy_to_native(arrayOop src_obj, size_t src_offset_in_bytes,
+ T* dst,
+ size_t length) {
+ AccessT::arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const T*>(NULL),
+ NULL, 0, dst,
+ length);
+ }
+
+ template <typename T>
+ static inline void arraycopy_from_native(const T* src,
+ arrayOop dst_obj, size_t dst_offset_in_bytes,
+ size_t length) {
+ AccessT::arraycopy(NULL, 0, src,
+ dst_obj, dst_offset_in_bytes, reinterpret_cast<T*>(NULL),
+ length);
+ }
+
+ static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
+ arrayOop dst_obj, size_t dst_offset_in_bytes,
+ size_t length) {
+ return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, reinterpret_cast<const HeapWord*>(NULL),
+ dst_obj, dst_offset_in_bytes, reinterpret_cast<HeapWord*>(NULL),
+ length);
+ }
+
+ template <typename T>
+ static inline bool oop_arraycopy_raw(T* src, T* dst, size_t length) {
+ return AccessT::oop_arraycopy(NULL, 0, src,
+ NULL, 0, dst,
+ length);
+ }
+
+};
+
template <DecoratorSet decorators>
template <DecoratorSet expected_decorators>
void Access<decorators>::verify_decorators() {
--- a/src/hotspot/share/oops/access.inline.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/access.inline.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -123,17 +123,23 @@
template <class GCBarrierType, DecoratorSet decorators>
struct PostRuntimeDispatch<GCBarrierType, BARRIER_ARRAYCOPY, decorators>: public AllStatic {
template <typename T>
- static bool access_barrier(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
- GCBarrierType::arraycopy_in_heap(src_obj, dst_obj, src, dst, length);
+ static bool access_barrier(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ GCBarrierType::arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
return true;
}
template <typename T>
- static bool oop_access_barrier(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ static bool oop_access_barrier(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
typedef typename HeapOopType<decorators>::type OopType;
- return GCBarrierType::oop_arraycopy_in_heap(src_obj, dst_obj,
- reinterpret_cast<OopType*>(src),
- reinterpret_cast<OopType*>(dst), length);
+ return GCBarrierType::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, reinterpret_cast<OopType*>(src_raw),
+ dst_obj, dst_offset_in_bytes, reinterpret_cast<OopType*>(dst_raw),
+ length);
}
};
@@ -337,10 +343,14 @@
}
template <DecoratorSet decorators, typename T>
- bool RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy_init(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
+ bool RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy_init(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
func_t function = BarrierResolver<decorators, func_t, BARRIER_ARRAYCOPY>::resolve_barrier();
_arraycopy_func = function;
- return function(src_obj, dst_obj, src, dst, length);
+ return function(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
template <DecoratorSet decorators, typename T>
--- a/src/hotspot/share/oops/accessBackend.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/accessBackend.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -105,11 +105,21 @@
}
template<>
+ void arraycopy_conjoint<jboolean>(jboolean* src, jboolean* dst, size_t length) {
+ Copy::conjoint_jbytes(reinterpret_cast<jbyte*>(src), reinterpret_cast<jbyte*>(dst), length);
+ }
+
+ template<>
void arraycopy_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length) {
Copy::conjoint_jbytes(src, dst, length);
}
template<>
+ void arraycopy_conjoint<jchar>(jchar* src, jchar* dst, size_t length) {
+ Copy::conjoint_jshorts_atomic(reinterpret_cast<jshort*>(src), reinterpret_cast<jshort*>(dst), length);
+ }
+
+ template<>
void arraycopy_conjoint<jshort>(jshort* src, jshort* dst, size_t length) {
Copy::conjoint_jshorts_atomic(src, dst, length);
}
@@ -120,11 +130,21 @@
}
template<>
+ void arraycopy_conjoint<jfloat>(jfloat* src, jfloat* dst, size_t length) {
+ Copy::conjoint_jints_atomic(reinterpret_cast<jint*>(src), reinterpret_cast<jint*>(dst), length);
+ }
+
+ template<>
void arraycopy_conjoint<jlong>(jlong* src, jlong* dst, size_t length) {
Copy::conjoint_jlongs_atomic(src, dst, length);
}
template<>
+ void arraycopy_conjoint<jdouble>(jdouble* src, jdouble* dst, size_t length) {
+ Copy::conjoint_jlongs_atomic(reinterpret_cast<jlong*>(src), reinterpret_cast<jlong*>(dst), length);
+ }
+
+ template<>
void arraycopy_arrayof_conjoint<jbyte>(jbyte* src, jbyte* dst, size_t length) {
Copy::arrayof_conjoint_jbytes(reinterpret_cast<HeapWord*>(src),
reinterpret_cast<HeapWord*>(dst),
--- a/src/hotspot/share/oops/accessBackend.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/accessBackend.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -110,7 +110,9 @@
typedef T (*atomic_cmpxchg_func_t)(T new_value, void* addr, T compare_value);
typedef T (*atomic_xchg_func_t)(T new_value, void* addr);
- typedef bool (*arraycopy_func_t)(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
+ typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length);
typedef void (*clone_func_t)(oop src, oop dst, size_t size);
typedef oop (*resolve_func_t)(oop obj);
typedef bool (*equals_func_t)(oop o1, oop o2);
@@ -118,7 +120,9 @@
template <DecoratorSet decorators>
struct AccessFunctionTypes<decorators, void> {
- typedef bool (*arraycopy_func_t)(arrayOop src_obj, arrayOop dst_obj, void* src, void* dst, size_t length);
+ typedef bool (*arraycopy_func_t)(arrayOop src_obj, size_t src_offset_in_bytes, void* src,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, void* dst,
+ size_t length);
};
template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
@@ -256,7 +260,7 @@
static inline typename EnableIf<
HasDecorator<ds, MO_UNORDERED>::value, T>::type
load_internal(void* addr) {
- return *reinterpret_cast<const T*>(addr);
+ return *reinterpret_cast<T*>(addr);
}
template <DecoratorSet ds, typename T>
@@ -353,7 +357,9 @@
}
template <typename T>
- static bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
+ static bool arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length);
template <typename T>
static void oop_store(void* addr, T value);
@@ -396,7 +402,9 @@
}
template <typename T>
- static bool oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
+ static bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length);
static void clone(oop src, oop dst, size_t size);
@@ -559,10 +567,16 @@
typedef typename AccessFunction<decorators, T, BARRIER_ARRAYCOPY>::type func_t;
static func_t _arraycopy_func;
- static bool arraycopy_init(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length);
+ static bool arraycopy_init(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length);
- static inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
- return _arraycopy_func(src_obj, dst_obj, src, dst, length);
+ static inline bool arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ return _arraycopy_func(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
};
@@ -900,37 +914,55 @@
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
HasDecorator<decorators, AS_RAW>::value && CanHardwireRaw<decorators>::value, bool>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
if (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value) {
- return Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length);
+ return Raw::oop_arraycopy(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
} else {
- return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
+ return Raw::arraycopy(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
HasDecorator<decorators, AS_RAW>::value && !CanHardwireRaw<decorators>::value, bool>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
if (UseCompressedOops) {
const DecoratorSet expanded_decorators = decorators | convert_compressed_oops;
- return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
+ return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
} else {
const DecoratorSet expanded_decorators = decorators & ~convert_compressed_oops;
- return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
+ return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
}
template <DecoratorSet decorators, typename T>
inline static typename EnableIf<
!HasDecorator<decorators, AS_RAW>::value, bool>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
if (is_hardwired_primitive<decorators>()) {
const DecoratorSet expanded_decorators = decorators | AS_RAW;
- return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
+ return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
} else {
- return RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy(src_obj, dst_obj, src, dst, length);
+ return RuntimeDispatch<decorators, T, BARRIER_ARRAYCOPY>::arraycopy(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
}
@@ -1092,21 +1124,33 @@
}
template <DecoratorSet decorators, typename T>
- inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
- return PreRuntimeDispatch::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
+ inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ return PreRuntimeDispatch::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
template <DecoratorSet decorators>
- inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, HeapWord* src, HeapWord* dst, size_t length) {
+ inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, HeapWord* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, HeapWord* dst_raw,
+ size_t length) {
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP;
- return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
+ return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
template <DecoratorSet decorators>
- inline bool arraycopy_reduce_types(arrayOop src_obj, arrayOop dst_obj, narrowOop* src, narrowOop* dst, size_t length) {
+ inline bool arraycopy_reduce_types(arrayOop src_obj, size_t src_offset_in_bytes, narrowOop* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, narrowOop* dst_raw,
+ size_t length) {
const DecoratorSet expanded_decorators = decorators | INTERNAL_CONVERT_COMPRESSED_OOP |
INTERNAL_RT_USE_COMPRESSED_OOPS;
- return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, dst_obj, src, dst, length);
+ return PreRuntimeDispatch::arraycopy<expanded_decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
// Step 1: Set default decorators. This step remembers if a type was volatile
@@ -1239,15 +1283,16 @@
}
template <DecoratorSet decorators, typename T>
- inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ inline bool arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ||
(IsSame<T, void>::value || IsIntegral<T>::value) ||
IsFloatingPoint<T>::value)); // arraycopy allows type erased void elements
typedef typename Decay<T>::type DecayedT;
const DecoratorSet expanded_decorators = DecoratorFixup<decorators | IN_HEAP_ARRAY | IN_HEAP>::value;
- return arraycopy_reduce_types<expanded_decorators>(src_obj, dst_obj,
- const_cast<DecayedT*>(src),
- const_cast<DecayedT*>(dst),
+ return arraycopy_reduce_types<expanded_decorators>(src_obj, src_offset_in_bytes, const_cast<DecayedT*>(src_raw),
+ dst_obj, dst_offset_in_bytes, const_cast<DecayedT*>(dst_raw),
length);
}
--- a/src/hotspot/share/oops/accessBackend.inline.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/accessBackend.inline.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -118,8 +118,12 @@
template <DecoratorSet decorators>
template <typename T>
-inline bool RawAccessBarrier<decorators>::oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
- return arraycopy(src_obj, dst_obj, src, dst, length);
+inline bool RawAccessBarrier<decorators>::oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ return arraycopy(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
}
template <DecoratorSet decorators>
@@ -247,35 +251,45 @@
template <DecoratorSet decorators, typename T>
static inline typename EnableIf<
HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+
+ src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
+ dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
+
// We do not check for ARRAYCOPY_ATOMIC for oops, because they are unconditionally always atomic.
if (HasDecorator<decorators, ARRAYCOPY_ARRAYOF>::value) {
- AccessInternal::arraycopy_arrayof_conjoint_oops(src, dst, length);
+ AccessInternal::arraycopy_arrayof_conjoint_oops(src_raw, dst_raw, length);
} else {
typedef typename HeapOopType<decorators>::type OopType;
- AccessInternal::arraycopy_conjoint_oops(reinterpret_cast<OopType*>(src),
- reinterpret_cast<OopType*>(dst), length);
+ AccessInternal::arraycopy_conjoint_oops(reinterpret_cast<OopType*>(src_raw),
+ reinterpret_cast<OopType*>(dst_raw), length);
}
}
template <DecoratorSet decorators, typename T>
static inline typename EnableIf<
!HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
+ arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw, arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw, size_t length) {
+
+ src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
+ dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
+
if (HasDecorator<decorators, ARRAYCOPY_ARRAYOF>::value) {
- AccessInternal::arraycopy_arrayof_conjoint(src, dst, length);
+ AccessInternal::arraycopy_arrayof_conjoint(const_cast<T*>(src_raw), dst_raw, length);
} else if (HasDecorator<decorators, ARRAYCOPY_DISJOINT>::value && sizeof(T) == HeapWordSize) {
// There is only a disjoint optimization for word granularity copying
if (HasDecorator<decorators, ARRAYCOPY_ATOMIC>::value) {
- AccessInternal::arraycopy_disjoint_words_atomic(src, dst, length);
+ AccessInternal::arraycopy_disjoint_words_atomic(const_cast<T*>(src_raw), dst_raw, length);
} else {
- AccessInternal::arraycopy_disjoint_words(src, dst, length);
+ AccessInternal::arraycopy_disjoint_words(const_cast<T*>(src_raw), dst_raw, length);
}
} else {
if (HasDecorator<decorators, ARRAYCOPY_ATOMIC>::value) {
- AccessInternal::arraycopy_conjoint_atomic(src, dst, length);
+ AccessInternal::arraycopy_conjoint_atomic(const_cast<T*>(src_raw), dst_raw, length);
} else {
- AccessInternal::arraycopy_conjoint(src, dst, length);
+ AccessInternal::arraycopy_conjoint(const_cast<T*>(src_raw), dst_raw, length);
}
}
}
@@ -283,19 +297,29 @@
template <DecoratorSet decorators>
static inline typename EnableIf<
!HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value>::type
- arraycopy(arrayOop src_obj, arrayOop dst_obj, void* src, void* dst, size_t length) {
+ arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const void* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, void* dst_raw,
+ size_t length) {
+
+ src_raw = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
+ dst_raw = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
+
if (HasDecorator<decorators, ARRAYCOPY_ATOMIC>::value) {
- AccessInternal::arraycopy_conjoint_atomic(src, dst, length);
+ AccessInternal::arraycopy_conjoint_atomic(const_cast<void*>(src_raw), dst_raw, length);
} else {
- AccessInternal::arraycopy_conjoint(src, dst, length);
+ AccessInternal::arraycopy_conjoint(const_cast<void*>(src_raw), dst_raw, length);
}
}
};
template <DecoratorSet decorators>
template <typename T>
-inline bool RawAccessBarrier<decorators>::arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
- RawAccessBarrierArrayCopy::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
+inline bool RawAccessBarrier<decorators>::arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
+ arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
+ size_t length) {
+ RawAccessBarrierArrayCopy::arraycopy<decorators>(src_obj, src_offset_in_bytes, src_raw,
+ dst_obj, dst_offset_in_bytes, dst_raw,
+ length);
return true;
}
--- a/src/hotspot/share/oops/arrayOop.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/arrayOop.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -88,6 +88,18 @@
inline void* base(BasicType type) const;
inline void* base_raw(BasicType type) const; // GC barrier invariant
+ template <typename T>
+ static T* obj_offset_to_raw(arrayOop obj, size_t offset_in_bytes, T* raw) {
+ if (obj != NULL) {
+ assert(raw == NULL, "either raw or in-heap");
+ char* base = reinterpret_cast<char*>((void*) obj);
+ raw = reinterpret_cast<T*>(base + offset_in_bytes);
+ } else {
+ assert(raw != NULL, "either raw or in-heap");
+ }
+ return raw;
+ }
+
// Tells whether index is within bounds.
bool is_within_bounds(int index) const { return 0 <= index && index < length(); }
--- a/src/hotspot/share/oops/objArrayKlass.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/objArrayKlass.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -218,23 +218,23 @@
}
// Either oop or narrowOop depending on UseCompressedOops.
-template <class T> void ObjArrayKlass::do_copy(arrayOop s, T* src,
- arrayOop d, T* dst, int length, TRAPS) {
+void ObjArrayKlass::do_copy(arrayOop s, size_t src_offset,
+ arrayOop d, size_t dst_offset, int length, TRAPS) {
if (oopDesc::equals(s, d)) {
// since source and destination are equal we do not need conversion checks.
assert(length > 0, "sanity check");
- HeapAccess<>::oop_arraycopy(s, d, src, dst, length);
+ ArrayAccess<>::oop_arraycopy(s, src_offset, d, dst_offset, length);
} else {
// We have to make sure all elements conform to the destination array
Klass* bound = ObjArrayKlass::cast(d->klass())->element_klass();
Klass* stype = ObjArrayKlass::cast(s->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(s, d, src, dst, length);
+ ArrayAccess<ARRAYCOPY_DISJOINT>::oop_arraycopy(s, src_offset, d, dst_offset, length);
} else {
// slow case: need individual subtype checks
// note: don't use obj_at_put below because it includes a redundant store check
- if (!HeapAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, d, src, dst, length)) {
+ if (!ArrayAccess<ARRAYCOPY_DISJOINT | ARRAYCOPY_CHECKCAST>::oop_arraycopy(s, src_offset, d, dst_offset, length)) {
THROW(vmSymbols::java_lang_ArrayStoreException());
}
}
@@ -289,13 +289,21 @@
return;
}
if (UseCompressedOops) {
- narrowOop* const src = objArrayOop(s)->obj_at_addr<narrowOop>(src_pos);
- narrowOop* const dst = objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos);
- do_copy<narrowOop>(s, src, d, dst, length, CHECK);
+ size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(src_pos);
+ size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<narrowOop>(dst_pos);
+ assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(s, src_offset, NULL) ==
+ objArrayOop(s)->obj_at_addr<narrowOop>(src_pos), "sanity");
+ assert(arrayOopDesc::obj_offset_to_raw<narrowOop>(d, dst_offset, NULL) ==
+ objArrayOop(d)->obj_at_addr<narrowOop>(dst_pos), "sanity");
+ do_copy(s, src_offset, d, dst_offset, length, CHECK);
} else {
- oop* const src = objArrayOop(s)->obj_at_addr<oop>(src_pos);
- oop* const dst = objArrayOop(d)->obj_at_addr<oop>(dst_pos);
- do_copy<oop> (s, src, d, dst, length, CHECK);
+ size_t src_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(src_pos);
+ size_t dst_offset = (size_t) objArrayOopDesc::obj_at_offset<oop>(dst_pos);
+ assert(arrayOopDesc::obj_offset_to_raw<oop>(s, src_offset, NULL) ==
+ objArrayOop(s)->obj_at_addr<oop>(src_pos), "sanity");
+ assert(arrayOopDesc::obj_offset_to_raw<oop>(d, dst_offset, NULL) ==
+ objArrayOop(d)->obj_at_addr<oop>(dst_pos), "sanity");
+ do_copy(s, src_offset, d, dst_offset, length, CHECK);
}
}
--- a/src/hotspot/share/oops/objArrayKlass.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/objArrayKlass.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -88,8 +88,9 @@
private:
// Either oop or narrowOop depending on UseCompressedOops.
// must be called from within ObjArrayKlass.cpp
- template <class T> void do_copy(arrayOop s, T* src, arrayOop d,
- T* dst, int length, TRAPS);
+ void do_copy(arrayOop s, size_t src_offset,
+ arrayOop d, size_t dst_offset,
+ int length, TRAPS);
protected:
// Returns the ObjArrayKlass for n'th dimension.
virtual Klass* array_klass_impl(bool or_null, int n, TRAPS);
--- a/src/hotspot/share/oops/typeArrayKlass.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/typeArrayKlass.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -175,10 +175,9 @@
// This is an attempt to make the copy_array fast.
int l2es = log2_element_size();
- int ihs = array_header_in_bytes() / wordSize;
- void* src = (char*) (s->base(element_type())) + ((size_t)src_pos << l2es);
- void* dst = (char*) (d->base(element_type())) + ((size_t)dst_pos << l2es);
- HeapAccess<ARRAYCOPY_ATOMIC>::arraycopy(s, d, src, dst, (size_t)length << l2es);
+ size_t src_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)src_pos << l2es);
+ size_t dst_offset = arrayOopDesc::base_offset_in_bytes(element_type()) + ((size_t)dst_pos << l2es);
+ ArrayAccess<ARRAYCOPY_ATOMIC>::arraycopy<void>(s, src_offset, d, dst_offset, (size_t)length << l2es);
}
// create a klass of array holding typeArrays
--- a/src/hotspot/share/oops/typeArrayOop.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/typeArrayOop.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -32,12 +32,22 @@
// It is used for arrays of {characters, singles, doubles, bytes, shorts, integers, longs}
#include <limits.h>
+namespace TypeToBT {
+ template<typename T> BasicType to_basic_type();
+ template<> inline BasicType to_basic_type<jboolean>() { return T_BOOLEAN; }
+ template<> inline BasicType to_basic_type<jbyte>() { return T_BYTE; }
+ template<> inline BasicType to_basic_type<jchar>() { return T_CHAR; }
+ template<> inline BasicType to_basic_type<jshort>() { return T_SHORT; }
+ template<> inline BasicType to_basic_type<jint>() { return T_INT; }
+ template<> inline BasicType to_basic_type<jlong>() { return T_LONG; }
+ template<> inline BasicType to_basic_type<jfloat>() { return T_FLOAT; }
+ template<> inline BasicType to_basic_type<jdouble>() { return T_DOUBLE; }
+};
+
class typeArrayOopDesc : public arrayOopDesc {
private:
- template <class T>
- static ptrdiff_t element_offset(BasicType bt, int index) {
- return arrayOopDesc::base_offset_in_bytes(bt) + sizeof(T) * index;
- }
+ template <typename T>
+ static BasicType bt() { return TypeToBT::to_basic_type<T>(); }
protected:
jchar* char_base() const;
@@ -52,6 +62,11 @@
friend class TypeArrayKlass;
public:
+ template <typename T>
+ static ptrdiff_t element_offset(int index) {
+ return arrayOopDesc::base_offset_in_bytes(bt<T>()) + sizeof(T) * index;
+ }
+
jbyte* byte_at_addr(int which) const;
jboolean* bool_at_addr(int which) const;
jchar* char_at_addr(int which) const;
--- a/src/hotspot/share/oops/typeArrayOop.inline.hpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/oops/typeArrayOop.inline.hpp Mon Jun 04 23:01:48 2018 +0200
@@ -90,92 +90,92 @@
}
inline jbyte typeArrayOopDesc::byte_at(int which) const {
- ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ ptrdiff_t offset = element_offset<jbyte>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::byte_at_put(int which, jbyte contents) {
- ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ ptrdiff_t offset = element_offset<jbyte>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jboolean typeArrayOopDesc::bool_at(int which) const {
- ptrdiff_t offset = element_offset<jboolean>(T_BOOLEAN, which);
+ ptrdiff_t offset = element_offset<jboolean>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::bool_at_put(int which, jboolean contents) {
- ptrdiff_t offset = element_offset<jboolean>(T_BOOLEAN, which);
+ ptrdiff_t offset = element_offset<jboolean>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, jboolean(contents & 1));
}
inline jchar typeArrayOopDesc::char_at(int which) const {
- ptrdiff_t offset = element_offset<jchar>(T_CHAR, which);
+ ptrdiff_t offset = element_offset<jchar>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::char_at_put(int which, jchar contents) {
- ptrdiff_t offset = element_offset<jchar>(T_CHAR, which);
+ ptrdiff_t offset = element_offset<jchar>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jint typeArrayOopDesc::int_at(int which) const {
- ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ ptrdiff_t offset = element_offset<jint>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::int_at_put(int which, jint contents) {
- ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ ptrdiff_t offset = element_offset<jint>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jshort typeArrayOopDesc::short_at(int which) const {
- ptrdiff_t offset = element_offset<jshort>(T_SHORT, which);
+ ptrdiff_t offset = element_offset<jshort>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::short_at_put(int which, jshort contents) {
- ptrdiff_t offset = element_offset<jshort>(T_SHORT, which);
+ ptrdiff_t offset = element_offset<jshort>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jushort typeArrayOopDesc::ushort_at(int which) const {
- ptrdiff_t offset = element_offset<jushort>(T_SHORT, which);
+ ptrdiff_t offset = element_offset<jushort>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::ushort_at_put(int which, jushort contents) {
- ptrdiff_t offset = element_offset<jushort>(T_SHORT, which);
+ ptrdiff_t offset = element_offset<jushort>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jlong typeArrayOopDesc::long_at(int which) const {
- ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ ptrdiff_t offset = element_offset<jlong>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::long_at_put(int which, jlong contents) {
- ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ ptrdiff_t offset = element_offset<jlong>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jfloat typeArrayOopDesc::float_at(int which) const {
- ptrdiff_t offset = element_offset<jfloat>(T_FLOAT, which);
+ ptrdiff_t offset = element_offset<jfloat>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::float_at_put(int which, jfloat contents) {
- ptrdiff_t offset = element_offset<jfloat>(T_FLOAT, which);
+ ptrdiff_t offset = element_offset<jfloat>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jdouble typeArrayOopDesc::double_at(int which) const {
- ptrdiff_t offset = element_offset<jdouble>(T_DOUBLE, which);
+ ptrdiff_t offset = element_offset<jdouble>(which);
return HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::double_at_put(int which, jdouble contents) {
- ptrdiff_t offset = element_offset<jdouble>(T_DOUBLE, which);
+ ptrdiff_t offset = element_offset<jdouble>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
inline jbyte typeArrayOopDesc::byte_at_acquire(int which) const {
- ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ ptrdiff_t offset = element_offset<jbyte>(which);
return HeapAccess<MO_ACQUIRE | IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::release_byte_at_put(int which, jbyte contents) {
- ptrdiff_t offset = element_offset<jbyte>(T_BYTE, which);
+ ptrdiff_t offset = element_offset<jbyte>(which);
HeapAccess<MO_RELEASE | IN_HEAP_ARRAY>::store_at(as_oop(), offset, contents);
}
@@ -184,20 +184,20 @@
// casting
#ifdef _LP64
inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
- ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ ptrdiff_t offset = element_offset<jlong>(which);
return (Symbol*)(jlong) HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
- ptrdiff_t offset = element_offset<jlong>(T_LONG, which);
+ ptrdiff_t offset = element_offset<jlong>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, (jlong)contents);
}
#else
inline Symbol* typeArrayOopDesc::symbol_at(int which) const {
- ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ ptrdiff_t offset = element_offset<jint>(which);
return (Symbol*)(jint) HeapAccess<IN_HEAP_ARRAY>::load_at(as_oop(), offset);
}
inline void typeArrayOopDesc::symbol_at_put(int which, Symbol* contents) {
- ptrdiff_t offset = element_offset<jint>(T_INT, which);
+ ptrdiff_t offset = element_offset<jint>(which);
HeapAccess<IN_HEAP_ARRAY>::store_at(as_oop(), offset, (jint)contents);
}
#endif // _LP64
--- a/src/hotspot/share/opto/runtime.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/opto/runtime.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -393,9 +393,9 @@
ResourceMark rm;
jint len = dims->length();
assert(len > 0, "Dimensions array should contain data");
- jint *j_dims = typeArrayOop(dims)->int_at_addr(0);
jint *c_dims = NEW_RESOURCE_ARRAY(jint, len);
- Copy::conjoint_jints_atomic(j_dims, c_dims, len);
+ ArrayAccess<>::arraycopy_to_native<>(dims, typeArrayOopDesc::element_offset<jint>(0),
+ c_dims, len);
Handle holder(THREAD, elem_type->klass_holder()); // keep the klass alive
oop obj = ArrayKlass::cast(elem_type)->multi_allocate(len, c_dims, THREAD);
--- a/src/hotspot/share/prims/jni.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/prims/jni.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -2466,7 +2466,8 @@
if (buf != NULL) {
if (s_len > 0) {
if (!is_latin1) {
- memcpy(buf, s_value->char_at_addr(0), sizeof(jchar)*s_len);
+ ArrayAccess<>::arraycopy_to_native(s_value, (size_t) typeArrayOopDesc::element_offset<jchar>(0),
+ buf, s_len);
} else {
for (int i = 0; i < s_len; i++) {
buf[i] = ((jchar) s_value->byte_at(i)) & 0xff;
@@ -2722,7 +2723,8 @@
result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
if (result != NULL) { \
/* copy the array to the c chunk */ \
- memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
+ ArrayAccess<>::arraycopy_to_native(a, typeArrayOopDesc::element_offset<ElementType>(0), \
+ result, len); \
if (isCopy) { \
*isCopy = JNI_TRUE; \
} \
@@ -2771,7 +2773,7 @@
int len = a->length(); \
if (len != 0) { /* Empty array: nothing to free or copy. */ \
if ((mode == 0) || (mode == JNI_COMMIT)) { \
- memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
+ ArrayAccess<>::arraycopy_from_native(buf, a, typeArrayOopDesc::element_offset<ElementType>(0), len); \
} \
if ((mode == 0) || (mode == JNI_ABORT)) { \
FreeHeap(buf); \
@@ -2822,10 +2824,7 @@
THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
} else { \
if (len > 0) { \
- int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \
- memcpy((u_char*) buf, \
- (u_char*) src->Tag##_at_addr(start), \
- len << sc); \
+ ArrayAccess<>::arraycopy_to_native(src, typeArrayOopDesc::element_offset<ElementType>(start), buf, len); \
} \
} \
JNI_END
@@ -2872,10 +2871,7 @@
THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
} else { \
if (len > 0) { \
- int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
- memcpy((u_char*) dst->Tag##_at_addr(start), \
- (u_char*) buf, \
- len << sc); \
+ ArrayAccess<>::arraycopy_from_native(buf, dst, typeArrayOopDesc::element_offset<ElementType>(start), len); \
} \
} \
JNI_END
@@ -3111,7 +3107,8 @@
typeArrayOop s_value = java_lang_String::value(s);
bool is_latin1 = java_lang_String::is_latin1(s);
if (!is_latin1) {
- memcpy(buf, s_value->char_at_addr(start), sizeof(jchar)*len);
+ ArrayAccess<>::arraycopy_to_native(s_value, typeArrayOopDesc::element_offset<jchar>(start),
+ buf, len);
} else {
for (int i = 0; i < len; i++) {
buf[i] = ((jchar) s_value->byte_at(i + start)) & 0xff;
--- a/src/hotspot/share/prims/unsafe.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/prims/unsafe.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -762,8 +762,8 @@
// caller responsible to free it:
*temp_alloc = class_bytes;
- jbyte* array_base = typeArrayOop(JNIHandles::resolve_non_null(data))->byte_at_addr(0);
- Copy::conjoint_jbytes(array_base, class_bytes, length);
+ ArrayAccess<>::arraycopy_to_native(arrayOop(JNIHandles::resolve_non_null(data)), typeArrayOopDesc::element_offset<jbyte>(0),
+ reinterpret_cast<jbyte*>(class_bytes), length);
objArrayHandle cp_patches_h;
if (cp_patches_jh != NULL) {
--- a/src/hotspot/share/runtime/stubRoutines.cpp Mon Jun 04 22:03:10 2018 +0200
+++ b/src/hotspot/share/runtime/stubRoutines.cpp Mon Jun 04 23:01:48 2018 +0200
@@ -410,7 +410,7 @@
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT
assert(count != 0, "count should be non-zero");
- HeapAccess<>::oop_arraycopy(NULL, NULL, (HeapWord*)src, (HeapWord*)dest, count);
+ ArrayAccess<>::oop_arraycopy_raw((HeapWord*)src, (HeapWord*)dest, count);
JRT_END
JRT_LEAF(void, StubRoutines::oop_copy_uninit(oop* src, oop* dest, size_t count))
@@ -418,7 +418,7 @@
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT
assert(count != 0, "count should be non-zero");
- HeapAccess<AS_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, (HeapWord*)src, (HeapWord*)dest, count);
+ ArrayAccess<AS_DEST_NOT_INITIALIZED>::oop_arraycopy_raw((HeapWord*)src, (HeapWord*)dest, count);
JRT_END
JRT_LEAF(void, StubRoutines::arrayof_jbyte_copy(HeapWord* src, HeapWord* dest, size_t count))
@@ -454,7 +454,7 @@
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT
assert(count != 0, "count should be non-zero");
- HeapAccess<ARRAYCOPY_ARRAYOF>::oop_arraycopy(NULL, NULL, src, dest, count);
+ ArrayAccess<ARRAYCOPY_ARRAYOF>::oop_arraycopy_raw(src, dest, count);
JRT_END
JRT_LEAF(void, StubRoutines::arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count))
@@ -462,7 +462,7 @@
SharedRuntime::_oop_array_copy_ctr++; // Slow-path oop array copy
#endif // !PRODUCT
assert(count != 0, "count should be non-zero");
- HeapAccess<ARRAYCOPY_ARRAYOF | AS_DEST_NOT_INITIALIZED>::oop_arraycopy(NULL, NULL, src, dest, count);
+ ArrayAccess<ARRAYCOPY_ARRAYOF | AS_DEST_NOT_INITIALIZED>::oop_arraycopy_raw(src, dest, count);
JRT_END
address StubRoutines::select_fill_function(BasicType t, bool aligned, const char* &name) {