changeset 7384:d0fbdf2f7a0e

added com.sun.crypto.provider.CipherBlockChaining intrinsifications
author Doug Simon <doug.simon@oracle.com>
date Tue, 15 Jan 2013 21:11:32 +0100
parents 36474f315a8a
children 6ad818b8892e
files graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSnippetInstaller.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CipherBlockChainingSubstitutions.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java src/share/vm/graal/graalCompilerToVM.cpp
diffstat 9 files changed, 188 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Tue Jan 15 21:11:32 2013 +0100
@@ -38,6 +38,8 @@
 import static com.oracle.graal.hotspot.nodes.VerifyOopStubCall.*;
 import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.DecryptBlockStubCall.*;
 import static com.oracle.graal.hotspot.snippets.AESCryptSubstitutions.EncryptBlockStubCall.*;
+import static com.oracle.graal.hotspot.snippets.CipherBlockChainingSubstitutions.DecryptAESCryptStubCall.*;
+import static com.oracle.graal.hotspot.snippets.CipherBlockChainingSubstitutions.EncryptAESCryptStubCall.*;
 import static com.oracle.graal.lir.amd64.AMD64Call.*;
 
 import com.oracle.graal.api.code.*;
@@ -154,6 +156,24 @@
                 /* arg0:     in */ carg(0, word),
                 /* arg1:    out */ carg(1, word),
                 /* arg2:    key */ carg(2, word));
+
+        addRuntimeCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub,
+                /*        temps */ null,
+                /*          ret */ ret(Kind.Void),
+                /* arg0:     in */ carg(0, word),
+                /* arg1:    out */ carg(1, word),
+                /* arg2:    key */ carg(2, word),
+                /* arg3:      r */ carg(3, word),
+              /* arg4: inLength */ carg(4, Kind.Int));
+
+        addRuntimeCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub,
+                /*        temps */ null,
+                /*          ret */ ret(Kind.Void),
+                /* arg0:     in */ carg(0, word),
+                /* arg1:    out */ carg(1, word),
+                /* arg2:    key */ carg(2, word),
+                /* arg3:      r */ carg(3, word),
+              /* arg4: inLength */ carg(4, Kind.Int));
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSnippetInstaller.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSnippetInstaller.java	Tue Jan 15 21:11:32 2013 +0100
@@ -49,12 +49,14 @@
                     return;
                 }
             }
-        } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class) {
+        } else if (substituteMethod.getDeclaringClass() == AESCryptSubstitutions.class || substituteMethod.getDeclaringClass() == CipherBlockChainingSubstitutions.class) {
             if (!config.useAESIntrinsics) {
                 return;
             }
             assert config.aescryptEncryptBlockStub != 0L;
             assert config.aescryptDecryptBlockStub != 0L;
+            assert config.cipherBlockChainingEncryptAESCryptStub != 0L;
+            assert config.cipherBlockChainingDecryptAESCryptStub != 0L;
         }
         super.installSubstitution(originalMethod, substituteMethod);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Tue Jan 15 21:11:32 2013 +0100
@@ -338,6 +338,8 @@
     public long identityHashCodeStub;
     public long aescryptEncryptBlockStub;
     public long aescryptDecryptBlockStub;
+    public long cipherBlockChainingEncryptAESCryptStub;
+    public long cipherBlockChainingDecryptAESCryptStub;
 
     public int deoptReasonNullCheck;
     public int deoptReasonRangeCheck;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Tue Jan 15 21:11:32 2013 +0100
@@ -23,7 +23,7 @@
 
 package com.oracle.graal.hotspot.bridge;
 
-import static com.oracle.graal.graph.FieldIntrospection.*;
+import static com.oracle.graal.graph.UnsafeAccess.*;
 
 import java.io.*;
 import java.lang.reflect.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Jan 15 21:11:32 2013 +0100
@@ -322,8 +322,9 @@
         if (GraalOptions.IntrinsifyClassMethods) {
             installer.installSubstitutions(ClassSubstitutions.class);
         }
-        if (GraalOptions.IntrinsifyAESCryptMethods) {
+        if (GraalOptions.IntrinsifyAESMethods) {
             installer.installSubstitutions(AESCryptSubstitutions.class);
+            installer.installSubstitutions(CipherBlockChainingSubstitutions.class);
         }
         if (GraalOptions.IntrinsifyArrayCopy) {
             installer.installSnippets(ArrayCopySnippets.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/AESCryptSubstitutions.java	Tue Jan 15 21:11:32 2013 +0100
@@ -44,13 +44,16 @@
 @ClassSubstitution(className = "com.sun.crypto.provider.AESCrypt")
 public class AESCryptSubstitutions {
 
-    private static final long kOffset;
+    static final long kOffset;
+    static final Class<?> AESCryptClass;
+
     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"));
+            AESCryptClass = Class.forName("com.sun.crypto.provider.AESCrypt", true, cl);
+            kOffset = UnsafeAccess.unsafe.objectFieldOffset(AESCryptClass.getDeclaredField("K"));
         } catch (Exception ex) {
             throw new GraalInternalError(ex);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/snippets/CipherBlockChainingSubstitutions.java	Tue Jan 15 21:11:32 2013 +0100
@@ -0,0 +1,152 @@
+/*
+ * 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 static com.oracle.graal.hotspot.snippets.HotSpotSnippetUtils.*;
+import sun.misc.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.RuntimeCallTarget.Descriptor;
+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.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.snippets.Snippet.Fold;
+import com.oracle.graal.word.*;
+
+/**
+ * Substitutions for {@code com.sun.crypto.provider.CipherBlockChaining} methods.
+ */
+@ClassSubstitution(className = "com.sun.crypto.provider.CipherBlockChaining")
+public class CipherBlockChainingSubstitutions {
+
+    private static final long embeddedCipherOffset;
+    private static final long rOffset;
+    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();
+            embeddedCipherOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.FeedbackCipher", true, cl).getDeclaredField("embeddedCipher"));
+            rOffset = UnsafeAccess.unsafe.objectFieldOffset(Class.forName("com.sun.crypto.provider.CipherBlockChaining", true, cl).getDeclaredField("r"));
+        } catch (Exception ex) {
+            throw new GraalInternalError(ex);
+        }
+    }
+
+    @Fold
+    private static Class getAESCryptClass() {
+        return AESCryptSubstitutions.AESCryptClass;
+    }
+
+    @MethodSubstitution(isStatic = false)
+    static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
+        Object embeddedCipher = Word.fromObject(rcvr).readObject(Word.unsigned(embeddedCipherOffset));
+        if (getAESCryptClass().isInstance(embeddedCipher)) {
+            Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset)).add(arrayBaseOffset(Kind.Byte));
+            Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset)).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);
+            EncryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength);
+        } else {
+            encrypt(rcvr, in, inOffset, inLength, out, outOffset);
+        }
+    }
+
+    @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));
+        if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
+            Word kAddr = Word.fromObject(embeddedCipher).readWord(Word.unsigned(AESCryptSubstitutions.kOffset)).add(arrayBaseOffset(Kind.Byte));
+            Word rAddr = Word.unsigned(GetObjectAddressNode.get(rcvr)).readWord(Word.unsigned(rOffset)).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);
+            DecryptAESCryptStubCall.call(inAddr, outAddr, kAddr, rAddr, inLength);
+        } else {
+            decrypt(rcvr, in, inOffset, inLength, out, outOffset);
+        }
+    }
+
+    public static class EncryptAESCryptStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+        @Input private final ValueNode in;
+        @Input private final ValueNode out;
+        @Input private final ValueNode key;
+        @Input private final ValueNode r;
+        @Input private final ValueNode inLength;
+
+        public static final Descriptor ENCRYPT = new Descriptor("encrypt", false, 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(StampFactory.forVoid());
+            this.in = in;
+            this.out = out;
+            this.key = key;
+            this.r = r;
+            this.inLength = inLength;
+        }
+
+        @Override
+        public void generate(LIRGenerator gen) {
+            RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(ENCRYPT);
+            gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength));
+        }
+
+        @NodeIntrinsic
+        public static native void call(Word in, Word out, Word key, Word r, int inLength);
+    }
+
+    public static class DecryptAESCryptStubCall extends FixedWithNextNode implements LIRGenLowerable {
+
+        @Input private final ValueNode in;
+        @Input private final ValueNode out;
+        @Input private final ValueNode key;
+        @Input private final ValueNode r;
+        @Input private final ValueNode inLength;
+
+        public static final Descriptor DECRYPT = new Descriptor("decrypt", false, void.class, Word.class, Word.class, Word.class, Word.class, int.class);
+
+        public DecryptAESCryptStubCall(ValueNode in, ValueNode out, ValueNode key, ValueNode r, ValueNode inLength) {
+            super(StampFactory.forVoid());
+            this.in = in;
+            this.out = out;
+            this.key = key;
+            this.r = r;
+            this.inLength = inLength;
+        }
+
+        @Override
+        public void generate(LIRGenerator gen) {
+            RuntimeCallTarget stub = gen.getRuntime().lookupRuntimeCall(DECRYPT);
+            gen.emitCall(stub, stub.getCallingConvention(), false, gen.operand(in), gen.operand(out), gen.operand(key), gen.operand(r), gen.operand(inLength));
+        }
+
+        @NodeIntrinsic
+        public static native void call(Word in, Word out, Word key, Word r, int inLength);
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jan 15 21:08:13 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Jan 15 21:11:32 2013 +0100
@@ -208,7 +208,7 @@
     public static boolean IntrinsifyThreadMethods            = true;
     public static boolean IntrinsifyUnsafeMethods            = true;
     public static boolean IntrinsifyMathMethods              = true;
-    public static boolean IntrinsifyAESCryptMethods          = true;
+    public static boolean IntrinsifyAESMethods               = true;
 
     /**
      * Counts the various paths taken through snippets.
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jan 15 21:08:13 2013 +0100
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Tue Jan 15 21:11:32 2013 +0100
@@ -736,6 +736,8 @@
   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_long("cipherBlockChainingEncryptAESCryptStub", VmIds::addStub(StubRoutines::cipherBlockChaining_encryptAESCrypt()));
+  set_long("cipherBlockChainingDecryptAESCryptStub", VmIds::addStub(StubRoutines::cipherBlockChaining_decryptAESCrypt()));
 
   set_int("deoptReasonNone", Deoptimization::Reason_none);
   set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check);