# HG changeset patch # User Doug Simon # Date 1358118894 -3600 # Node ID f4f3d63d35e6a168b29ccc263eb2398728bd62ab # Parent 3a8e79636f8eac852b6b740c3f4b155f789a3fd1 AESCrypt intrinsification - disabled by default as it doesn't yet work diff -r 3a8e79636f8e -r f4f3d63d35e6 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 Sun Jan 13 21:55:49 2013 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Mon Jan 14 00:14:54 2013 +0100 @@ -25,6 +25,7 @@ import static com.oracle.graal.amd64.AMD64.*; import static com.oracle.graal.compiler.amd64.AMD64DeoptimizationStub.*; import static com.oracle.graal.compiler.amd64.AMD64LIRGenerator.*; +import static com.oracle.graal.hotspot.nodes.IdentityHashCodeStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorEnterStubCall.*; import static com.oracle.graal.hotspot.nodes.MonitorExitStubCall.*; import static com.oracle.graal.hotspot.nodes.NewArraySlowStubCall.*; @@ -32,10 +33,11 @@ import static com.oracle.graal.hotspot.nodes.NewInstanceSlowStubCall.*; 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.IdentityHashCodeStubCall.*; -import static com.oracle.graal.hotspot.nodes.ThreadIsInterruptedStubCall.*; +import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.DecryptBlockStubCall.*; +import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.EncryptBlockStubCall.*; import static com.oracle.graal.lir.amd64.AMD64Call.*; import com.oracle.graal.api.code.*; @@ -138,6 +140,20 @@ /* ret */ rax.asValue(Kind.Int), /* arg0: thread */ arg(0, Kind.Object), /* arg1: clearInterrupted */ arg(1, Kind.Boolean)); + + addRuntimeCall(ENCRYPT_BLOCK, config.aescryptEncryptBlockStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: in */ arg(0, word), + /* arg1: out */ arg(1, word), + /* arg2: key */ arg(2, word)); + + addRuntimeCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, + /* temps */ null, + /* ret */ ret(Kind.Void), + /* arg0: in */ arg(0, word), + /* arg1: out */ arg(1, word), + /* arg2: key */ arg(2, word)); } @Override diff -r 3a8e79636f8e -r f4f3d63d35e6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Sun Jan 13 21:55:49 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Jan 14 00:14:54 2013 +0100 @@ -334,6 +334,8 @@ public int deoptReasonNone; public long threadIsInterruptedStub; public long identityHashCodeStub; + public long aescryptEncryptBlockStub; + public long aescryptDecryptBlockStub; public int deoptReasonNullCheck; public int deoptReasonRangeCheck; diff -r 3a8e79636f8e -r f4f3d63d35e6 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 Sun Jan 13 21:55:49 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Mon Jan 14 00:14:54 2013 +0100 @@ -317,6 +317,14 @@ if (GraalOptions.IntrinsifyClassMethods) { installer.installSubstitutions(ClassSubstitutions.class); } + if (GraalOptions.IntrinsifyAESCryptMethods) { + if (graalRuntime.getConfig().aescryptEncryptBlockStub != 0L) { + installer.installSubstitutions(AESCryptSubstitutions.class); + } else { + // AES not supported on this CPU + assert graalRuntime.getConfig().aescryptDecryptBlockStub == 0L; + } + } if (GraalOptions.IntrinsifyArrayCopy) { installer.installSnippets(ArrayCopySnippets.class); } diff -r 3a8e79636f8e -r f4f3d63d35e6 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java Mon Jan 14 00:14:54 2013 +0100 @@ -0,0 +1,122 @@ +/* + * 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.snippets; + +import sun.misc.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor; +import com.oracle.graal.compiler.gen.*; +import com.oracle.graal.compiler.target.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.graal.snippets.*; +import com.oracle.graal.snippets.ClassSubstitution.MethodSubstitution; +import com.oracle.graal.word.*; + +/** + * Substitutions for {@code com.sun.crypto.provider.AESCrypt} methods. + */ +@ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt") +public class AESCryptSubstitutions { + + private static final long kOffset; + static { + try { + // Need to use launcher class path as com.sun.crypto.provider.AESCrypt + // is normally not on the boot class path + ClassLoader cl = Launcher.getLauncher().getClassLoader(); + kOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.AESCrypt", true, cl).getDeclaredField("K")); + } catch (Exception ex) { + throw new GraalInternalError(ex); + } + } + + @MethodSubstitution(isStatic = false) + static void encryptBlock(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) { + Word kAddr = Word.unsigned(GetObjectAddressNode.get(rcvr) + kOffset); + Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + inOffset); + Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + outOffset); + EncryptBlockStubCall.call(inAddr, outAddr, kAddr); + } + + @MethodSubstitution(isStatic = false) + static void decryptBlock(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset) { + Word kAddr = Word.unsigned(GetObjectAddressNode.get(rcvr) + kOffset); + Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + inOffset); + Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + outOffset); + DecryptBlockStubCall.call(inAddr, outAddr, kAddr); + } + + public static class EncryptBlockStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private final ValueNode in; + @Input private final ValueNode out; + @Input private final ValueNode key; + + public static final Descriptor ENCRYPT_BLOCK = new Descriptor("encrypt_block", false, void.class, Word.class, Word.class, Word.class); + + public EncryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) { + super(StampFactory.forVoid()); + this.in = in; + this.out = out; + this.key = key; + } + + @Override + public void generate(LIRGenerator gen) { + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(ENCRYPT_BLOCK); + gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(in), gen.operand(out), gen.operand(key)); + } + + @NodeIntrinsic + public static native void call(Word in, Word out, Word key); + } + + public static class DecryptBlockStubCall extends FixedWithNextNode implements LIRGenLowerable { + + @Input private final ValueNode in; + @Input private final ValueNode out; + @Input private final ValueNode key; + + public static final Descriptor DECRYPT_BLOCK = new Descriptor("decrypt_block", false, void.class, Word.class, Word.class, Word.class); + + public DecryptBlockStubCall(ValueNode in, ValueNode out, ValueNode key) { + super(StampFactory.forVoid()); + this.in = in; + this.out = out; + this.key = key; + } + + @Override + public void generate(LIRGenerator gen) { + RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(DECRYPT_BLOCK); + gen.emitCall(stub, stub.getCallingConvention(), true, gen.operand(in), gen.operand(out), gen.operand(key)); + } + + @NodeIntrinsic + public static native void call(Word in, Word out, Word key); + } +} diff -r 3a8e79636f8e -r f4f3d63d35e6 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Sun Jan 13 21:55:49 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Jan 14 00:14:54 2013 +0100 @@ -208,6 +208,7 @@ public static boolean IntrinsifyThreadMethods = true; public static boolean IntrinsifyUnsafeMethods = true; public static boolean IntrinsifyMathMethods = true; + public static boolean IntrinsifyAESCryptMethods = false; // TODO (ds) make true once AES stubs are working /** * Counts the various paths taken through snippets. diff -r 3a8e79636f8e -r f4f3d63d35e6 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Sun Jan 13 21:55:49 2013 +0100 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Jan 14 00:14:54 2013 +0100 @@ -732,6 +732,8 @@ set_long("logPrimitiveStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_primitive_id))); set_long("logObjectStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_object_id))); set_long("logPrintfStub", VmIds::addStub(GraalRuntime::entry_for(GraalRuntime::graal_log_printf_id))); + set_long("aescryptEncryptBlockStub", VmIds::addStub(StubRoutines::aescrypt_encryptBlock())); + set_long("aescryptDecryptBlockStub", VmIds::addStub(StubRoutines::aescrypt_decryptBlock())); set_int("deoptReasonNone", Deoptimization::Reason_none); set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check);