# HG changeset patch # User Doug Simon # Date 1368823555 -7200 # Node ID 20963f52fdd5add0a7d326ac566ea419b5921ae6 # Parent 8a1b0a3d4fc34e7c9c8ced5eecbb34bce4241ade# Parent 2461285a2f90ba06aa9eb30c1285be956cd86d01 Merge. diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Fri May 17 22:45:55 2013 +0200 @@ -426,18 +426,29 @@ } long start = System.currentTimeMillis(); PhasePlan phasePlan = new PhasePlan(); - StructuredGraph graphCopy = graph.copy(); + final StructuredGraph graphCopy = graph.copy(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); phasePlan.addPhase(PhasePosition.LOW_LEVEL, new WriteBarrierAdditionPhase()); editPhasePlan(method, graph, phasePlan); CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false); - CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, + final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog()); if (printCompilation) { TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize())); } - return addMethod(method, compResult, graphCopy); + return Debug.scope("CodeInstall", new Object[]{runtime, method}, new Callable() { + + @Override + public InstalledCode call() throws Exception { + InstalledCode code = addMethod(method, compResult, graphCopy); + if (Debug.isDumpEnabled()) { + Debug.dump(new Object[]{compResult, code}, "After code installation"); + } + + return code; + } + }); } }); @@ -448,18 +459,7 @@ } protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult, final StructuredGraph graph) { - return Debug.scope("CodeInstall", new Object[]{runtime, method}, new Callable() { - - @Override - public InstalledCode call() throws Exception { - InstalledCode installedCode = runtime.addMethod(method, compResult, graph); - if (Debug.isDumpEnabled()) { - Debug.dump(new Object[]{compResult, installedCode}, "After code installation"); - } - - return installedCode; - } - }); + return runtime.addMethod(method, compResult, graph); } /** diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Fri May 17 22:45:55 2013 +0200 @@ -231,14 +231,16 @@ } } } - if (!hsLinkage.isLeaf()) { - append(new AMD64HotSpotCRuntimeCallPrologueOp()); - } - Variable result = super.emitForeignCall(linkage, info, args); + Variable result; if (!hsLinkage.isLeaf()) { + assert info != null; + append(new AMD64HotSpotCRuntimeCallPrologueOp()); + result = super.emitForeignCall(linkage, info, args); append(new AMD64HotSpotCRuntimeCallEpilogueOp()); + } else { + result = super.emitForeignCall(linkage, null, args); } if (destroysRegisters) { diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Fri May 17 22:45:55 2013 +0200 @@ -29,10 +29,8 @@ import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; -import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.DecryptBlockStubCall.*; -import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.EncryptBlockStubCall.*; -import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*; -import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*; +import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.*; +import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.*; import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java Fri May 17 22:45:55 2013 +0200 @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2013, 2013, 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.hotspot.test; + +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; + +import java.io.*; +import java.lang.reflect.*; +import java.security.*; + +import javax.crypto.*; + +import org.junit.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.compiler.test.*; +import com.oracle.graal.hotspot.*; +import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.nodes.*; + +/** + * Tests the intrinsification of certain crypto methods. + */ +public class HotSpotCryptoSubstitutionTest extends GraalCompilerTest { + + @Override + protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, StructuredGraph graph) { + HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method; + HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, graph, true); + HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult); + CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null); + Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK); + + // HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime; + // TTY.println(hsMethod.toString()); + // TTY.println(hsRuntime.disassemble(installedCode)); + return installedCode; + } + + @Test + public void testAESEncryptSubstitution() throws Exception { + byte[] seed = {0x4, 0x7, 0x1, 0x1}; + SecureRandom random = new SecureRandom(seed); + KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES"); + aesKeyGen.init(128, random); + SecretKey aesKey = aesKeyGen.generateKey(); + byte[] input = readClassfile16(getClass()); + + ByteArrayOutputStream expected = new ByteArrayOutputStream(); + expected.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); + expected.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); + + if (compiledAndInstall("com.sun.crypto.provider.AESCrypt", "encryptBlock", "decryptBlock")) { + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); + actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); + Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray()); + } + + if (compiledAndInstall("com.sun.crypto.provider.CipherBlockChaining", "encrypt", "decrypt")) { + ByteArrayOutputStream actual = new ByteArrayOutputStream(); + actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input)); + actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input)); + Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray()); + } + } + + /** + * Compiles and installs the substitution for some specified methods. Once installed, the next + * execution of the methods will use the newly installed code. + * + * @param className the name of the class for which substitutions are available + * @param methodNames the names of the substituted methods + * @return true if at least one substitution was compiled and installed + */ + private boolean compiledAndInstall(String className, String... methodNames) { + boolean atLeastOneCompiled = false; + for (String methodName : methodNames) { + Method method = lookup(className, methodName); + if (method != null) { + ResolvedJavaMethod installedCodeOwner = runtime.lookupJavaMethod(method); + StructuredGraph graph = replacements.getMethodSubstitution(installedCodeOwner); + if (graph != null) { + Assert.assertNotNull(getCode(installedCodeOwner, graph, true)); + atLeastOneCompiled = true; + } else { + Assert.assertFalse(graalRuntime().getConfig().useAESIntrinsics); + } + } + } + return atLeastOneCompiled; + } + + private static Method lookup(String className, String methodName) { + Class c; + try { + c = Class.forName(className); + for (Method m : c.getDeclaredMethods()) { + if (m.getName().equals(methodName)) { + return m; + } + } + // If the expected security provider exists, the specific method should also exist + throw new NoSuchMethodError(className + "." + methodName); + } catch (ClassNotFoundException e) { + // It's ok to not find the class - a different security provider + // may have been installed + return null; + } + } + + AlgorithmParameters algorithmParameters; + + private byte[] encrypt(byte[] indata, SecretKey key, String algorithm) throws Exception { + + byte[] result = indata; + + Cipher c = Cipher.getInstance(algorithm); + c.init(Cipher.ENCRYPT_MODE, key); + algorithmParameters = c.getParameters(); + + byte[] r1 = c.update(result); + byte[] r2 = c.doFinal(); + + result = new byte[r1.length + r2.length]; + System.arraycopy(r1, 0, result, 0, r1.length); + System.arraycopy(r2, 0, result, r1.length, r2.length); + + return result; + } + + private byte[] decrypt(byte[] indata, SecretKey key, String algorithm) throws Exception { + + byte[] result = indata; + + Cipher c = Cipher.getInstance(algorithm); + c.init(Cipher.DECRYPT_MODE, key, algorithmParameters); + + byte[] r1 = c.update(result); + byte[] r2 = c.doFinal(); + + result = new byte[r1.length + r2.length]; + System.arraycopy(r1, 0, result, 0, r1.length); + System.arraycopy(r2, 0, result, r1.length, r2.length); + return result; + } + + private static byte[] readClassfile16(Class c) throws IOException { + String classFilePath = "/" + c.getName().replace('.', '/') + ".class"; + InputStream stream = c.getResourceAsStream(classFilePath); + int bytesToRead = stream.available(); + bytesToRead -= bytesToRead % 16; + byte[] classFile = new byte[bytesToRead]; + new DataInputStream(stream).readFully(classFile); + return classFile; + } + + public byte[] runEncryptDecrypt(SecretKey key, String algorithm, byte[] input) throws Exception { + byte[] indata = input.clone(); + byte[] cipher = encrypt(indata, key, algorithm); + byte[] plain = decrypt(cipher, key, algorithm); + Assert.assertArrayEquals(indata, plain); + return plain; + } +} diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri May 17 22:45:55 2013 +0200 @@ -31,17 +31,16 @@ import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; import static com.oracle.graal.hotspot.nodes.NewArrayStubCall.*; import static com.oracle.graal.hotspot.nodes.NewInstanceStubCall.*; import static com.oracle.graal.hotspot.nodes.NewMultiArrayStubCall.*; -import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*; import static com.oracle.graal.hotspot.nodes.VMErrorNode.*; -import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPostStubCall.*; import static com.oracle.graal.hotspot.nodes.WriteBarrierPreStubCall.*; +import static com.oracle.graal.hotspot.replacements.MonitorSnippets.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; +import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*; import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*; import static com.oracle.graal.hotspot.stubs.NewArrayStub.*; import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*; @@ -95,6 +94,7 @@ public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class); public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class); + public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class); public final HotSpotVMConfig config; diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorEnterStubCall.java Fri May 17 17:43:01 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2012, 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.hotspot.nodes; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; -import com.oracle.graal.word.*; - -/** - * Node implementing a call to {@code GraalRuntime::monitorenter}. - */ -public class MonitorEnterStubCall extends DeoptimizingStubCall implements LIRGenLowerable { - - @Input private ValueNode object; - @Input private ValueNode lock; - public static final ForeignCallDescriptor MONITORENTER = new ForeignCallDescriptor("monitorenter", void.class, Object.class, Word.class); - - public MonitorEnterStubCall(ValueNode object, ValueNode lock) { - super(StampFactory.forVoid()); - this.object = object; - this.lock = lock; - } - - @Override - public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(MONITORENTER); - gen.emitForeignCall(linkage, this, gen.operand(object), gen.operand(lock)); - } - - @NodeIntrinsic - public static native void call(Object object, Word lock); -} diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ThreadIsInterruptedStubCall.java Fri May 17 17:43:01 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2012, 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.hotspot.nodes; - -import java.lang.reflect.*; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; - -/** - * Node implementing a call to {@code GraalRuntime::thread_is_interrupted}. - */ -public class ThreadIsInterruptedStubCall extends DeoptimizingStubCall implements LIRGenLowerable { - - @Input private ValueNode thread; - @Input private ValueNode clearIsInterrupted; - public static final ForeignCallDescriptor THREAD_IS_INTERRUPTED = new ForeignCallDescriptor("thread_is_interrupted", boolean.class, Object.class, boolean.class); - - public ThreadIsInterruptedStubCall(ValueNode thread, ValueNode clearIsInterrupted) { - super(StampFactory.forInteger(Kind.Int, 0, 1)); - this.thread = thread; - this.clearIsInterrupted = clearIsInterrupted; - } - - @Override - public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(ThreadIsInterruptedStubCall.THREAD_IS_INTERRUPTED); - Variable result = gen.emitForeignCall(linkage, this, gen.operand(thread), gen.operand(clearIsInterrupted)); - gen.setResult(this, result); - } - - @NodeIntrinsic - public static boolean call(Thread thread, boolean clearIsInterrupted) { - try { - Method isInterrupted = Thread.class.getDeclaredMethod("isInterrupted", boolean.class); - isInterrupted.setAccessible(true); - return (Boolean) isInterrupted.invoke(thread, clearIsInterrupted); - } catch (Exception e) { - throw new GraalInternalError(e); - } - } -} diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VerifyOopStubCall.java Fri May 17 17:43:01 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2012, 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.hotspot.nodes; - -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; -import com.oracle.graal.hotspot.stubs.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; - -/** - * Call to {@link VerifyOopStub}. - */ -public class VerifyOopStubCall extends DeoptimizingStubCall implements LIRGenLowerable { - - @Input private ValueNode object; - public static final ForeignCallDescriptor VERIFY_OOP = new ForeignCallDescriptor("verify_oop", Object.class, Object.class); - - public VerifyOopStubCall(ValueNode object) { - super(StampFactory.objectNonNull()); - this.object = object; - } - - @Override - public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(VerifyOopStubCall.VERIFY_OOP); - gen.emitForeignCall(linkage, this, gen.operand(object)); - } - - @NodeIntrinsic - public static native Object call(Object object); -} diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java Fri May 17 22:45:55 2013 +0200 @@ -25,15 +25,13 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import sun.misc.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.*; /** @@ -72,56 +70,18 @@ Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset); if (encrypt) { - EncryptBlockStubCall.call(inAddr, outAddr, kAddr); + encryptBlockStub(ENCRYPT_BLOCK, inAddr, outAddr, kAddr); } else { - DecryptBlockStubCall.call(inAddr, outAddr, kAddr); + decryptBlockStub(DECRYPT_BLOCK, inAddr, outAddr, kAddr); } } - abstract static class CryptBlockStubCall extends DeoptimizingStubCall implements LIRGenLowerable { - - @Input private ValueNode in; - @Input private ValueNode out; - @Input private ValueNode key; - - private final ForeignCallDescriptor descriptor; - - public CryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key, ForeignCallDescriptor descriptor) { - super(StampFactory.forVoid()); - this.in = in; - this.out = out; - this.key = key; - this.descriptor = descriptor; - } - - @Override - public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor); - gen.emitForeignCall(linkage, null, gen.operand(in), gen.operand(out), gen.operand(key)); - } - } + public static final ForeignCallDescriptor ENCRYPT_BLOCK = new ForeignCallDescriptor("encrypt_block", void.class, Word.class, Word.class, Word.class); + public static final ForeignCallDescriptor DECRYPT_BLOCK = new ForeignCallDescriptor("decrypt_block", void.class, Word.class, Word.class, Word.class); - public static class EncryptBlockStubCall extends CryptBlockStubCall { - - public static final ForeignCallDescriptor ENCRYPT_BLOCK = new ForeignCallDescriptor("encrypt_block", void.class, Word.class, Word.class, Word.class); - - public EncryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) { - super(in, out, key, ENCRYPT_BLOCK); - } - - @NodeIntrinsic - public static native void call(Word in, Word out, Word key); - } + @NodeIntrinsic(ForeignCallNode.class) + public static native void encryptBlockStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Word key); - public static class DecryptBlockStubCall extends CryptBlockStubCall { - - public static final ForeignCallDescriptor DECRYPT_BLOCK = new ForeignCallDescriptor("decrypt_block", void.class, Word.class, Word.class, Word.class); - - public DecryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) { - super(in, out, key, DECRYPT_BLOCK); - } - - @NodeIntrinsic - public static native void call(Word in, Word out, Word key); - } + @NodeIntrinsic(ForeignCallNode.class) + public static native void decryptBlockStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Word key); } diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java Fri May 17 22:45:55 2013 +0200 @@ -25,15 +25,13 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import sun.misc.*; -import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.gen.*; -import com.oracle.graal.compiler.target.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.nodes.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.replacements.Snippet.Fold; import com.oracle.graal.word.*; @@ -72,19 +70,6 @@ } } - private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { - Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); - Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); - Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); - Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset); - if (encrypt) { - EncryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength); - } else { - DecryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength); - } - - } - @MethodSubstitution(isStatic = false) static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) { Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset), ANY_LOCATION); @@ -95,54 +80,24 @@ } } - abstract static class AESCryptStubCall extends DeoptimizingStubCall implements LIRGenLowerable { - - @Input private ValueNode in; - @Input private ValueNode out; - @Input private ValueNode key; - @Input private ValueNode r; - @Input private ValueNode inLength; - - private final ForeignCallDescriptor descriptor; - - public AESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength, ForeignCallDescriptor descriptor) { - super(StampFactory.forVoid()); - this.in = in; - this.out = out; - this.key = key; - this.r = r; - this.inLength = inLength; - this.descriptor = descriptor; - } - - @Override - public void generate(LIRGenerator gen) { - ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor); - gen.emitForeignCall(linkage, null, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength)); + private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) { + Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); + Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset), ANY_LOCATION).add(arrayBaseOffset(Kind.Byte)); + Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset); + Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset); + if (encrypt) { + encryptAESCryptStub(ENCRYPT, inAddr, outAddr, kAddr, rAddr, inLength); + } else { + decryptAESCryptStub(DECRYPT, inAddr, outAddr, kAddr, rAddr, inLength); } } - public static class EncryptAESCryptStubCall extends AESCryptStubCall { - - public static final ForeignCallDescriptor ENCRYPT = new ForeignCallDescriptor("encrypt", void.class, Word.class, Word.class, Word.class, Word.class, int.class); - - public EncryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) { - super(in, out, key, r, inLength, ENCRYPT); - } - - @NodeIntrinsic - public static native void call(Word in, Word out, Word key, Word r, int inLength); - } + public static final ForeignCallDescriptor ENCRYPT = new ForeignCallDescriptor("encrypt", void.class, Word.class, Word.class, Word.class, Word.class, int.class); + public static final ForeignCallDescriptor DECRYPT = new ForeignCallDescriptor("decrypt", void.class, Word.class, Word.class, Word.class, Word.class, int.class); - public static class DecryptAESCryptStubCall extends AESCryptStubCall { - - public static final ForeignCallDescriptor DECRYPT = new ForeignCallDescriptor("decrypt", void.class, Word.class, Word.class, Word.class, Word.class, int.class); + @NodeIntrinsic(ForeignCallNode.class) + public static native void encryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Word key, Word r, int inLength); - public DecryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) { - super(in, out, key, r, inLength, DECRYPT); - } - - @NodeIntrinsic - public static native void call(Word in, Word out, Word key, Word r, int inLength); - } + @NodeIntrinsic(ForeignCallNode.class) + public static native void decryptAESCryptStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Word in, Word out, Word key, Word r, int inLength); } diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java Fri May 17 22:45:55 2013 +0200 @@ -33,7 +33,6 @@ import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.extended.LocationNode.LocationIdentity; import com.oracle.graal.replacements.Snippet.Fold; @@ -450,11 +449,14 @@ public static Object verifyOop(Object object) { if (verifyOops()) { - VerifyOopStubCall.call(object); + verifyOopStub(VERIFY_OOP, object); } return object; } + @NodeIntrinsic(ForeignCallNode.class) + private static native Object verifyOopStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object); + /** * Gets the value of the stack pointer register as a Word. */ diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Fri May 17 22:45:55 2013 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.hotspot.nodes.*; @@ -159,7 +160,7 @@ // owns the bias and we need to revoke that bias. The revocation will occur // in the interpreter runtime. traceObject(trace, "+lock{stub:revoke}", object); - MonitorEnterStubCall.call(object, lock); + monitorenterStub(MONITORENTER, object, lock); return; } else { // At this point we know the epoch has expired, meaning that the @@ -179,7 +180,7 @@ // succeeded in biasing it toward itself and we need to revoke that // bias. The revocation will occur in the runtime in the slow case. traceObject(trace, "+lock{stub:epoch-expired}", object); - MonitorEnterStubCall.call(object, lock); + monitorenterStub(MONITORENTER, object, lock); return; } } else { @@ -236,7 +237,7 @@ if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) { // Most likely not a recursive lock, go into a slow runtime call traceObject(trace, "+lock{stub:failed-cas}", object); - MonitorEnterStubCall.call(object, lock); + monitorenterStub(MONITORENTER, object, lock); return; } else { // Recursively locked => write 0 to the lock slot @@ -262,7 +263,7 @@ // cannot float about the null check above final Word lock = beginLockScope(lockDepth); traceObject(trace, "+lock{stub}", object); - MonitorEnterStubCall.call(object, lock); + monitorenterStub(MONITORENTER, object, lock); } @Snippet @@ -517,4 +518,10 @@ } } } + + public static final ForeignCallDescriptor MONITORENTER = new ForeignCallDescriptor("monitorenter", void.class, Object.class, Word.class); + + @NodeIntrinsic(ForeignCallNode.class) + private static native void monitorenterStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Object object, Word lock); + } diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ThreadSubstitutions.java Fri May 17 22:45:55 2013 +0200 @@ -24,8 +24,15 @@ import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; +import java.lang.reflect.*; + +import com.oracle.graal.api.meta.*; import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.Node.ConstantNodeParameter; +import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.*; /** @@ -51,6 +58,22 @@ } } - return ThreadIsInterruptedStubCall.call(thisObject, clearInterrupted); + return threadIsInterruptedStub(THREAD_IS_INTERRUPTED, thisObject, clearInterrupted); + } + + public static final ForeignCallDescriptor THREAD_IS_INTERRUPTED = new ForeignCallDescriptor("thread_is_interrupted", boolean.class, Object.class, boolean.class); + + /** + * @param descriptor + */ + @NodeIntrinsic(ForeignCallNode.class) + private static boolean threadIsInterruptedStub(@ConstantNodeParameter ForeignCallDescriptor descriptor, Thread thread, boolean clearIsInterrupted) { + try { + Method isInterrupted = Thread.class.getDeclaredMethod("isInterrupted", boolean.class); + isInterrupted.setAccessible(true); + return (Boolean) isInterrupted.invoke(thread, clearIsInterrupted); + } catch (Exception e) { + throw new GraalInternalError(e); + } } } diff -r 2461285a2f90 -r 20963f52fdd5 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Fri May 17 17:43:01 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java Fri May 17 22:45:55 2013 +0200 @@ -27,12 +27,11 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; /** - * Stub called from {@link VerifyOopStubCall}. + * Stub called via {@link HotSpotRuntime#VERIFY_OOP}. */ public class VerifyOopStub extends SnippetStub {