added patch585 rh1648995-shenandoah_array_copy_broken_by_not_always_copy_forward_for_disjoint_arrays.patch
199 lines
9.4 KiB
Diff
199 lines
9.4 KiB
Diff
|
|
# HG changeset patch
|
|
# User zgu
|
|
# Date 1541803086 18000
|
|
# Node ID 9c4bf4a86cd89f33bee1e372fd8f6071636b0953
|
|
# Parent 1e4229c1a99bdbe79e202a41a046c13b9b4bd0b6
|
|
[backport] Always copy forward for disjoint arrays
|
|
|
|
diff -r 1e4229c1a99b -r 9c4bf4a86cd8 src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp
|
|
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Fri Nov 09 12:49:43 2018 +0100
|
|
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp Fri Nov 09 17:38:06 2018 -0500
|
|
@@ -120,18 +120,18 @@
|
|
|
|
template <typename T>
|
|
bool arraycopy_loop_1(T* src, T* dst, size_t length, Klass* bound,
|
|
- bool checkcast, bool satb, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
|
|
+ bool checkcast, bool satb, bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
|
|
|
|
template <typename T, bool CHECKCAST>
|
|
bool arraycopy_loop_2(T* src, T* dst, size_t length, Klass* bound,
|
|
- bool satb, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
|
|
+ bool satb, bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
|
|
|
|
template <typename T, bool CHECKCAST, bool SATB>
|
|
bool arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound,
|
|
- ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
|
|
+ bool disjoint, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode);
|
|
|
|
template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
|
|
- bool arraycopy_loop(T* src, T* dst, size_t length, Klass* bound);
|
|
+ bool arraycopy_loop(T* src, T* dst, size_t length, Klass* bound, bool disjoint);
|
|
|
|
template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
|
|
bool arraycopy_element(T* cur_src, T* cur_dst, Klass* bound, Thread* thread);
|
|
diff -r 1e4229c1a99b -r 9c4bf4a86cd8 src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp
|
|
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Fri Nov 09 12:49:43 2018 +0100
|
|
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp Fri Nov 09 17:38:06 2018 -0500
|
|
@@ -93,34 +93,36 @@
|
|
|
|
template <typename T>
|
|
bool ShenandoahBarrierSet::arraycopy_loop_1(T* src, T* dst, size_t length, Klass* bound,
|
|
- bool checkcast, bool satb, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
|
|
+ bool checkcast, bool satb, bool disjoint,
|
|
+ ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
|
|
if (checkcast) {
|
|
- return arraycopy_loop_2<T, true>(src, dst, length, bound, satb, storeval_mode);
|
|
+ return arraycopy_loop_2<T, true>(src, dst, length, bound, satb, disjoint, storeval_mode);
|
|
} else {
|
|
- return arraycopy_loop_2<T, false>(src, dst, length, bound, satb, storeval_mode);
|
|
+ return arraycopy_loop_2<T, false>(src, dst, length, bound, satb, disjoint, storeval_mode);
|
|
}
|
|
}
|
|
|
|
template <typename T, bool CHECKCAST>
|
|
bool ShenandoahBarrierSet::arraycopy_loop_2(T* src, T* dst, size_t length, Klass* bound,
|
|
- bool satb, ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
|
|
+ bool satb, bool disjoint,
|
|
+ ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
|
|
if (satb) {
|
|
- return arraycopy_loop_3<T, CHECKCAST, true>(src, dst, length, bound, storeval_mode);
|
|
+ return arraycopy_loop_3<T, CHECKCAST, true>(src, dst, length, bound, disjoint, storeval_mode);
|
|
} else {
|
|
- return arraycopy_loop_3<T, CHECKCAST, false>(src, dst, length, bound, storeval_mode);
|
|
+ return arraycopy_loop_3<T, CHECKCAST, false>(src, dst, length, bound, disjoint, storeval_mode);
|
|
}
|
|
}
|
|
|
|
template <typename T, bool CHECKCAST, bool SATB>
|
|
-bool ShenandoahBarrierSet::arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound,
|
|
+bool ShenandoahBarrierSet::arraycopy_loop_3(T* src, T* dst, size_t length, Klass* bound, bool disjoint,
|
|
ShenandoahBarrierSet::ArrayCopyStoreValMode storeval_mode) {
|
|
switch (storeval_mode) {
|
|
case NONE:
|
|
- return arraycopy_loop<T, CHECKCAST, SATB, NONE>(src, dst, length, bound);
|
|
+ return arraycopy_loop<T, CHECKCAST, SATB, NONE>(src, dst, length, bound, disjoint);
|
|
case READ_BARRIER:
|
|
- return arraycopy_loop<T, CHECKCAST, SATB, READ_BARRIER>(src, dst, length, bound);
|
|
+ return arraycopy_loop<T, CHECKCAST, SATB, READ_BARRIER>(src, dst, length, bound, disjoint);
|
|
case WRITE_BARRIER:
|
|
- return arraycopy_loop<T, CHECKCAST, SATB, WRITE_BARRIER>(src, dst, length, bound);
|
|
+ return arraycopy_loop<T, CHECKCAST, SATB, WRITE_BARRIER>(src, dst, length, bound, disjoint);
|
|
default:
|
|
ShouldNotReachHere();
|
|
return true; // happy compiler
|
|
@@ -128,30 +130,30 @@
|
|
}
|
|
|
|
template <typename T, bool CHECKCAST, bool SATB, ShenandoahBarrierSet::ArrayCopyStoreValMode STOREVAL_MODE>
|
|
-bool ShenandoahBarrierSet::arraycopy_loop(T* src, T* dst, size_t length, Klass* bound) {
|
|
+bool ShenandoahBarrierSet::arraycopy_loop(T* src, T* dst, size_t length, Klass* bound, bool disjoint) {
|
|
Thread* thread = Thread::current();
|
|
|
|
ShenandoahEvacOOMScope oom_evac_scope;
|
|
|
|
// We need to handle four cases:
|
|
//
|
|
- // a) src < dst, intersecting, can only copy backward only
|
|
+ // a) src < dst, conjoint, can only copy backward only
|
|
// [...src...]
|
|
// [...dst...]
|
|
//
|
|
- // b) src < dst, non-intersecting, can copy forward/backward
|
|
+ // b) src < dst, disjoint, can only copy forward, because types may mismatch
|
|
// [...src...]
|
|
// [...dst...]
|
|
//
|
|
- // c) src > dst, intersecting, can copy forward only
|
|
+ // c) src > dst, conjoint, can copy forward only
|
|
// [...src...]
|
|
// [...dst...]
|
|
//
|
|
- // d) src > dst, non-intersecting, can copy forward/backward
|
|
+ // d) src > dst, disjoint, can only copy forward, because types may mismatch
|
|
// [...src...]
|
|
// [...dst...]
|
|
//
|
|
- if (src > dst) {
|
|
+ if (src > dst || disjoint) {
|
|
// copy forward:
|
|
T* cur_src = src;
|
|
T* cur_dst = dst;
|
|
@@ -248,6 +250,7 @@
|
|
|
|
bool satb = ShenandoahSATBBarrier && heap->is_concurrent_mark_in_progress();
|
|
bool checkcast = HasDecorator<decorators, ARRAYCOPY_CHECKCAST>::value;
|
|
+ bool disjoint = HasDecorator<decorators, ARRAYCOPY_DISJOINT>::value;
|
|
ArrayCopyStoreValMode storeval_mode;
|
|
if (heap->has_forwarded_objects()) {
|
|
if (heap->is_concurrent_traversal_in_progress()) {
|
|
@@ -273,7 +276,7 @@
|
|
|
|
Klass* bound = objArrayOop(dst_obj)->element_klass();
|
|
ShenandoahBarrierSet* bs = ShenandoahBarrierSet::barrier_set();
|
|
- return bs->arraycopy_loop_1(src_raw, dst_raw, length, bound, checkcast, satb, storeval_mode);
|
|
+ return bs->arraycopy_loop_1(src_raw, dst_raw, length, bound, checkcast, satb, disjoint, storeval_mode);
|
|
}
|
|
|
|
#endif //SHARE_VM_GC_SHENANDOAH_SHENANDOAHBARRIERSET_INLINE_HPP
|
|
diff -r 1e4229c1a99b -r 9c4bf4a86cd8 test/hotspot/jtreg/gc/shenandoah/WrongArrayMember.java
|
|
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
|
|
+++ b/test/hotspot/jtreg/gc/shenandoah/WrongArrayMember.java Fri Nov 09 17:38:06 2018 -0500
|
|
@@ -0,0 +1,55 @@
|
|
+/*
|
|
+ * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates.
|
|
+ *
|
|
+ * This code is free software; you can redistribute it and/or modify it
|
|
+ * under the terms of the GNU General Public License version 2 only, as
|
|
+ * published by the Free Software Foundation.
|
|
+ *
|
|
+ * This code is distributed in the hope that it will be useful, but WITHOUT
|
|
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * version 2 for more details (a copy is included in the LICENSE file that
|
|
+ * accompanied this code).
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License version
|
|
+ * 2 along with this work; if not, write to the Free Software Foundation,
|
|
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+ *
|
|
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
+ * or visit www.oracle.com if you need additional information or have any
|
|
+ * questions.
|
|
+ *
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * @test WrongArrayMember
|
|
+ *
|
|
+ * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC WrongArrayMember
|
|
+ * @run main/othervm -Xmx128m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=traversal WrongArrayMember
|
|
+ */
|
|
+
|
|
+public class WrongArrayMember {
|
|
+ public static void main(String... args) throws Exception {
|
|
+ Object[] src = new Object[3];
|
|
+ src[0] = new Integer(0);
|
|
+ src[1] = new Object();
|
|
+ src[2] = new Object();
|
|
+ Object[] dst = new Integer[3];
|
|
+ dst[0] = new Integer(1);
|
|
+ dst[1] = new Integer(2);
|
|
+ dst[2] = new Integer(3);
|
|
+ try {
|
|
+ System.arraycopy(src, 0, dst, 0, 3);
|
|
+ throw new RuntimeException("Expected ArrayStoreException");
|
|
+ } catch (ArrayStoreException e) {
|
|
+ if (src[0] != dst[0]) {
|
|
+ throw new RuntimeException("First element not copied");
|
|
+ } else if (src[1] == dst[1] || src[2] == dst[2]) {
|
|
+ throw new RuntimeException("Second and third elements are affected");
|
|
+ } else {
|
|
+ return; // Passed!
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
|