# HG changeset patch # User Doug Simon # Date 1375824996 -7200 # Node ID a7c7b0bd055762daed3ddb870c4c4ddf7631d60c # Parent cf9603cd8b13b45f57d4ee6c1ffa9ee988c95abf add intrinsics for java.util.zip.CRC32 (GRAAL-385) diff -r cf9603cd8b13 -r a7c7b0bd0557 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 Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java Tue Aug 06 23:36:36 2013 +0200 @@ -31,6 +31,7 @@ import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.Transition.*; import static com.oracle.graal.hotspot.replacements.AESCryptSubstitutions.*; +import static com.oracle.graal.hotspot.replacements.CRC32Substitutions.*; import static com.oracle.graal.hotspot.replacements.CipherBlockChainingSubstitutions.*; import com.oracle.graal.api.code.*; @@ -69,6 +70,7 @@ registerForeignCall(DECRYPT_BLOCK, config.aescryptDecryptBlockStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(ENCRYPT, config.cipherBlockChainingEncryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); + registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION); convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, graalRuntime.getTarget()); super.registerReplacements(replacements); diff -r cf9603cd8b13 -r a7c7b0bd0557 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java Tue Aug 06 23:36:36 2013 +0200 @@ -60,6 +60,10 @@ assert config.aescryptDecryptBlockStub != 0L; assert config.cipherBlockChainingEncryptAESCryptStub != 0L; assert config.cipherBlockChainingDecryptAESCryptStub != 0L; + } else if (substituteMethod.getDeclaringClass() == CRC32Substitutions.class) { + if (!config.useCRC32Intrinsics) { + return null; + } } return super.registerMethodSubstitution(originalMethod, substituteMethod); } diff -r cf9603cd8b13 -r a7c7b0bd0557 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 Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Aug 06 23:36:36 2013 +0200 @@ -108,6 +108,7 @@ public final boolean useBiasedLocking = getVMOption("UseBiasedLocking"); public final boolean usePopCountInstruction = getVMOption("UsePopCountInstruction"); public final boolean useAESIntrinsics = getVMOption("UseAESIntrinsics"); + public final boolean useCRC32Intrinsics = getVMOption("UseCRC32Intrinsics"); public final boolean useG1GC = getVMOption("UseG1GC"); public long gcTotalCollectionsAddress; @@ -484,6 +485,7 @@ public long aescryptDecryptBlockStub; public long cipherBlockChainingEncryptAESCryptStub; public long cipherBlockChainingDecryptAESCryptStub; + public long updateBytesCRC32Stub; public long newInstanceAddress; public long newArrayAddress; @@ -513,6 +515,7 @@ public long arithmeticCosAddress; public long arithmeticTanAddress; public long loadAndClearExceptionAddress; + public long crcTableAddress; public int deoptReasonNone; public int deoptReasonNullCheck; diff -r cf9603cd8b13 -r a7c7b0bd0557 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 Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Tue Aug 06 23:36:36 2013 +0200 @@ -332,6 +332,9 @@ r.registerSubstitutions(AESCryptSubstitutions.class); r.registerSubstitutions(CipherBlockChainingSubstitutions.class); } + if (IntrinsifyCRC32Methods.getValue()) { + r.registerSubstitutions(CRC32Substitutions.class); + } if (IntrinsifyReflectionMethods.getValue()) { r.registerSubstitutions(ReflectionSubstitutions.class); } diff -r cf9603cd8b13 -r a7c7b0bd0557 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java Tue Aug 06 23:36:36 2013 +0200 @@ -0,0 +1,78 @@ +/* + * 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.replacements; + +import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; + +import java.util.zip.*; + +import com.oracle.graal.api.meta.*; +import com.oracle.graal.api.replacements.*; +import com.oracle.graal.graph.Node.*; +import com.oracle.graal.hotspot.nodes.*; +import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.replacements.Snippet.Fold; +import com.oracle.graal.word.*; + +/** + * Substitutions for {@link CRC32}. + */ +@ClassSubstitution(value = CRC32.class) +public class CRC32Substitutions { + + /** + * Gets the address of {@code StubRoutines::x86::_crc_table} in {@code stubRoutines_x86.hpp}. + */ + @Fold + private static long crcTableAddress() { + return graalRuntime().getConfig().crcTableAddress; + } + + @MethodSubstitution(isStatic = true) + static int update(int crc, int b) { + int c = ~crc; + int index = (b ^ c) & 0xFF; + int offset = index << 2; + int result = Word.unsigned(crcTableAddress()).readInt(offset); + result = result ^ (c >>> 8); + return ~result; + } + + @MethodSubstitution(isStatic = true) + static int updateBytes(int crc, byte[] buf, int off, int len) { + Word bufAddr = Word.unsigned(GetObjectAddressNode.get(buf) + arrayBaseOffset(Kind.Byte) + off); + return updateBytes(UPDATE_BYTES_CRC32, crc, bufAddr, len); + } + + @MethodSubstitution(isStatic = true, optional = true) + static int updateByteBuffer(int crc, long addr, int off, int len) { + Word bufAddr = Word.unsigned(addr).add(off); + return updateBytes(UPDATE_BYTES_CRC32, crc, bufAddr, len); + } + + public static final ForeignCallDescriptor UPDATE_BYTES_CRC32 = new ForeignCallDescriptor("updatedBytesCRC32", int.class, int.class, Word.class, int.class); + + @NodeIntrinsic(ForeignCallNode.class) + public static native int updateBytes(@ConstantNodeParameter ForeignCallDescriptor descriptor, int crc, Word buf, int length); +} diff -r cf9603cd8b13 -r a7c7b0bd0557 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/CRC32_updateBytes.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/CRC32_updateBytes.java Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/jdk/CRC32_updateBytes.java Tue Aug 06 23:36:36 2013 +0200 @@ -22,6 +22,7 @@ */ package com.oracle.graal.jtt.jdk; +import java.io.*; import java.util.zip.*; import org.junit.*; @@ -45,4 +46,12 @@ runTest("test", "some string".getBytes()); } + @Test + public void run1() throws Throwable { + String classfileName = CRC32_updateBytes.class.getSimpleName().replace('.', '/') + ".class"; + InputStream s = CRC32_updateBytes.class.getResourceAsStream(classfileName); + byte[] buf = new byte[s.available()]; + new DataInputStream(s).readFully(buf); + runTest("test", buf); + } } diff -r cf9603cd8b13 -r a7c7b0bd0557 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 Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Tue Aug 06 23:36:36 2013 +0200 @@ -308,6 +308,8 @@ @Option(help = "") public static final OptionValue IntrinsifyAESMethods = new OptionValue<>(true); @Option(help = "") + public static final OptionValue IntrinsifyCRC32Methods = new OptionValue<>(true); + @Option(help = "") public static final OptionValue IntrinsifyReflectionMethods = new OptionValue<>(true); @Option(help = "") public static final OptionValue IntrinsifyInstalledCodeMethods = new OptionValue<>(true); diff -r cf9603cd8b13 -r a7c7b0bd0557 graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java --- a/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java Tue Aug 06 22:12:12 2013 +0200 +++ b/graal/com.oracle.graal.replacements.verifier/src/com/oracle/graal/replacements/verifier/MethodSubstitutionVerifier.java Tue Aug 06 23:36:36 2013 +0200 @@ -170,8 +170,11 @@ } } if (originalMethod == null) { - env.getMessager().printMessage(Kind.ERROR, String.format("Could not find the original method with name '%s' and parameters '%s'.", originalName, Arrays.toString(signatureParameters)), - substitutionMethod, substitutionAnnotation); + boolean optional = resolveAnnotationValue(Boolean.class, findAnnotationValue(substitutionAnnotation, "optional")); + if (!optional) { + env.getMessager().printMessage(Kind.ERROR, String.format("Could not find the original method with name '%s' and parameters '%s'.", originalName, Arrays.toString(signatureParameters)), + substitutionMethod, substitutionAnnotation); + } return null; } diff -r cf9603cd8b13 -r a7c7b0bd0557 src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Tue Aug 06 22:12:12 2013 +0200 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Tue Aug 06 23:36:36 2013 +0200 @@ -788,6 +788,7 @@ set_address("aescryptDecryptBlockStub", StubRoutines::aescrypt_decryptBlock()); set_address("cipherBlockChainingEncryptAESCryptStub", StubRoutines::cipherBlockChaining_encryptAESCrypt()); set_address("cipherBlockChainingDecryptAESCryptStub", StubRoutines::cipherBlockChaining_decryptAESCrypt()); + set_address("updateBytesCRC32Stub", StubRoutines::updateBytesCRC32()); set_address("newInstanceAddress", GraalRuntime::new_instance); set_address("newArrayAddress", GraalRuntime::new_array); @@ -815,6 +816,7 @@ set_address("arithmeticSinAddress", CAST_FROM_FN_PTR(address, SharedRuntime::dsin)); set_address("arithmeticCosAddress", CAST_FROM_FN_PTR(address, SharedRuntime::dcos)); set_address("arithmeticTanAddress", CAST_FROM_FN_PTR(address, SharedRuntime::dtan)); + set_address("crcTableAddress", StubRoutines::crc_table_addr()); set_int("deoptReasonNone", Deoptimization::Reason_none); set_int("deoptReasonNullCheck", Deoptimization::Reason_null_check);