OpenJDK / jdk / jdk
changeset 60129:540fa2ed353e
8248598: [Graal] Several testcases from applications/jcstress/acqrel.java fails with forbidden state
Reviewed-by: dlong
author | roland |
---|---|
date | Thu, 09 Jul 2020 10:20:32 +0200 |
parents | cf50fcf7bec4 |
children | 224aa251bffb |
files | src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VolatileAccessReadEliminationTest.java src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java |
diffstat | 2 files changed, 126 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VolatileAccessReadEliminationTest.java Thu Jul 09 10:20:32 2020 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * 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. + */ + + +package org.graalvm.compiler.core.test; + +import jdk.vm.ci.meta.ResolvedJavaMethod; +import org.graalvm.compiler.core.common.type.IntegerStamp; +import org.graalvm.compiler.core.common.type.Stamp; +import org.graalvm.compiler.nodes.NodeView; +import org.graalvm.compiler.nodes.StructuredGraph; +import org.graalvm.compiler.nodes.memory.ReadNode; +import org.junit.Assert; +import org.junit.Test; + +// See https://bugs.openjdk.java.net/browse/JDK-8248598 +public class VolatileAccessReadEliminationTest extends GraalCompilerTest { + private static int field; + private Thread thread; + private static long[] array = new long[1]; + + static { + arrayBaseOffset = UNSAFE.arrayBaseOffset(long[].class); + } + + private static int arrayBaseOffset; + + public static int testMethod1() { + int v = field; + UNSAFE.putLongVolatile(array, arrayBaseOffset, 1); + while (UNSAFE.getLongVolatile(array, arrayBaseOffset) != 2) { + // wait for other thread + } + return v + field; // field load shouldn't common with one above. + } + + @Test + public void test1() { + test("testMethod1"); + } + + @Override + protected void before(ResolvedJavaMethod method) { + field = 0; + UNSAFE.putLongVolatile(array, arrayBaseOffset, 0); + thread = new Thread() { + @Override + public void run() { + while (UNSAFE.getLongVolatile(array, arrayBaseOffset) != 1) { + // wait for test thread to start + } + field = 0x42; + UNSAFE.putLongVolatile(array, arrayBaseOffset, 2); + } + }; + thread.start(); + } + + @Override + protected void after() { + try { + thread.join(); + } catch (InterruptedException e) { + } + } + + public static int testMethod2(int offset) { + int v = field; + long v2 = UNSAFE.getLongVolatile(array, offset); + return v + field + (int) v2; // field load shouldn't common with one above. + } + + @Test + public void test2() { + final StructuredGraph graph = getFinalGraph("testMethod2"); + Assert.assertEquals(2, getFieldReads(graph)); + } + + public static int testMethod3(int offset) { + int v = field; + UNSAFE.putLongVolatile(array, offset, 0x42); + return v + field; // field load shouldn't common with one above. + } + + @Test + public void test3() { + final StructuredGraph graph = getFinalGraph("testMethod3"); + Assert.assertEquals(2, getFieldReads(graph)); + } + + private static int getFieldReads(StructuredGraph graph) { + return graph.getNodes().filter(n -> n instanceof ReadNode).filter(n -> { + final Stamp stamp = ((ReadNode) n).stamp(NodeView.DEFAULT); + return stamp instanceof IntegerStamp && ((IntegerStamp) stamp).getBits() == 32; + }).count(); + } +}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Tue Jun 30 19:20:22 2020 +0200 +++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.virtual/src/org/graalvm/compiler/virtual/phases/ea/PEReadEliminationClosure.java Thu Jul 09 10:20:32 2020 +0200 @@ -179,6 +179,10 @@ } private boolean processUnsafeLoad(RawLoadNode load, PEReadEliminationBlockState state, GraphEffectList effects) { + if (load.isVolatile()) { + state.killReadCache(); + return false; + } if (load.offset().isConstant()) { ResolvedJavaType type = StampTool.typeOrNull(load.object()); if (type != null && type.isArray()) { @@ -205,6 +209,10 @@ } private boolean processUnsafeStore(RawStoreNode store, PEReadEliminationBlockState state, GraphEffectList effects) { + if (store.isVolatile()) { + state.killReadCache(); + return false; + } ResolvedJavaType type = StampTool.typeOrNull(store.object()); if (type != null && type.isArray()) { JavaKind accessKind = store.accessKind();