--- old/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp 2019-08-29 16:29:08.262612190 +0200 +++ new/src/hotspot/share/gc/shared/modRefBarrierSet.inline.hpp 2019-08-29 16:29:07.878605466 +0200 @@ -90,7 +90,18 @@ template template -inline bool ModRefBarrierSet::AccessBarrier:: +inline void ModRefBarrierSet::AccessBarrier:: +oop_arraycopy_partial_barrier(BarrierSetT *bs, T* dst_raw, T* p) { + 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_raw, pd); +} + +template +template +inline void ModRefBarrierSet::AccessBarrier:: 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) { @@ -99,7 +110,8 @@ 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::value) { + if ((!HasDecorator::value) && + (!HasDecorator::value)) { // Optimized covariant case bs->write_ref_array_pre(dst_raw, length, HasDecorator::value); @@ -112,22 +124,24 @@ T* end = from + length; 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(p); - *p = element; - } else { - // We must do a barrier to cover the partial copy. - 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_raw, pd); - return false; + // Apply any required checks + if (HasDecorator::value && CompressedOops::is_null(element)) { + oop_arraycopy_partial_barrier(bs, dst_raw, p); + throw_array_null_pointer_store_exception(src_obj, dst_obj, Thread::current()); + return; + } + if (HasDecorator::value && + (!oopDesc::is_instanceof_or_null(CompressedOops::decode(element), bound))) { + oop_arraycopy_partial_barrier(bs, dst_raw, p); + throw_array_store_exception(src_obj, dst_obj, Thread::current()); + return; } + // write + bs->template write_ref_field_pre(p); + *p = element; } bs->write_ref_array((HeapWord*)dst_raw, length); } - return true; } template