Skip to content

Commit 147488c

Browse files
committed
8198445: Access API for primitive/native arraycopy
Reviewed-by: pliden, eosterlund, dholmes
1 parent 8680d7d commit 147488c

8 files changed

Lines changed: 49 additions & 24 deletions

File tree

src/hotspot/share/c1/c1_Runtime1.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -1402,13 +1402,7 @@ JRT_LEAF(int, Runtime1::arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int d
14021402
Klass* klass_oop = src->klass();
14031403
if (klass_oop != dst->klass()) return ac_failed;
14041404
TypeArrayKlass* klass = TypeArrayKlass::cast(klass_oop);
1405-
const int l2es = klass->log2_element_size();
1406-
const int ihs = klass->array_header_in_bytes() / wordSize;
1407-
char* src_addr = (char*) ((oopDesc**)src + ihs) + (src_pos << l2es);
1408-
char* dst_addr = (char*) ((oopDesc**)dst + ihs) + (dst_pos << l2es);
1409-
// Potential problem: memmove is not guaranteed to be word atomic
1410-
// Revisit in Merlin
1411-
memmove(dst_addr, src_addr, length << l2es);
1405+
klass->copy_array(arrayOop(src), src_pos, arrayOop(dst), dst_pos, length, Thread::current());
14121406
return ac_ok;
14131407
} else if (src->is_objArray() && dst->is_objArray()) {
14141408
if (UseCompressedOops) {

src/hotspot/share/gc/shared/barrierSet.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,8 @@ class BarrierSet: public CHeapObj<mtGC> {
189189
}
190190

191191
template <typename T>
192-
static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
193-
return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
192+
static void arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
193+
Raw::arraycopy(src_obj, dst_obj, src, dst, length);
194194
}
195195

196196
// Heap oop accesses. These accessors get resolved when

src/hotspot/share/oops/access.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,10 @@ class Access: public AllStatic {
402402
}
403403

404404
template <typename T>
405-
static inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
405+
static inline void arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
406406
verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |
407407
AS_DECORATOR_MASK>();
408-
return AccessInternal::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
408+
AccessInternal::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
409409
}
410410

411411
// Oop heap accesses

src/hotspot/share/oops/access.inline.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ namespace AccessInternal {
139139
struct PostRuntimeDispatch<GCBarrierType, BARRIER_ARRAYCOPY, decorators>: public AllStatic {
140140
template <typename T>
141141
static bool access_barrier(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
142-
return GCBarrierType::arraycopy_in_heap(src_obj, dst_obj, src, dst, length);
142+
GCBarrierType::arraycopy_in_heap(src_obj, dst_obj, src, dst, length);
143+
return true;
143144
}
144145

145146
template <typename T>
@@ -763,7 +764,7 @@ namespace AccessInternal {
763764
HasDecorator<decorators, AS_RAW>::value, bool>::type
764765
arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T* dst, size_t length) {
765766
typedef RawAccessBarrier<decorators & RAW_DECORATOR_MASK> Raw;
766-
return Raw::arraycopy(src, dst, length);
767+
return Raw::arraycopy(src_obj, dst_obj, src, dst, length);
767768
}
768769

769770
template <DecoratorSet decorators, typename T>
@@ -1077,7 +1078,9 @@ namespace AccessInternal {
10771078

10781079
template <DecoratorSet decorators, typename T>
10791080
inline bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length) {
1080-
verify_types<decorators, T>();
1081+
STATIC_ASSERT((HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ||
1082+
(IsSame<T, void>::value || IsIntegral<T>::value) ||
1083+
IsFloatingPoint<T>::value)); // arraycopy allows type erased void elements
10811084
typedef typename Decay<T>::type DecayedT;
10821085
const DecoratorSet expanded_decorators = DecoratorFixup<decorators | IN_HEAP_ARRAY | IN_HEAP |
10831086
(HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?

src/hotspot/share/oops/accessBackend.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ namespace AccessInternal {
152152
length);
153153
}
154154

155+
template<>
156+
void arraycopy_conjoint<void>(void* src, void* dst, size_t length) {
157+
Copy::conjoint_jbytes(reinterpret_cast<jbyte*>(src),
158+
reinterpret_cast<jbyte*>(dst),
159+
length);
160+
}
161+
155162
template<>
156163
void arraycopy_conjoint_atomic<jbyte>(jbyte* src, jbyte* dst, size_t length) {
157164
Copy::conjoint_jbytes_atomic(src, dst, length);
@@ -171,4 +178,9 @@ namespace AccessInternal {
171178
void arraycopy_conjoint_atomic<jlong>(jlong* src, jlong* dst, size_t length) {
172179
Copy::conjoint_jlongs_atomic(src, dst, length);
173180
}
181+
182+
template<>
183+
void arraycopy_conjoint_atomic<void>(void* src, void* dst, size_t length) {
184+
Copy::conjoint_memory_atomic(src, dst, length);
185+
}
174186
}

src/hotspot/share/oops/accessBackend.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ namespace AccessInternal {
104104
typedef oop (*resolve_func_t)(oop obj);
105105
};
106106

107+
template <DecoratorSet decorators>
108+
struct AccessFunctionTypes<decorators, void> {
109+
typedef bool (*arraycopy_func_t)(arrayOop src_obj, arrayOop dst_obj, void* src, void* dst, size_t length);
110+
};
111+
107112
template <DecoratorSet decorators, typename T, BarrierType barrier> struct AccessFunction {};
108113

109114
#define ACCESS_GENERATE_ACCESS_FUNCTION(bt, func) \
@@ -335,7 +340,7 @@ class RawAccessBarrier: public AllStatic {
335340
}
336341

337342
template <typename T>
338-
static bool arraycopy(T* src, T* dst, size_t length);
343+
static bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length);
339344

340345
template <typename T>
341346
static void oop_store(void* addr, T value);

src/hotspot/share/oops/accessBackend.inline.hpp

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ inline T RawAccessBarrier<decorators>::oop_atomic_xchg_at(T new_value, oop base,
118118
template <DecoratorSet decorators>
119119
template <typename T>
120120
inline bool RawAccessBarrier<decorators>::oop_arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
121-
return arraycopy(src, dst, length);
121+
return arraycopy(src_obj, dst_obj, src, dst, length);
122122
}
123123

124124
template <DecoratorSet decorators>
@@ -257,7 +257,7 @@ class RawAccessBarrierArrayCopy: public AllStatic {
257257
template <DecoratorSet decorators, typename T>
258258
static inline typename EnableIf<
259259
HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value>::type
260-
arraycopy(T* src, T* dst, size_t length) {
260+
arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
261261
// We do not check for ARRAYCOPY_ATOMIC for oops, because they are unconditionally always atomic.
262262
if (HasDecorator<decorators, ARRAYCOPY_ARRAYOF>::value) {
263263
AccessInternal::arraycopy_arrayof_conjoint_oops(src, dst, length);
@@ -271,7 +271,7 @@ class RawAccessBarrierArrayCopy: public AllStatic {
271271
template <DecoratorSet decorators, typename T>
272272
static inline typename EnableIf<
273273
!HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value>::type
274-
arraycopy(T* src, T* dst, size_t length) {
274+
arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
275275
if (HasDecorator<decorators, ARRAYCOPY_ARRAYOF>::value) {
276276
AccessInternal::arraycopy_arrayof_conjoint(src, dst, length);
277277
} else if (HasDecorator<decorators, ARRAYCOPY_DISJOINT>::value && sizeof(T) == HeapWordSize) {
@@ -289,12 +289,23 @@ class RawAccessBarrierArrayCopy: public AllStatic {
289289
}
290290
}
291291
}
292+
293+
template <DecoratorSet decorators>
294+
static inline typename EnableIf<
295+
!HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value>::type
296+
arraycopy(arrayOop src_obj, arrayOop dst_obj, void* src, void* dst, size_t length) {
297+
if (HasDecorator<decorators, ARRAYCOPY_ATOMIC>::value) {
298+
AccessInternal::arraycopy_conjoint_atomic(src, dst, length);
299+
} else {
300+
AccessInternal::arraycopy_conjoint(src, dst, length);
301+
}
302+
}
292303
};
293304

294305
template <DecoratorSet decorators>
295306
template <typename T>
296-
inline bool RawAccessBarrier<decorators>::arraycopy(T* src, T* dst, size_t length) {
297-
RawAccessBarrierArrayCopy::arraycopy<decorators>(src, dst, length);
307+
inline bool RawAccessBarrier<decorators>::arraycopy(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) {
308+
RawAccessBarrierArrayCopy::arraycopy<decorators>(src_obj, dst_obj, src, dst, length);
298309
return true;
299310
}
300311

src/hotspot/share/oops/typeArrayKlass.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ void TypeArrayKlass::copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos
152152
// This is an attempt to make the copy_array fast.
153153
int l2es = log2_element_size();
154154
int ihs = array_header_in_bytes() / wordSize;
155-
char* src = (char*) ((oop*)s + ihs) + ((size_t)src_pos << l2es);
156-
char* dst = (char*) ((oop*)d + ihs) + ((size_t)dst_pos << l2es);
157-
Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es);
155+
void* src = (char*) (s->base(element_type())) + ((size_t)src_pos << l2es);
156+
void* dst = (char*) (d->base(element_type())) + ((size_t)dst_pos << l2es);
157+
HeapAccess<ARRAYCOPY_ATOMIC>::arraycopy(s, d, src, dst, (size_t)length << l2es);
158158
}
159159

160160

0 commit comments

Comments
 (0)