# HG changeset patch # User rkennke # Date 1519144458 -3600 # Tue Feb 20 17:34:18 2018 +0100 # Node ID 3f607de476d44e2e24c8641a439b1f631680187d # Parent be182a18c9b5dec365be2ebdbb1a7819eb891f89 [mq]: arraycopy-access-barriers.patch diff --git a/src/hotspot/share/c1/c1_Runtime1.cpp b/src/hotspot/share/c1/c1_Runtime1.cpp --- a/src/hotspot/share/c1/c1_Runtime1.cpp +++ b/src/hotspot/share/c1/c1_Runtime1.cpp @@ -1398,9 +1398,6 @@ if (length == 0) return ac_ok; - BarrierSet::barrier_set()->read_barrier(src); - BarrierSet::barrier_set()->write_barrier(dst); - if (src->is_typeArray()) { Klass* klass_oop = src->klass(); if (klass_oop != dst->klass()) return ac_failed; @@ -1411,8 +1408,7 @@ char* dst_addr = (char*) ((oopDesc**)dst + ihs) + (dst_pos << l2es); // Potential problem: memmove is not guaranteed to be word atomic // Revisit in Merlin - memmove(dst_addr, src_addr, length << l2es); - return ac_ok; + return HeapAccess<>::arraycopy(arrayOop(src), arrayOop(dst), src_addr, dst_addr, length << l2es) ? ac_ok : ac_failed; } else if (src->is_objArray() && dst->is_objArray()) { if (UseCompressedOops) { narrowOop *src_addr = objArrayOop(src)->obj_at_addr(src_pos); diff --git a/src/hotspot/share/gc/shared/barrierSet.hpp b/src/hotspot/share/gc/shared/barrierSet.hpp --- a/src/hotspot/share/gc/shared/barrierSet.hpp +++ b/src/hotspot/share/gc/shared/barrierSet.hpp @@ -242,8 +242,8 @@ } template - static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, size_t src_pos, size_t dst_pos, size_t length) { - return Raw::arraycopy(src_obj, dst_obj, src_pos, dst_pos, length); + static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { + return Raw::arraycopy(src, dst, length); } // Heap oop accesses. These accessors get resolved when diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp @@ -180,9 +180,7 @@ } template - static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { - return Raw::arraycopy(src_obj, dst_obj, src, dst, length); - } + static bool arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length); // Heap oop accesses. These accessors get resolved when // IN_HEAP is set (e.g. when using the HeapAccess API), it is @@ -234,12 +232,7 @@ } template - static bool oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { - ((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_ref_array_pre(dst, length, false); - bool success = Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length); - ((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_ref_array((HeapWord*) dst, length); - return success; - } + static bool oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length); // Clone barrier support static void clone_in_heap(oop src, oop dst, size_t size) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp --- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp @@ -78,4 +78,39 @@ return previous; } +template +template +bool ShenandoahBarrierSet::AccessBarrier::arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { + if (!oopDesc::is_null(src_obj)) { + size_t src_offset = pointer_delta((void*) src, (void*) src_obj, sizeof(T)); + src_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->read_barrier(src_obj)); + src = ((T*) (void*) src_obj) + src_offset; + } + if (!oopDesc::is_null(dst_obj)) { + size_t dst_offset = pointer_delta((void*) dst, (void*) dst_obj, sizeof(T)); + dst_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_barrier(dst_obj)); + dst = ((T*) (void*) dst_obj) + dst_offset; + } + return Raw::arraycopy(src, dst, length); +} + +template +template +bool ShenandoahBarrierSet::AccessBarrier::oop_arraycopy_in_heap(arrayOop src_obj, arrayOop dst_obj, T* src, T* dst, size_t length) { + if (!oopDesc::is_null(src_obj)) { + size_t src_offset = pointer_delta((void*) src, (void*) src_obj, sizeof(T)); + src_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->read_barrier(src_obj)); + src = ((T*) (void*) src_obj) + src_offset; + } + if (!oopDesc::is_null(dst_obj)) { + size_t dst_offset = pointer_delta((void*) dst, (void*) dst_obj, sizeof(T)); + dst_obj = arrayOop(((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_barrier(dst_obj)); + dst = ((T*) (void*) dst_obj) + dst_offset; + } + ((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_ref_array_pre(dst, length, false); + bool success = Raw::oop_arraycopy(src_obj, dst_obj, src, dst, length); + ((ShenandoahBarrierSet*) BarrierSet::barrier_set())->write_ref_array((HeapWord*) dst, length); + return success; +} + #endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP diff --git a/src/hotspot/share/oops/accessBackend.cpp b/src/hotspot/share/oops/accessBackend.cpp --- a/src/hotspot/share/oops/accessBackend.cpp +++ b/src/hotspot/share/oops/accessBackend.cpp @@ -105,6 +105,11 @@ } 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); } diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp --- a/src/hotspot/share/oops/objArrayKlass.cpp +++ b/src/hotspot/share/oops/objArrayKlass.cpp @@ -267,9 +267,6 @@ return; } - s = arrayOop(BarrierSet::barrier_set()->read_barrier(s)); - d = arrayOop(BarrierSet::barrier_set()->write_barrier(d)); - if (UseCompressedOops) { narrowOop* const src = objArrayOop(s)->obj_at_addr(src_pos); narrowOop* const dst = objArrayOop(d)->obj_at_addr(dst_pos); diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp --- a/src/hotspot/share/oops/typeArrayKlass.cpp +++ b/src/hotspot/share/oops/typeArrayKlass.cpp @@ -149,15 +149,12 @@ if (length == 0) return; - s = arrayOop(BarrierSet::barrier_set()->read_barrier(s)); - d = arrayOop(BarrierSet::barrier_set()->write_barrier(d)); - // 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); - Copy::conjoint_memory_atomic(src, dst, (size_t)length << l2es); + HeapAccess<>::arraycopy(s, d, src, dst, (size_t)length << l2es); }