Skip to content

Commit 53e77d2

Browse files
committed
8373801: Adopt arraycopy OopCopyResult from the lworld branch
Reviewed-by: jsikstro, tschatzl, aboldtch
1 parent 45cf042 commit 53e77d2

12 files changed

+179
-129
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,9 @@ class BarrierSet: public CHeapObj<mtGC> {
281281
}
282282

283283
template <typename T>
284-
static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
285-
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
286-
size_t length);
284+
static OopCopyResult oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
285+
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
286+
size_t length);
287287

288288
// Off-heap oop accesses. These accessors get resolved when
289289
// IN_HEAP is not set (e.g. when using the NativeAccess API), it is

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,29 @@
3434

3535
template <DecoratorSet decorators, typename BarrierSetT>
3636
template <typename T>
37-
inline bool BarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
38-
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
39-
size_t length) {
37+
inline OopCopyResult BarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
38+
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
39+
size_t length) {
4040
T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
4141
T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
4242

4343
if (!HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
4444
// Covariant, copy without checks
45-
return Raw::oop_arraycopy(nullptr, 0, src, nullptr, 0, dst, length);
45+
Raw::oop_arraycopy(nullptr, 0, src, nullptr, 0, dst, length);
46+
return OopCopyResult::ok;
4647
}
4748

4849
// Copy each element with checking casts
4950
Klass* const dst_klass = objArrayOop(dst_obj)->element_klass();
5051
for (const T* const end = src + length; src < end; src++, dst++) {
5152
const T elem = *src;
5253
if (!oopDesc::is_instanceof_or_null(CompressedOops::decode(elem), dst_klass)) {
53-
return false;
54+
return OopCopyResult::failed_check_class_cast;
5455
}
5556
*dst = elem;
5657
}
5758

58-
return true;
59+
return OopCopyResult::ok;
5960
}
6061

6162
#endif // SHARE_GC_SHARED_BARRIERSET_INLINE_HPP

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ class CardTableBarrierSet: public BarrierSet {
104104
static oop oop_atomic_xchg_in_heap(T* addr, oop new_value);
105105

106106
template <typename T>
107-
static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
108-
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
109-
size_t length);
107+
static OopCopyResult oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
108+
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
109+
size_t length);
110110

111111
static void clone_in_heap(oop src, oop dst, size_t size);
112112

src/hotspot/share/gc/shared/cardTableBarrierSet.inline.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ oop_atomic_xchg_in_heap(T* addr, oop new_value) {
9999

100100
template <DecoratorSet decorators, typename BarrierSetT>
101101
template <typename T>
102-
inline bool CardTableBarrierSet::AccessBarrier<decorators, BarrierSetT>::
102+
inline OopCopyResult CardTableBarrierSet::AccessBarrier<decorators, BarrierSetT>::
103103
oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
104104
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
105105
size_t length) {
@@ -131,12 +131,13 @@ oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
131131
// objArrayOop) which we assume is 32 bit.
132132
assert(pd == (size_t)(int)pd, "length field overflow");
133133
bs->write_ref_array((HeapWord*)dst_raw, pd);
134-
return false;
134+
return OopCopyResult::failed_check_class_cast;
135135
}
136136
}
137137
bs->write_ref_array((HeapWord*)dst_raw, length);
138138
}
139-
return true;
139+
140+
return OopCopyResult::ok;
140141
}
141142

142143
template <DecoratorSet decorators, typename BarrierSetT>

src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ class ShenandoahBarrierSet: public BarrierSet {
173173
static oop oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value);
174174

175175
template <typename T>
176-
static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
177-
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
178-
size_t length);
176+
static OopCopyResult oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
177+
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
178+
size_t length);
179179

180180
// Clone barrier support
181181
static void clone_in_heap(oop src, oop dst, size_t size);

src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,15 +382,15 @@ void ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::clone_in_heap
382382

383383
template <DecoratorSet decorators, typename BarrierSetT>
384384
template <typename T>
385-
bool ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
386-
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
387-
size_t length) {
385+
OopCopyResult ShenandoahBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, T* src_raw,
386+
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
387+
size_t length) {
388388
T* src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
389389
T* dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
390390

391391
ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
392392
bs->arraycopy_barrier(src, dst, length);
393-
bool result = Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
393+
OopCopyResult result = Raw::oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, src_raw, dst_obj, dst_offset_in_bytes, dst_raw, length);
394394
if (ShenandoahCardBarrier) {
395395
bs->write_ref_array((HeapWord*) dst, length);
396396
}

src/hotspot/share/gc/z/zBarrierSet.hpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ class ZBarrierSet : public BarrierSet {
8888
static void store_barrier_native_with_healing(zpointer* p);
8989
static void store_barrier_native_without_healing(zpointer* p);
9090

91+
[[noreturn]]
9192
static void unsupported();
9293
static zaddress load_barrier(narrowOop* p, zpointer o) { unsupported(); return zaddress::null; }
9394
static zaddress load_barrier_on_unknown_oop_ref(oop base, ptrdiff_t offset, narrowOop* p, zpointer o) { unsupported(); return zaddress::null; }
@@ -98,11 +99,11 @@ class ZBarrierSet : public BarrierSet {
9899
static void store_barrier_native_without_healing(narrowOop* p) { unsupported(); }
99100

100101
static zaddress oop_copy_one_barriers(zpointer* dst, zpointer* src);
101-
static bool oop_copy_one_check_cast(zpointer* dst, zpointer* src, Klass* dst_klass);
102-
static void oop_copy_one(zpointer* dst, zpointer* src);
102+
static OopCopyResult oop_copy_one_check_cast(zpointer* dst, zpointer* src, Klass* dst_klass);
103+
static OopCopyResult oop_copy_one(zpointer* dst, zpointer* src);
103104

104-
static bool oop_arraycopy_in_heap_check_cast(zpointer* dst, zpointer* src, size_t length, Klass* dst_klass);
105-
static bool oop_arraycopy_in_heap_no_check_cast(zpointer* dst, zpointer* src, size_t length);
105+
static OopCopyResult oop_arraycopy_in_heap_check_cast(zpointer* dst, zpointer* src, size_t length, Klass* dst_klass);
106+
static OopCopyResult oop_arraycopy_in_heap_no_check_cast(zpointer* dst, zpointer* src, size_t length);
106107

107108
public:
108109
//
@@ -134,19 +135,19 @@ class ZBarrierSet : public BarrierSet {
134135
static oop oop_atomic_xchg_in_heap(narrowOop* p, oop new_value) { unsupported(); return nullptr; }
135136
static oop oop_atomic_xchg_in_heap_at(oop base, ptrdiff_t offset, oop new_value);
136137

137-
static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, zpointer* src_raw,
138-
arrayOop dst_obj, size_t dst_offset_in_bytes, zpointer* dst_raw,
139-
size_t length);
140-
static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, oop* src_raw,
141-
arrayOop dst_obj, size_t dst_offset_in_bytes, oop* dst_raw,
142-
size_t length) {
138+
static OopCopyResult oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, zpointer* src_raw,
139+
arrayOop dst_obj, size_t dst_offset_in_bytes, zpointer* dst_raw,
140+
size_t length);
141+
static OopCopyResult oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, oop* src_raw,
142+
arrayOop dst_obj, size_t dst_offset_in_bytes, oop* dst_raw,
143+
size_t length) {
143144
return oop_arraycopy_in_heap(src_obj, src_offset_in_bytes, (zpointer*)src_raw,
144145
dst_obj, dst_offset_in_bytes, (zpointer*)dst_raw,
145146
length);
146147
}
147-
static bool oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, narrowOop* src_raw,
148-
arrayOop dst_obj, size_t dst_offset_in_bytes, narrowOop* dst_raw,
149-
size_t length) { unsupported(); return false; }
148+
static OopCopyResult oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, narrowOop* src_raw,
149+
arrayOop dst_obj, size_t dst_offset_in_bytes, narrowOop* dst_raw,
150+
size_t length) { unsupported(); }
150151

151152
static void clone_in_heap(oop src, oop dst, size_t size);
152153

src/hotspot/share/gc/z/zBarrierSet.inline.hpp

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -328,77 +328,89 @@ inline zaddress ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_copy_on
328328
}
329329

330330
template <DecoratorSet decorators, typename BarrierSetT>
331-
inline void ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_copy_one(zpointer* dst, zpointer* src) {
331+
inline OopCopyResult ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_copy_one(zpointer* dst, zpointer* src) {
332332
const zaddress obj = oop_copy_one_barriers(dst, src);
333333

334+
// Future location for null-restriction check and failure reporting
335+
334336
AtomicAccess::store(dst, ZAddress::store_good(obj));
337+
338+
return OopCopyResult::ok;
335339
}
336340

337341
template <DecoratorSet decorators, typename BarrierSetT>
338-
inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_copy_one_check_cast(zpointer* dst, zpointer* src, Klass* dst_klass) {
342+
inline OopCopyResult ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_copy_one_check_cast(zpointer* dst, zpointer* src, Klass* dst_klass) {
339343
const zaddress obj = oop_copy_one_barriers(dst, src);
340344

341345
if (!oopDesc::is_instanceof_or_null(to_oop(obj), dst_klass)) {
342346
// Check cast failed
343-
return false;
347+
return OopCopyResult::failed_check_class_cast;
344348
}
345349

346350
AtomicAccess::store(dst, ZAddress::store_good(obj));
347351

348-
return true;
352+
return OopCopyResult::ok;
349353
}
350354

351355
template <DecoratorSet decorators, typename BarrierSetT>
352-
inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap_check_cast(zpointer* dst, zpointer* src, size_t length, Klass* dst_klass) {
356+
inline OopCopyResult ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap_check_cast(zpointer* dst, zpointer* src, size_t length, Klass* dst_klass) {
353357
// Check cast and copy each elements
354358
for (const zpointer* const end = src + length; src < end; src++, dst++) {
355-
if (!oop_copy_one_check_cast(dst, src, dst_klass)) {
356-
// Check cast failed
357-
return false;
359+
const OopCopyResult result = oop_copy_one_check_cast(dst, src, dst_klass);
360+
if (result != OopCopyResult::ok) {
361+
return result;
358362
}
359363
}
360364

361-
return true;
365+
return OopCopyResult::ok;
362366
}
363367

364368
template <DecoratorSet decorators, typename BarrierSetT>
365-
inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap_no_check_cast(zpointer* dst, zpointer* src, size_t length) {
369+
inline OopCopyResult ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap_no_check_cast(zpointer* dst, zpointer* src, size_t length) {
366370
const bool is_disjoint = HasDecorator<decorators, ARRAYCOPY_DISJOINT>::value;
367371

368372
if (is_disjoint || src > dst) {
369373
for (const zpointer* const end = src + length; src < end; src++, dst++) {
370-
oop_copy_one(dst, src);
374+
const OopCopyResult result = oop_copy_one(dst, src);
375+
if (result != OopCopyResult::ok) {
376+
return result;
377+
}
371378
}
372-
return true;
379+
380+
return OopCopyResult::ok;
373381
}
374382

375383
if (src < dst) {
376384
const zpointer* const end = src;
377385
src += length - 1;
378386
dst += length - 1;
379387
for ( ; src >= end; src--, dst--) {
380-
oop_copy_one(dst, src);
388+
const OopCopyResult result = oop_copy_one(dst, src);
389+
if (result != OopCopyResult::ok) {
390+
return result;
391+
}
381392
}
382-
return true;
393+
394+
return OopCopyResult::ok;
383395
}
384396

385397
// src and dst are the same; nothing to do
386-
return true;
398+
return OopCopyResult::ok;
387399
}
388400

389401
template <DecoratorSet decorators, typename BarrierSetT>
390-
inline bool ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, zpointer* src_raw,
391-
arrayOop dst_obj, size_t dst_offset_in_bytes, zpointer* dst_raw,
392-
size_t length) {
402+
inline OopCopyResult ZBarrierSet::AccessBarrier<decorators, BarrierSetT>::oop_arraycopy_in_heap(arrayOop src_obj, size_t src_offset_in_bytes, zpointer* src_raw,
403+
arrayOop dst_obj, size_t dst_offset_in_bytes, zpointer* dst_raw,
404+
size_t length) {
393405
zpointer* const src = arrayOopDesc::obj_offset_to_raw(src_obj, src_offset_in_bytes, src_raw);
394406
zpointer* const dst = arrayOopDesc::obj_offset_to_raw(dst_obj, dst_offset_in_bytes, dst_raw);
395407

396408
if (HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value) {
397409
Klass* const dst_klass = objArrayOop(dst_obj)->element_klass();
398410
return oop_arraycopy_in_heap_check_cast(dst, src, length, dst_klass);
411+
} else {
412+
return oop_arraycopy_in_heap_no_check_cast(dst, src, length);
399413
}
400-
401-
return oop_arraycopy_in_heap_no_check_cast(dst, src, length);
402414
}
403415

404416
template <DecoratorSet decorators, typename BarrierSetT>

src/hotspot/share/oops/access.hpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ class Access: public AllStatic {
128128

129129
protected:
130130
template <typename T>
131-
static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
132-
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
133-
size_t length) {
131+
static inline OopCopyResult oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes, const T* src_raw,
132+
arrayOop dst_obj, size_t dst_offset_in_bytes, T* dst_raw,
133+
size_t length) {
134134
verify_decorators<ARRAYCOPY_DECORATOR_MASK | IN_HEAP |
135135
AS_DECORATOR_MASK | IS_ARRAY | IS_DEST_UNINITIALIZED>();
136136
return AccessInternal::arraycopy<decorators | INTERNAL_VALUE_IS_OOP>(src_obj, src_offset_in_bytes, src_raw,
@@ -316,19 +316,24 @@ class ArrayAccess: public HeapAccess<IS_ARRAY | decorators> {
316316
length);
317317
}
318318

319-
static inline bool oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
320-
arrayOop dst_obj, size_t dst_offset_in_bytes,
321-
size_t length) {
319+
[[nodiscard]] // The caller is responsible to throw an exception on failure
320+
static inline OopCopyResult oop_arraycopy(arrayOop src_obj, size_t src_offset_in_bytes,
321+
arrayOop dst_obj, size_t dst_offset_in_bytes,
322+
size_t length) {
322323
return AccessT::oop_arraycopy(src_obj, src_offset_in_bytes, static_cast<const HeapWord*>(nullptr),
323324
dst_obj, dst_offset_in_bytes, static_cast<HeapWord*>(nullptr),
324325
length);
325326
}
326327

327328
template <typename T>
328-
static inline bool oop_arraycopy_raw(T* src, T* dst, size_t length) {
329-
return AccessT::oop_arraycopy(nullptr, 0, src,
330-
nullptr, 0, dst,
331-
length);
329+
static inline void oop_arraycopy_raw(T* src, T* dst, size_t length) {
330+
static_assert((decorators & ARRAYCOPY_CHECKCAST) == 0);
331+
332+
OopCopyResult result = AccessT::oop_arraycopy(nullptr, 0, src,
333+
nullptr, 0, dst,
334+
length);
335+
336+
assert(result == OopCopyResult::ok, "Should never fail");
332337
}
333338

334339
};

0 commit comments

Comments
 (0)