1 /*
2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 package org.graalvm.compiler.hotspot.test;
26
27 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.referentOffset;
28
29 import java.lang.ref.WeakReference;
30
31 import org.graalvm.compiler.api.replacements.Fold;
32 import org.graalvm.compiler.debug.DebugContext;
33 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
34 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfigBase;
35 import org.graalvm.compiler.nodes.StructuredGraph;
36 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
37 import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
38 import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
39 import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
40 import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
41 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
42 import org.graalvm.compiler.nodes.graphbuilderconf.NodeIntrinsicPluginFactory;
43 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
44 import org.graalvm.compiler.nodes.memory.ReadNode;
45 import org.graalvm.compiler.nodes.memory.WriteNode;
46 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
47 import org.graalvm.compiler.nodes.spi.LoweringTool;
48 import org.graalvm.compiler.phases.OptimisticOptimizations;
49 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
50 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
51 import org.graalvm.compiler.phases.common.LoweringPhase;
52 import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
53 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
54 import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
55 import org.graalvm.compiler.phases.tiers.HighTierContext;
56 import org.graalvm.compiler.phases.tiers.MidTierContext;
57 import org.graalvm.compiler.replacements.NodeIntrinsificationProvider;
58 import org.junit.Assert;
59 import org.junit.Test;
60
61 import jdk.vm.ci.hotspot.HotSpotInstalledCode;
62 import jdk.vm.ci.meta.JavaConstant;
63 import jdk.vm.ci.meta.ResolvedJavaMethod;
64 import sun.misc.Unsafe;
65
66 /**
67 * The following unit tests assert the presence of write barriers for both Serial and G1 GCs.
68 * Normally, the tests check for compile time inserted barriers. However, there are the cases of
69 * unsafe loads of the java.lang.ref.Reference.referent field where runtime checks have to be
70 * performed also. For those cases, the unit tests check the presence of the compile-time inserted
71 * barriers. Concerning the runtime checks, the results of variable inputs (object types and
72 * offsets) passed as input parameters can be checked against printed output from the G1 write
73 * barrier snippets. The runtime checks have been validated offline.
74 */
75 public class WriteBarrierAdditionTest extends HotSpotGraalCompilerTest {
76
77 private final GraalHotSpotVMConfig config = runtime().getVMConfig();
144
145 /**
146 * Expected 2 barriers for the Serial GC and 5 for G1 (3 pre + 2 post) The (2 or 4) barriers are
147 * emitted while initializing the fields of the WeakReference instance. The extra pre barrier of
148 * G1 concerns the read of the referent field.
149 */
150 @Test
151 public void test4() throws Exception {
152 testHelper("test4Snippet", config.useG1GC ? 5 : 2);
153 }
154
155 public static Object test4Snippet() {
156 WeakReference<Object> weakRef = new WeakReference<>(new Object());
157 return weakRef.get();
158 }
159
160 static WeakReference<Object> wr = new WeakReference<>(new Object());
161 static Container con = new Container();
162
163 /**
164 * Expected 4 barriers for the Serial GC and 9 for G1 (1 ref + 4 pre + 4 post). In this test, we
165 * load the correct offset of the WeakReference object so naturally we assert the presence of
166 * the pre barrier.
167 */
168 @Test
169 public void test5() throws Exception {
170 testHelper("test5Snippet", config.useG1GC ? 1 : 0);
171 }
172
173 @Override
174 protected void registerInvocationPlugins(InvocationPlugins invocationPlugins) {
175 NodeIntrinsicPluginFactory.InjectionProvider injection = new NodeIntrinsificationProvider(getMetaAccess(), getSnippetReflection(), getProviders().getForeignCalls(), null);
176 new PluginFactory_WriteBarrierAdditionTest().registerPlugins(invocationPlugins, injection);
177 super.registerInvocationPlugins(invocationPlugins);
178 }
179
180 @Fold
181 public static boolean useCompressedOops(@Fold.InjectedParameter GraalHotSpotVMConfig config) {
182 return config.useCompressedOops;
183 }
184
185 public static Object test5Snippet() throws Exception {
186 return UNSAFE.getObject(wr, useCompressedOops(GraalHotSpotVMConfigBase.INJECTED_VMCONFIG) ? 12L : 16L);
187 }
188
189 /**
190 * The following test concerns the runtime checks of the unsafe loads. In this test, we unsafely
191 * load the java.lang.ref.Reference.referent field so the pre barier has to be executed.
192 */
193 @Test
194 public void test6() throws Exception {
195 test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(referentOffset(getMetaAccess())), null);
196 }
197
198 /**
199 * The following test concerns the runtime checks of the unsafe loads. In this test, we unsafely
200 * load a matching offset of a wrong object so the pre barier must not be executed.
201 */
202 @Test
203 public void test7() throws Exception {
204 test2("testUnsafeLoad", UNSAFE, con, Long.valueOf(referentOffset(getMetaAccess())), null);
205 }
206
|
1 /*
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24
25 package org.graalvm.compiler.hotspot.test;
26
27 import static org.graalvm.compiler.hotspot.replacements.HotSpotReplacementsUtil.referentOffset;
28
29 import java.lang.ref.WeakReference;
30
31 import org.graalvm.compiler.api.test.Graal;
32 import org.graalvm.compiler.debug.DebugContext;
33 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
34 import org.graalvm.compiler.hotspot.HotSpotBackend;
35 import org.graalvm.compiler.nodes.StructuredGraph;
36 import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
37 import org.graalvm.compiler.nodes.gc.G1PostWriteBarrier;
38 import org.graalvm.compiler.nodes.gc.G1PreWriteBarrier;
39 import org.graalvm.compiler.nodes.gc.G1ReferentFieldReadBarrier;
40 import org.graalvm.compiler.nodes.gc.SerialWriteBarrier;
41 import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType;
42 import org.graalvm.compiler.nodes.memory.ReadNode;
43 import org.graalvm.compiler.nodes.memory.WriteNode;
44 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
45 import org.graalvm.compiler.nodes.spi.LoweringTool;
46 import org.graalvm.compiler.phases.OptimisticOptimizations;
47 import org.graalvm.compiler.phases.common.CanonicalizerPhase;
48 import org.graalvm.compiler.phases.common.GuardLoweringPhase;
49 import org.graalvm.compiler.phases.common.LoweringPhase;
50 import org.graalvm.compiler.phases.common.WriteBarrierAdditionPhase;
51 import org.graalvm.compiler.phases.common.inlining.InliningPhase;
52 import org.graalvm.compiler.phases.common.inlining.policy.InlineEverythingPolicy;
53 import org.graalvm.compiler.phases.tiers.HighTierContext;
54 import org.graalvm.compiler.phases.tiers.MidTierContext;
55 import org.graalvm.compiler.runtime.RuntimeProvider;
56 import org.junit.Assert;
57 import org.junit.Test;
58
59 import jdk.vm.ci.hotspot.HotSpotInstalledCode;
60 import jdk.vm.ci.meta.JavaConstant;
61 import jdk.vm.ci.meta.ResolvedJavaMethod;
62 import sun.misc.Unsafe;
63
64 /**
65 * The following unit tests assert the presence of write barriers for both Serial and G1 GCs.
66 * Normally, the tests check for compile time inserted barriers. However, there are the cases of
67 * unsafe loads of the java.lang.ref.Reference.referent field where runtime checks have to be
68 * performed also. For those cases, the unit tests check the presence of the compile-time inserted
69 * barriers. Concerning the runtime checks, the results of variable inputs (object types and
70 * offsets) passed as input parameters can be checked against printed output from the G1 write
71 * barrier snippets. The runtime checks have been validated offline.
72 */
73 public class WriteBarrierAdditionTest extends HotSpotGraalCompilerTest {
74
75 private final GraalHotSpotVMConfig config = runtime().getVMConfig();
142
143 /**
144 * Expected 2 barriers for the Serial GC and 5 for G1 (3 pre + 2 post) The (2 or 4) barriers are
145 * emitted while initializing the fields of the WeakReference instance. The extra pre barrier of
146 * G1 concerns the read of the referent field.
147 */
148 @Test
149 public void test4() throws Exception {
150 testHelper("test4Snippet", config.useG1GC ? 5 : 2);
151 }
152
153 public static Object test4Snippet() {
154 WeakReference<Object> weakRef = new WeakReference<>(new Object());
155 return weakRef.get();
156 }
157
158 static WeakReference<Object> wr = new WeakReference<>(new Object());
159 static Container con = new Container();
160
161 /**
162 * Expected 0 barrier for the Serial GC and 1 for G1. In this test, we load the correct offset
163 * of the WeakReference object so naturally we assert the presence of the pre barrier.
164 */
165 @Test
166 public void test5() throws Exception {
167 testHelper("test5Snippet", config.useG1GC ? 1 : 0);
168 }
169
170 private static final boolean useCompressedOops = ((HotSpotBackend) Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend()).getRuntime().getVMConfig().useCompressedOops;
171
172 public Object test5Snippet() {
173 return UNSAFE.getObject(wr, useCompressedOops ? 12L : 16L);
174 }
175
176 /**
177 * The following test concerns the runtime checks of the unsafe loads. In this test, we unsafely
178 * load the java.lang.ref.Reference.referent field so the pre barier has to be executed.
179 */
180 @Test
181 public void test6() throws Exception {
182 test2("testUnsafeLoad", UNSAFE, wr, Long.valueOf(referentOffset(getMetaAccess())), null);
183 }
184
185 /**
186 * The following test concerns the runtime checks of the unsafe loads. In this test, we unsafely
187 * load a matching offset of a wrong object so the pre barier must not be executed.
188 */
189 @Test
190 public void test7() throws Exception {
191 test2("testUnsafeLoad", UNSAFE, con, Long.valueOf(referentOffset(getMetaAccess())), null);
192 }
193
|