# HG changeset patch # User Gilles Duboscq # Date 1434710138 -7200 # Node ID ab879bff09ab11ce77995d9a4cfd75cf44ae01f0 # Parent 3af3e3851ca6b26ad95a11a55a2abfc619f6fdd4 Track and set has_unsafe_access flag diff -r 3af3e3851ca6 -r ab879bff09ab graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MarkUnsafeAccessTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MarkUnsafeAccessTest.java Fri Jun 19 12:35:38 2015 +0200 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2015, 2015, Oracle and/or its affiliates. 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 com.oracle.graal.compiler.test; + +import org.junit.*; + +import sun.misc.*; + +public class MarkUnsafeAccessTest extends GraalCompilerTest { + + public static Unsafe unsafe; + + public void getRaw() { + unsafe.getInt(0L); + } + + public void get() { + unsafe.getInt(null, 0L); + } + + public void putRaw() { + unsafe.putInt(0L, 0); + } + + public void put() { + unsafe.putInt(null, 0L, 0); + } + + public void cas() { + unsafe.compareAndSwapInt(null, 0, 0, 0); + } + + public void noAccess() { + unsafe.addressSize(); + unsafe.pageSize(); + } + + private void assertHasUnsafe(String name, boolean hasUnsafe) { + Assert.assertEquals(hasUnsafe, compile(getResolvedJavaMethod(name), null).hasUnsafeAccess()); + } + + @Test + public void testGet() { + assertHasUnsafe("get", true); + assertHasUnsafe("getRaw", true); + } + + @Test + public void testPut() { + assertHasUnsafe("put", true); + assertHasUnsafe("putRaw", true); + } + + @Test + public void testCas() { + assertHasUnsafe("cas", true); + } + + @Test + public void testNoAcces() { + assertHasUnsafe("noAccess", false); + } +} diff -r 3af3e3851ca6 -r ab879bff09ab graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Jun 19 11:10:15 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Jun 19 12:35:38 2015 +0200 @@ -239,6 +239,7 @@ lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites); try (Scope s2 = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { int bytecodeSize = graph.method() == null ? 0 : graph.getBytecodeSize(); + compilationResult.setHasUnsafeAccess(graph.hasUnsafeAccess()); emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), bytecodeSize, lirGen, compilationResult, installedCodeOwner, factory); } catch (Throwable e) { throw Debug.handle(e); diff -r 3af3e3851ca6 -r ab879bff09ab graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Jun 19 11:10:15 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Fri Jun 19 12:35:38 2015 +0200 @@ -122,6 +122,8 @@ */ private Map inlinedMethods = new HashMap<>(); + private boolean hasUnsafeAccess = false; + /** * Creates a new Graph containing a single {@link AbstractBeginNode} as the {@link #start() * start} node. @@ -609,4 +611,12 @@ public JavaMethod asJavaMethod() { return method(); } + + public boolean hasUnsafeAccess() { + return hasUnsafeAccess; + } + + public void markUnsafeAccess() { + hasUnsafeAccess = true; + } } diff -r 3af3e3851ca6 -r ab879bff09ab graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Fri Jun 19 11:10:15 2015 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Fri Jun 19 12:35:38 2015 +0200 @@ -119,6 +119,7 @@ // Emits a null-check for the otherwise unused receiver unsafe.get(); b.addPush(kind, new AtomicReadAndWriteNode(object, offset, value, kind, LocationIdentity.any())); + b.getGraph().markUnsafeAccess(); return true; } }); @@ -129,6 +130,7 @@ unsafe.get(); AddressNode address = b.add(new OffsetAddressNode(object, offset)); b.addPush(kind, new AtomicReadAndAddNode(address, delta, LocationIdentity.any())); + b.getGraph().markUnsafeAccess(); return true; } }); diff -r 3af3e3851ca6 -r ab879bff09ab graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Fri Jun 19 11:10:15 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java Fri Jun 19 12:35:38 2015 +0200 @@ -88,6 +88,7 @@ } private static final Field STRING_VALUE_FIELD; + static { try { STRING_VALUE_FIELD = String.class.getDeclaredField("value"); @@ -170,6 +171,7 @@ // Emits a null-check for the otherwise unused receiver unsafe.get(); b.addPush(Kind.Int, new CompareAndSwapNode(object, offset, expected, x, kind, LocationIdentity.any())); + b.getGraph().markUnsafeAccess(); return true; } }); @@ -534,6 +536,7 @@ // Emits a null-check for the otherwise unused receiver unsafe.get(); b.addPush(returnKind, new DirectReadNode(address, returnKind)); + b.getGraph().markUnsafeAccess(); return true; } @@ -547,6 +550,7 @@ if (isVolatile) { b.add(new MembarNode(JMM_POST_VOLATILE_READ)); } + b.getGraph().markUnsafeAccess(); return true; } } @@ -565,6 +569,7 @@ // Emits a null-check for the otherwise unused receiver unsafe.get(); b.add(new DirectStoreNode(address, value, kind)); + b.getGraph().markUnsafeAccess(); return true; } @@ -578,6 +583,7 @@ if (isVolatile) { b.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); } + b.getGraph().markUnsafeAccess(); return true; } } diff -r 3af3e3851ca6 -r ab879bff09ab jvmci/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java --- a/jvmci/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Fri Jun 19 11:10:15 2015 +0200 +++ b/jvmci/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Fri Jun 19 12:35:38 2015 +0200 @@ -516,6 +516,8 @@ private int bytecodeSize; + private boolean hasUnsafeAccess; + public CompilationResult() { this(null); } @@ -937,7 +939,16 @@ return name; } + public void setHasUnsafeAccess(boolean hasUnsafeAccess) { + this.hasUnsafeAccess = hasUnsafeAccess; + } + + public boolean hasUnsafeAccess() { + return hasUnsafeAccess; + } + public void reset() { + hasUnsafeAccess = false; infopoints.clear(); dataPatches.clear(); exceptionHandlers.clear(); diff -r 3af3e3851ca6 -r ab879bff09ab jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotCompiledNmethod.java --- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotCompiledNmethod.java Fri Jun 19 11:10:15 2015 +0200 +++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotCompiledNmethod.java Fri Jun 19 12:35:38 2015 +0200 @@ -35,6 +35,7 @@ public final int entryBCI; public final int id; public final long jvmciEnv; + public final boolean hasUnsafeAccess; /** * May be set by VM if code installation fails. It will describe in more detail why installation @@ -52,6 +53,7 @@ this.entryBCI = compResult.getEntryBCI(); this.id = compResult.getId(); this.jvmciEnv = jvmciEnv; + this.hasUnsafeAccess = compResult.hasUnsafeAccess(); } @Override diff -r 3af3e3851ca6 -r ab879bff09ab src/share/vm/jvmci/jvmciCodeInstaller.cpp --- a/src/share/vm/jvmci/jvmciCodeInstaller.cpp Fri Jun 19 11:10:15 2015 +0200 +++ b/src/share/vm/jvmci/jvmciCodeInstaller.cpp Fri Jun 19 12:35:38 2015 +0200 @@ -446,6 +446,7 @@ methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code)); jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code); jint id = HotSpotCompiledNmethod::id(compiled_code); + jboolean has_unsafe_access = HotSpotCompiledNmethod::hasUnsafeAccess(compiled_code); JVMCIEnv* env = (JVMCIEnv*) (address) HotSpotCompiledNmethod::jvmciEnv(compiled_code); if (id == -1) { // Make sure a valid compile_id is associated with every compile @@ -454,7 +455,7 @@ result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, JVMCICompiler::instance(), _debug_recorder, _dependencies, env, id, - false, _has_wide_vector, installed_code, compiled_code, speculation_log); + (bool) has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log); cb = nm; } diff -r 3af3e3851ca6 -r ab879bff09ab src/share/vm/jvmci/jvmciJavaAccess.hpp --- a/src/share/vm/jvmci/jvmciJavaAccess.hpp Fri Jun 19 11:10:15 2015 +0200 +++ b/src/share/vm/jvmci/jvmciJavaAccess.hpp Fri Jun 19 12:35:38 2015 +0200 @@ -92,6 +92,7 @@ int_field(HotSpotCompiledNmethod, entryBCI) \ int_field(HotSpotCompiledNmethod, id) \ long_field(HotSpotCompiledNmethod, jvmciEnv) \ + boolean_field(HotSpotCompiledNmethod, hasUnsafeAccess) \ end_class \ start_class(HotSpotForeignCallTarget) \ long_field(HotSpotForeignCallTarget, address) \