8076112: Add @HotSpotIntrinsicCandidate annotation to indicate methods for which Java Runtime has intrinsics
Summary: Annotate possibly intrinsified methods with @HotSpotIntrinsicCandidate. Add checks omitted by intrinsics to the library code. Add CheckIntrinsics flags to check consistency of intrinsics.
Reviewed-by: jrose, kvn, thartmann, vlivanov, abuckley, darcy, ascarpino, briangoetz, alanb, aph, dnsimon
--- a/jdk/make/mapfiles/libzip/mapfile-vers Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/make/mapfiles/libzip/mapfile-vers Fri Jul 03 07:23:45 2015 +0200
@@ -32,8 +32,8 @@
Java_java_util_zip_Adler32_updateBytes;
Java_java_util_zip_Adler32_updateByteBuffer;
Java_java_util_zip_CRC32_update;
- Java_java_util_zip_CRC32_updateBytes;
- Java_java_util_zip_CRC32_updateByteBuffer;
+ Java_java_util_zip_CRC32_updateBytes0;
+ Java_java_util_zip_CRC32_updateByteBuffer0;
Java_java_util_zip_Deflater_deflateBytes;
Java_java_util_zip_Deflater_end;
Java_java_util_zip_Deflater_getAdler;
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/AESCrypt.java Fri Jul 03 07:23:45 2015 +0200
@@ -38,6 +38,9 @@
import java.security.InvalidKeyException;
import java.util.Arrays;
+import java.util.Objects;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
@@ -346,7 +349,16 @@
* Encrypt exactly one block of plaintext.
*/
void encryptBlock(byte[] in, int inOffset,
- byte[] out, int outOffset)
+ byte[] out, int outOffset) {
+ cryptBlockCheck(in, inOffset);
+ cryptBlockCheck(out, outOffset);
+ implEncryptBlock(in, inOffset, out, outOffset);
+ }
+
+ // Encryption operation. Possibly replaced with a compiler intrinsic.
+ @HotSpotIntrinsicCandidate
+ private void implEncryptBlock(byte[] in, int inOffset,
+ byte[] out, int outOffset)
{
int keyOffset = 0;
int t0 = ((in[inOffset++] ) << 24 |
@@ -412,12 +424,20 @@
out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));
}
-
/**
* Decrypt exactly one block of plaintext.
*/
void decryptBlock(byte[] in, int inOffset,
- byte[] out, int outOffset)
+ byte[] out, int outOffset) {
+ cryptBlockCheck(in, inOffset);
+ cryptBlockCheck(out, outOffset);
+ implDecryptBlock(in, inOffset, out, outOffset);
+ }
+
+ // Decrypt operation. Possibly replaced with a compiler intrinsic.
+ @HotSpotIntrinsicCandidate
+ private void implDecryptBlock(byte[] in, int inOffset,
+ byte[] out, int outOffset)
{
int keyOffset = 4;
int t0 = ((in[inOffset++] ) << 24 |
@@ -572,6 +592,25 @@
out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));
}
+ // Used to perform all checks required by the Java semantics
+ // (i.e., null checks and bounds checks) on the input parameters
+ // to encryptBlock and to decryptBlock.
+ // Normally, the Java Runtime performs these checks, however, as
+ // encryptBlock and decryptBlock are possibly replaced with
+ // compiler intrinsics, the JDK performs the required checks instead.
+ // Does not check accesses to class-internal (private) arrays.
+ private static void cryptBlockCheck(byte[] array, int offset) {
+ Objects.requireNonNull(array);
+
+ if (offset < 0 || offset >= array.length) {
+ throw new ArrayIndexOutOfBoundsException(offset);
+ }
+
+ int largestIndex = offset + AES_BLOCK_SIZE - 1;
+ if (largestIndex < 0 || largestIndex >= array.length) {
+ throw new ArrayIndexOutOfBoundsException(largestIndex);
+ }
+ }
/**
* Expand a user-supplied key material into a session key.
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java Fri Jul 03 07:23:45 2015 +0200
@@ -27,6 +27,9 @@
import java.security.InvalidKeyException;
import java.security.ProviderException;
+import java.util.Objects;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
@@ -138,15 +141,22 @@
* @return the length of the encrypted data
*/
int encrypt(byte[] plain, int plainOffset, int plainLen,
- byte[] cipher, int cipherOffset)
+ byte[] cipher, int cipherOffset) {
+ cryptBlockSizeCheck(plainLen);
+ cryptNullAndBoundsCheck(plain, plainOffset, plainLen);
+ cryptNullAndBoundsCheck(cipher, cipherOffset, plainLen);
+ return implEncrypt(plain, plainOffset, plainLen,
+ cipher, cipherOffset);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private int implEncrypt(byte[] plain, int plainOffset, int plainLen,
+ byte[] cipher, int cipherOffset)
{
- if ((plainLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
int endIndex = plainOffset + plainLen;
for (; plainOffset < endIndex;
- plainOffset+=blockSize, cipherOffset += blockSize) {
+ plainOffset += blockSize, cipherOffset += blockSize) {
for (int i = 0; i < blockSize; i++) {
k[i] = (byte)(plain[i + plainOffset] ^ r[i]);
}
@@ -179,11 +189,17 @@
* @return the length of the decrypted data
*/
int decrypt(byte[] cipher, int cipherOffset, int cipherLen,
- byte[] plain, int plainOffset)
+ byte[] plain, int plainOffset) {
+ cryptBlockSizeCheck(cipherLen);
+ cryptNullAndBoundsCheck(cipher, cipherOffset, cipherLen);
+ cryptNullAndBoundsCheck(plain, plainOffset, cipherLen);
+ return implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private int implDecrypt(byte[] cipher, int cipherOffset, int cipherLen,
+ byte[] plain, int plainOffset)
{
- if ((cipherLen % blockSize) != 0) {
- throw new ProviderException("Internal error in input buffering");
- }
int endIndex = cipherOffset + cipherLen;
for (; cipherOffset < endIndex;
@@ -196,4 +212,27 @@
}
return cipherLen;
}
+
+ private void cryptBlockSizeCheck(int len) {
+ if ((len % blockSize) != 0) {
+ throw new ProviderException("Internal error in input buffering");
+ }
+ }
+
+ private static void cryptNullAndBoundsCheck(byte[] array, int offset, int len) {
+ if (len <= 0) {
+ return; // not an error because cryptImpl/decryptImpl won't execute if len <= 0
+ }
+
+ Objects.requireNonNull(array);
+
+ if (offset < 0 || offset >= array.length) {
+ throw new ArrayIndexOutOfBoundsException(offset);
+ }
+
+ int endIndex = offset + len - 1;
+ if (endIndex < 0 || endIndex >= array.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndex);
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GHASH.java Fri Jul 03 07:23:45 2015 +0200
@@ -31,6 +31,8 @@
import java.security.ProviderException;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* This class represents the GHASH function defined in NIST 800-38D
* under section 6.4. It needs to be constructed w/ a hash subkey, i.e.
@@ -227,6 +229,7 @@
* the hotspot signature. This method and methods called by it, cannot
* throw exceptions or allocate arrays as it will breaking intrinsics
*/
+ @HotSpotIntrinsicCandidate
private static void processBlocks(byte[] data, int inOfs, int blocks, long[] st, long[] subH) {
int offset = inOfs;
while (blocks > 0) {
--- a/jdk/src/java.base/share/classes/java/lang/Boolean.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Boolean.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,8 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* The Boolean class wraps a value of the primitive type
* {@code boolean} in an object. An object of type
@@ -128,6 +130,7 @@
*
* @return the primitive {@code boolean} value of this object.
*/
+ @HotSpotIntrinsicCandidate
public boolean booleanValue() {
return value;
}
@@ -146,6 +149,7 @@
* @return a {@code Boolean} instance representing {@code b}.
* @since 1.4
*/
+ @HotSpotIntrinsicCandidate
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
--- a/jdk/src/java.base/share/classes/java/lang/Byte.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Byte.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,8 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
*
* The {@code Byte} class wraps a value of primitive type {@code byte}
@@ -98,6 +100,7 @@
* @return a {@code Byte} instance representing {@code b}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Byte valueOf(byte b) {
final int offset = 128;
return ByteCache.cache[(int)b + offset];
@@ -320,6 +323,7 @@
* Returns the value of this {@code Byte} as a
* {@code byte}.
*/
+ @HotSpotIntrinsicCandidate
public byte byteValue() {
return value;
}
--- a/jdk/src/java.base/share/classes/java/lang/Character.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Character.java Fri Jul 03 07:23:45 2015 +0200
@@ -30,6 +30,8 @@
import java.util.HashMap;
import java.util.Locale;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* The {@code Character} class wraps a value of the primitive
* type {@code char} in an object. An object of type
@@ -4569,6 +4571,7 @@
* @return a <tt>Character</tt> instance representing <tt>c</tt>.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
@@ -4581,6 +4584,7 @@
* @return the primitive {@code char} value represented by
* this object.
*/
+ @HotSpotIntrinsicCandidate
public char charValue() {
return value;
}
@@ -7181,6 +7185,7 @@
* the bytes in the specified <tt>char</tt> value.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static char reverseBytes(char ch) {
return (char) (((ch & 0xFF00) >> 8) | (ch << 8));
}
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Fri Jul 03 07:23:45 2015 +0200
@@ -56,6 +56,7 @@
import java.util.Objects;
import java.util.StringJoiner;
import sun.misc.Unsafe;
+import jdk.internal.HotSpotIntrinsicCandidate;
import sun.reflect.CallerSensitive;
import sun.reflect.ConstantPool;
import sun.reflect.Reflection;
@@ -502,6 +503,7 @@
*
* @since 1.1
*/
+ @HotSpotIntrinsicCandidate
public native boolean isInstance(Object obj);
@@ -529,6 +531,7 @@
* null.
* @since 1.1
*/
+ @HotSpotIntrinsicCandidate
public native boolean isAssignableFrom(Class<?> cls);
@@ -539,6 +542,7 @@
* @return {@code true} if this object represents an interface;
* {@code false} otherwise.
*/
+ @HotSpotIntrinsicCandidate
public native boolean isInterface();
@@ -549,6 +553,7 @@
* {@code false} otherwise.
* @since 1.1
*/
+ @HotSpotIntrinsicCandidate
public native boolean isArray();
@@ -580,6 +585,7 @@
* @see java.lang.Void#TYPE
* @since 1.1
*/
+ @HotSpotIntrinsicCandidate
public native boolean isPrimitive();
/**
@@ -751,6 +757,7 @@
*
* @return the direct superclass of the class represented by this object
*/
+ @HotSpotIntrinsicCandidate
public native Class<? super T> getSuperclass();
@@ -984,6 +991,7 @@
* @see java.lang.reflect.Modifier
* @since 1.1
*/
+ @HotSpotIntrinsicCandidate
public native int getModifiers();
@@ -3382,6 +3390,7 @@
* @since 1.5
*/
@SuppressWarnings("unchecked")
+ @HotSpotIntrinsicCandidate
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
throw new ClassCastException(cannotCastMsg(obj));
--- a/jdk/src/java.base/share/classes/java/lang/Double.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Double.java Fri Jul 03 07:23:45 2015 +0200
@@ -27,6 +27,7 @@
import sun.misc.FloatingDecimal;
import sun.misc.DoubleConsts;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The {@code Double} class wraps a value of the primitive type
@@ -514,6 +515,7 @@
* @return a {@code Double} instance representing {@code d}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Double valueOf(double d) {
return new Double(d);
}
@@ -711,6 +713,7 @@
*
* @return the {@code double} value represented by this object
*/
+ @HotSpotIntrinsicCandidate
public double doubleValue() {
return value;
}
@@ -831,6 +834,7 @@
* @param value a {@code double} precision floating-point number.
* @return the bits that represent the floating-point number.
*/
+ @HotSpotIntrinsicCandidate
public static long doubleToLongBits(double value) {
if (!isNaN(value)) {
return doubleToRawLongBits(value);
@@ -874,6 +878,7 @@
* @return the bits that represent the floating-point number.
* @since 1.3
*/
+ @HotSpotIntrinsicCandidate
public static native long doubleToRawLongBits(double value);
/**
@@ -937,6 +942,7 @@
* @return the {@code double} floating-point value with the same
* bit pattern.
*/
+ @HotSpotIntrinsicCandidate
public static native double longBitsToDouble(long bits);
/**
--- a/jdk/src/java.base/share/classes/java/lang/Float.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Float.java Fri Jul 03 07:23:45 2015 +0200
@@ -28,6 +28,7 @@
import sun.misc.FloatingDecimal;
import sun.misc.FloatConsts;
import sun.misc.DoubleConsts;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The {@code Float} class wraps a value of primitive type
@@ -429,6 +430,7 @@
* @return a {@code Float} instance representing {@code f}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Float valueOf(float f) {
return new Float(f);
}
@@ -622,6 +624,7 @@
*
* @return the {@code float} value represented by this object
*/
+ @HotSpotIntrinsicCandidate
public float floatValue() {
return value;
}
@@ -740,6 +743,7 @@
* @param value a floating-point number.
* @return the bits that represent the floating-point number.
*/
+ @HotSpotIntrinsicCandidate
public static int floatToIntBits(float value) {
if (!isNaN(value)) {
return floatToRawIntBits(value);
@@ -782,6 +786,7 @@
* @return the bits that represent the floating-point number.
* @since 1.3
*/
+ @HotSpotIntrinsicCandidate
public static native int floatToRawIntBits(float value);
/**
@@ -843,6 +848,7 @@
* @return the {@code float} floating-point value with the same bit
* pattern.
*/
+ @HotSpotIntrinsicCandidate
public static native float intBitsToFloat(int bits);
/**
--- a/jdk/src/java.base/share/classes/java/lang/Integer.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Integer.java Fri Jul 03 07:23:45 2015 +0200
@@ -27,6 +27,7 @@
import java.lang.annotation.Native;
import java.util.Objects;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The {@code Integer} class wraps a value of the primitive type
@@ -395,6 +396,7 @@
* @param i an integer to be converted.
* @return a string representation of the argument in base 10.
*/
+ @HotSpotIntrinsicCandidate
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
@@ -972,6 +974,7 @@
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
@@ -1035,6 +1038,7 @@
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
+ @HotSpotIntrinsicCandidate
public int intValue() {
return value;
}
@@ -1538,6 +1542,7 @@
* is equal to zero.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
@@ -1565,6 +1570,7 @@
* to zero.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
@@ -1587,6 +1593,7 @@
* representation of the specified {@code int} value.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
@@ -1688,6 +1695,7 @@
* {@code int} value.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int reverseBytes(int i) {
return ((i >>> 24) ) |
((i >> 8) & 0xFF00) |
--- a/jdk/src/java.base/share/classes/java/lang/Long.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Long.java Fri Jul 03 07:23:45 2015 +0200
@@ -28,6 +28,7 @@
import java.lang.annotation.Native;
import java.math.*;
import java.util.Objects;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
@@ -1074,6 +1075,7 @@
* @return a {@code Long} instance representing {@code l}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache
@@ -1238,6 +1240,7 @@
* Returns the value of this {@code Long} as a
* {@code long} value.
*/
+ @HotSpotIntrinsicCandidate
public long longValue() {
return value;
}
@@ -1655,6 +1658,7 @@
* is equal to zero.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int numberOfLeadingZeros(long i) {
// HD, Figure 5-6
if (i == 0)
@@ -1684,6 +1688,7 @@
* to zero.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int numberOfTrailingZeros(long i) {
// HD, Figure 5-14
int x, y;
@@ -1707,6 +1712,7 @@
* representation of the specified {@code long} value.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static int bitCount(long i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x5555555555555555L);
@@ -1810,6 +1816,7 @@
* {@code long} value.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static long reverseBytes(long i) {
i = (i & 0x00ff00ff00ff00ffL) << 8 | (i >>> 8) & 0x00ff00ff00ff00ffL;
return (i << 48) | ((i & 0xffff0000L) << 16) |
--- a/jdk/src/java.base/share/classes/java/lang/Math.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Math.java Fri Jul 03 07:23:45 2015 +0200
@@ -24,10 +24,11 @@
*/
package java.lang;
+
import java.util.Random;
-
import sun.misc.FloatConsts;
import sun.misc.DoubleConsts;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The class {@code Math} contains methods for performing basic
@@ -147,6 +148,7 @@
* @param a an angle, in radians.
* @return the sine of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static double sin(double a) {
return StrictMath.sin(a); // default impl. delegates to StrictMath
}
@@ -162,6 +164,7 @@
* @param a an angle, in radians.
* @return the cosine of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static double cos(double a) {
return StrictMath.cos(a); // default impl. delegates to StrictMath
}
@@ -179,6 +182,7 @@
* @param a an angle, in radians.
* @return the tangent of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static double tan(double a) {
return StrictMath.tan(a); // default impl. delegates to StrictMath
}
@@ -280,6 +284,7 @@
* @return the value <i>e</i><sup>{@code a}</sup>,
* where <i>e</i> is the base of the natural logarithms.
*/
+ @HotSpotIntrinsicCandidate
public static double exp(double a) {
return StrictMath.exp(a); // default impl. delegates to StrictMath
}
@@ -301,6 +306,7 @@
* @return the value ln {@code a}, the natural logarithm of
* {@code a}.
*/
+ @HotSpotIntrinsicCandidate
public static double log(double a) {
return StrictMath.log(a); // default impl. delegates to StrictMath
}
@@ -326,6 +332,7 @@
* @return the base 10 logarithm of {@code a}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static double log10(double a) {
return StrictMath.log10(a); // default impl. delegates to StrictMath
}
@@ -347,6 +354,7 @@
* @return the positive square root of {@code a}.
* If the argument is NaN or less than zero, the result is NaN.
*/
+ @HotSpotIntrinsicCandidate
public static double sqrt(double a) {
return StrictMath.sqrt(a); // default impl. delegates to StrictMath
// Note that hardware sqrt instructions
@@ -525,6 +533,7 @@
* in polar coordinates that corresponds to the point
* (<i>x</i>, <i>y</i>) in Cartesian coordinates.
*/
+ @HotSpotIntrinsicCandidate
public static double atan2(double y, double x) {
return StrictMath.atan2(y, x); // default impl. delegates to StrictMath
}
@@ -652,6 +661,7 @@
* @param b the exponent.
* @return the value {@code a}<sup>{@code b}</sup>.
*/
+ @HotSpotIntrinsicCandidate
public static double pow(double a, double b) {
return StrictMath.pow(a, b); // default impl. delegates to StrictMath
}
@@ -806,6 +816,7 @@
* @throws ArithmeticException if the result overflows an int
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static int addExact(int x, int y) {
int r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
@@ -825,6 +836,7 @@
* @throws ArithmeticException if the result overflows a long
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static long addExact(long x, long y) {
long r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
@@ -844,6 +856,7 @@
* @throws ArithmeticException if the result overflows an int
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static int subtractExact(int x, int y) {
int r = x - y;
// HD 2-12 Overflow iff the arguments have different signs and
@@ -864,6 +877,7 @@
* @throws ArithmeticException if the result overflows a long
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static long subtractExact(long x, long y) {
long r = x - y;
// HD 2-12 Overflow iff the arguments have different signs and
@@ -884,6 +898,7 @@
* @throws ArithmeticException if the result overflows an int
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static int multiplyExact(int x, int y) {
long r = (long)x * (long)y;
if ((int)r != r) {
@@ -902,6 +917,7 @@
* @throws ArithmeticException if the result overflows a long
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static long multiplyExact(long x, long y) {
long r = x * y;
long ax = Math.abs(x);
@@ -927,6 +943,7 @@
* @throws ArithmeticException if the result overflows an int
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static int incrementExact(int a) {
if (a == Integer.MAX_VALUE) {
throw new ArithmeticException("integer overflow");
@@ -944,6 +961,7 @@
* @throws ArithmeticException if the result overflows a long
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static long incrementExact(long a) {
if (a == Long.MAX_VALUE) {
throw new ArithmeticException("long overflow");
@@ -961,6 +979,7 @@
* @throws ArithmeticException if the result overflows an int
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static int decrementExact(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("integer overflow");
@@ -978,6 +997,7 @@
* @throws ArithmeticException if the result overflows a long
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static long decrementExact(long a) {
if (a == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow");
@@ -995,6 +1015,7 @@
* @throws ArithmeticException if the result overflows an int
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static int negateExact(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("integer overflow");
@@ -1012,6 +1033,7 @@
* @throws ArithmeticException if the result overflows a long
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public static long negateExact(long a) {
if (a == Long.MIN_VALUE) {
throw new ArithmeticException("long overflow");
@@ -1256,6 +1278,7 @@
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
+ @HotSpotIntrinsicCandidate
public static double abs(double a) {
return (a <= 0.0D) ? 0.0D - a : a;
}
@@ -1270,6 +1293,7 @@
* @param b another argument.
* @return the larger of {@code a} and {@code b}.
*/
+ @HotSpotIntrinsicCandidate
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
@@ -1354,6 +1378,7 @@
* @param b another argument.
* @return the smaller of {@code a} and {@code b}.
*/
+ @HotSpotIntrinsicCandidate
public static int min(int a, int b) {
return (a <= b) ? a : b;
}
--- a/jdk/src/java.base/share/classes/java/lang/Object.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Object.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,8 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* Class {@code Object} is the root of the class hierarchy.
* Every class has {@code Object} as a superclass. All objects,
@@ -44,6 +46,7 @@
/**
* Constructs a new object.
*/
+ @HotSpotIntrinsicCandidate
public Object() {}
/**
@@ -65,6 +68,7 @@
* class of this object.
* @jls 15.8.2 Class Literals
*/
+ @HotSpotIntrinsicCandidate
public final native Class<?> getClass();
/**
@@ -101,6 +105,7 @@
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
+ @HotSpotIntrinsicCandidate
public native int hashCode();
/**
@@ -213,6 +218,7 @@
* be cloned.
* @see java.lang.Cloneable
*/
+ @HotSpotIntrinsicCandidate
protected native Object clone() throws CloneNotSupportedException;
/**
--- a/jdk/src/java.base/share/classes/java/lang/Short.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Short.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,8 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* The {@code Short} class wraps a value of primitive type {@code
* short} in an object. An object of type {@code Short} contains a
@@ -227,6 +229,7 @@
* @return a {@code Short} instance representing {@code s}.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static Short valueOf(short s) {
final int offset = 128;
int sAsInt = s;
@@ -334,6 +337,7 @@
* Returns the value of this {@code Short} as a
* {@code short}.
*/
+ @HotSpotIntrinsicCandidate
public short shortValue() {
return value;
}
@@ -487,6 +491,7 @@
* the bytes in the specified {@code short} value.
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static short reverseBytes(short i) {
return (short) (((i & 0xFF00) >> 8) | (i << 8));
}
--- a/jdk/src/java.base/share/classes/java/lang/StrictMath.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StrictMath.java Fri Jul 03 07:23:45 2015 +0200
@@ -24,8 +24,10 @@
*/
package java.lang;
+
import java.util.Random;
import sun.misc.DoubleConsts;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The class {@code StrictMath} contains methods for performing basic
@@ -243,7 +245,6 @@
*/
public static native double log(double a);
-
/**
* Returns the base 10 logarithm of a {@code double} value.
* Special cases:
@@ -280,6 +281,7 @@
* @param a a value.
* @return the positive square root of {@code a}.
*/
+ @HotSpotIntrinsicCandidate
public static native double sqrt(double a);
/**
@@ -521,7 +523,6 @@
*/
public static native double atan2(double y, double x);
-
/**
* Returns the value of the first argument raised to the power of the
* second argument. Special cases:
@@ -1009,6 +1010,7 @@
* @param b another argument.
* @return the larger of {@code a} and {@code b}.
*/
+ @HotSpotIntrinsicCandidate
public static int max(int a, int b) {
return Math.max(a, b);
}
@@ -1073,6 +1075,7 @@
* @param b another argument.
* @return the smaller of {@code a} and {@code b}.
*/
+ @HotSpotIntrinsicCandidate
public static int min(int a, int b) {
return Math.min(a, b);
}
--- a/jdk/src/java.base/share/classes/java/lang/String.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/String.java Fri Jul 03 07:23:45 2015 +0200
@@ -42,6 +42,7 @@
import java.util.regex.PatternSyntaxException;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The {@code String} class represents character strings. All
@@ -152,6 +153,7 @@
* @param original
* A {@code String}
*/
+ @HotSpotIntrinsicCandidate
public String(String original) {
this.value = original.value;
this.hash = original.hash;
@@ -978,6 +980,7 @@
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
+ @HotSpotIntrinsicCandidate
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
@@ -1154,6 +1157,7 @@
* value greater than {@code 0} if this string is
* lexicographically greater than the string argument.
*/
+ @HotSpotIntrinsicCandidate
public int compareTo(String anotherString) {
char[] v1 = value;
char[] v2 = anotherString.value;
@@ -1696,6 +1700,7 @@
* @return the index of the first occurrence of the specified substring,
* or {@code -1} if there is no such occurrence.
*/
+ @HotSpotIntrinsicCandidate
public int indexOf(String str) {
return indexOf(str, 0);
}
--- a/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuffer.java Fri Jul 03 07:23:45 2015 +0200
@@ -26,6 +26,7 @@
package java.lang;
import java.util.Arrays;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* A thread-safe, mutable sequence of characters.
@@ -112,6 +113,7 @@
* Constructs a string buffer with no characters in it and an
* initial capacity of 16 characters.
*/
+ @HotSpotIntrinsicCandidate
public StringBuffer() {
super(16);
}
@@ -124,6 +126,7 @@
* @exception NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
+ @HotSpotIntrinsicCandidate
public StringBuffer(int capacity) {
super(capacity);
}
@@ -135,6 +138,7 @@
*
* @param str the initial contents of the buffer.
*/
+ @HotSpotIntrinsicCandidate
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
@@ -271,6 +275,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
@@ -382,6 +387,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public synchronized StringBuffer append(char c) {
toStringCache = null;
super.append(c);
@@ -389,6 +395,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public synchronized StringBuffer append(int i) {
toStringCache = null;
super.append(i);
@@ -670,6 +677,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
--- a/jdk/src/java.base/share/classes/java/lang/StringBuilder.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StringBuilder.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,7 @@
package java.lang;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* A mutable sequence of characters. This class provides an API compatible
@@ -85,6 +86,7 @@
* Constructs a string builder with no characters in it and an
* initial capacity of 16 characters.
*/
+ @HotSpotIntrinsicCandidate
public StringBuilder() {
super(16);
}
@@ -97,6 +99,7 @@
* @throws NegativeArraySizeException if the {@code capacity}
* argument is less than {@code 0}.
*/
+ @HotSpotIntrinsicCandidate
public StringBuilder(int capacity) {
super(capacity);
}
@@ -108,6 +111,7 @@
*
* @param str the initial contents of the buffer.
*/
+ @HotSpotIntrinsicCandidate
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
@@ -132,6 +136,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public StringBuilder append(String str) {
super.append(str);
return this;
@@ -198,12 +203,14 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public StringBuilder append(char c) {
super.append(c);
return this;
}
@Override
+ @HotSpotIntrinsicCandidate
public StringBuilder append(int i) {
super.append(i);
return this;
@@ -402,6 +409,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
--- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Fri Jul 03 07:23:45 2015 +0200
@@ -42,6 +42,7 @@
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* The <code>System</code> class contains several useful class fields
@@ -349,6 +350,7 @@
* the current time and midnight, January 1, 1970 UTC.
* @see java.util.Date
*/
+ @HotSpotIntrinsicCandidate
public static native long currentTimeMillis();
/**
@@ -392,6 +394,7 @@
* high-resolution time source, in nanoseconds
* @since 1.5
*/
+ @HotSpotIntrinsicCandidate
public static native long nanoTime();
/**
@@ -486,6 +489,7 @@
* @exception NullPointerException if either <code>src</code> or
* <code>dest</code> is <code>null</code>.
*/
+ @HotSpotIntrinsicCandidate
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
@@ -501,6 +505,7 @@
* @return the hashCode
* @since 1.1
*/
+ @HotSpotIntrinsicCandidate
public static native int identityHashCode(Object x);
/**
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Fri Jul 03 07:23:45 2015 +0200
@@ -40,7 +40,7 @@
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
-
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* A <i>thread</i> is a thread of execution in a program. The Java
@@ -261,6 +261,7 @@
*
* @return the currently executing thread.
*/
+ @HotSpotIntrinsicCandidate
public static native Thread currentThread();
/**
@@ -966,6 +967,7 @@
* is reset or not based on the value of ClearInterrupted that is
* passed.
*/
+ @HotSpotIntrinsicCandidate
private native boolean isInterrupted(boolean ClearInterrupted);
/**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandle.java Fri Jul 03 07:23:45 2015 +0200
@@ -27,6 +27,7 @@
import java.util.*;
+import jdk.internal.HotSpotIntrinsicCandidate;
import static java.lang.invoke.MethodHandleStatics.*;
@@ -476,6 +477,7 @@
* @throws WrongMethodTypeException if the target's type is not identical with the caller's symbolic type descriptor
* @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
*/
+ @HotSpotIntrinsicCandidate
public final native @PolymorphicSignature Object invokeExact(Object... args) throws Throwable;
/**
@@ -513,6 +515,7 @@
* @throws ClassCastException if the target's type can be adjusted to the caller, but a reference cast fails
* @throws Throwable anything thrown by the underlying method propagates unchanged through the method handle call
*/
+ @HotSpotIntrinsicCandidate
public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
/**
@@ -532,6 +535,7 @@
* @param args the signature-polymorphic parameter list, statically represented using varargs
* @return the signature-polymorphic result, statically represented using {@code Object}
*/
+ @HotSpotIntrinsicCandidate
/*non-public*/ final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
/**
@@ -541,6 +545,7 @@
* @param args the signature-polymorphic parameter list, statically represented using varargs
* @return the signature-polymorphic result, statically represented using {@code Object}
*/
+ @HotSpotIntrinsicCandidate
/*non-public*/ static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
/**
@@ -550,6 +555,7 @@
* @param args the signature-polymorphic parameter list, statically represented using varargs
* @return the signature-polymorphic result, statically represented using {@code Object}
*/
+ @HotSpotIntrinsicCandidate
/*non-public*/ static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
/**
@@ -559,6 +565,7 @@
* @param args the signature-polymorphic parameter list, statically represented using varargs
* @return the signature-polymorphic result, statically represented using {@code Object}
*/
+ @HotSpotIntrinsicCandidate
/*non-public*/ static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
/**
@@ -568,6 +575,7 @@
* @param args the signature-polymorphic parameter list, statically represented using varargs
* @return the signature-polymorphic result, statically represented using {@code Object}
*/
+ @HotSpotIntrinsicCandidate
/*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
/**
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Jul 03 07:23:45 2015 +0200
@@ -36,6 +36,7 @@
import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper;
+import jdk.internal.HotSpotIntrinsicCandidate;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import static java.lang.invoke.LambdaForm.*;
@@ -709,6 +710,7 @@
// Intrinsified by C2. Counters are used during parsing to calculate branch frequencies.
@LambdaForm.Hidden
+ @jdk.internal.HotSpotIntrinsicCandidate
static
boolean profileBoolean(boolean result, int[] counters) {
// Profile is int[2] where [0] and [1] correspond to false and true occurrences respectively.
@@ -724,6 +726,7 @@
// Intrinsified by C2. Returns true if obj is a compile-time constant.
@LambdaForm.Hidden
+ @jdk.internal.HotSpotIntrinsicCandidate
static
boolean isCompileConstant(Object obj) {
return false;
--- a/jdk/src/java.base/share/classes/java/lang/ref/Reference.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/ref/Reference.java Fri Jul 03 07:23:45 2015 +0200
@@ -29,6 +29,7 @@
import sun.misc.JavaLangRefAccess;
import sun.misc.ManagedLocalsThread;
import sun.misc.SharedSecrets;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* Abstract base class for reference objects. This class defines the
@@ -251,6 +252,7 @@
* @return The object to which this reference refers, or
* <code>null</code> if this reference object has been cleared
*/
+ @HotSpotIntrinsicCandidate
public T get() {
return this.referent;
}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Array.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Array.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,8 @@
package java.lang.reflect;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* The {@code Array} class provides static methods to dynamically create and
* access Java arrays.
@@ -119,6 +121,7 @@
* @exception IllegalArgumentException if the object argument is not
* an array
*/
+ @HotSpotIntrinsicCandidate
public static native int getLength(Object array)
throws IllegalArgumentException;
@@ -477,6 +480,7 @@
* Private
*/
+ @HotSpotIntrinsicCandidate
private static native Object newArray(Class<?> componentType, int length)
throws NegativeArraySizeException;
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import jdk.internal.HotSpotIntrinsicCandidate;
import sun.reflect.CallerSensitive;
import sun.reflect.MethodAccessor;
import sun.reflect.Reflection;
@@ -485,6 +486,7 @@
* provoked by this method fails.
*/
@CallerSensitive
+ @HotSpotIntrinsicCandidate
public Object invoke(Object obj, Object... args)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException
--- a/jdk/src/java.base/share/classes/java/math/BigInteger.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/math/BigInteger.java Fri Jul 03 07:23:45 2015 +0200
@@ -34,10 +34,13 @@
import java.io.ObjectOutputStream;
import java.io.ObjectStreamField;
import java.util.Arrays;
+import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
+
import sun.misc.DoubleConsts;
import sun.misc.FloatConsts;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* Immutable arbitrary-precision integers. All operations behave as if
@@ -1649,6 +1652,13 @@
* the result into z. There will be no leading zeros in the resultant array.
*/
private static int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
+ multiplyToLenCheck(x, xlen);
+ multiplyToLenCheck(y, ylen);
+ return implMultiplyToLen(x, xlen, y, ylen, z);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private static int[] implMultiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
int xstart = xlen - 1;
int ystart = ylen - 1;
@@ -1678,6 +1688,18 @@
return z;
}
+ private static void multiplyToLenCheck(int[] array, int length) {
+ if (length <= 0) {
+ return; // not an error because multiplyToLen won't execute if len <= 0
+ }
+
+ Objects.requireNonNull(array);
+
+ if (length > array.length) {
+ throw new ArrayIndexOutOfBoundsException(length - 1);
+ }
+ }
+
/**
* Multiplies two BigIntegers using the Karatsuba multiplication
* algorithm. This is a recursive divide-and-conquer algorithm which is
@@ -2008,6 +2030,7 @@
/**
* Java Runtime may use intrinsic for this method.
*/
+ @HotSpotIntrinsicCandidate
private static final int[] implSquareToLen(int[] x, int len, int[] z, int zlen) {
/*
* The algorithm used here is adapted from Colin Plumb's C library.
@@ -2668,11 +2691,13 @@
// These methods are intended to be be replaced by virtual machine
// intrinsics.
+ @HotSpotIntrinsicCandidate
private static int[] implMontgomeryMultiply(int[] a, int[] b, int[] n, int len,
long inv, int[] product) {
product = multiplyToLen(a, len, b, len, product);
return montReduce(product, n, len, (int)inv);
}
+ @HotSpotIntrinsicCandidate
private static int[] implMontgomerySquare(int[] a, int[] n, int len,
long inv, int[] product) {
product = squareToLen(a, len, product);
@@ -3004,6 +3029,7 @@
/**
* Java Runtime may use intrinsic for this method.
*/
+ @HotSpotIntrinsicCandidate
private static int implMulAdd(int[] out, int[] in, int offset, int len, int k) {
long kLong = k & LONG_MASK;
long carry = 0;
--- a/jdk/src/java.base/share/classes/java/nio/Buffer.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java Fri Jul 03 07:23:45 2015 +0200
@@ -26,6 +26,7 @@
package java.nio;
import java.util.Spliterator;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* A container for data of a specific primitive type.
@@ -535,6 +536,7 @@
* IndexOutOfBoundsException} if it is not smaller than the limit
* or is smaller than zero.
*/
+ @HotSpotIntrinsicCandidate
final int checkIndex(int i) { // package-private
if ((i < 0) || (i >= limit))
throw new IndexOutOfBoundsException();
--- a/jdk/src/java.base/share/classes/java/util/Arrays.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/Arrays.java Fri Jul 03 07:23:45 2015 +0200
@@ -42,6 +42,7 @@
import java.util.stream.LongStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* This class contains various methods for manipulating arrays (such as
@@ -2654,6 +2655,7 @@
* @param a2 the other array to be tested for equality
* @return <tt>true</tt> if the two arrays are equal
*/
+ @HotSpotIntrinsicCandidate
public static boolean equals(char[] a, char[] a2) {
if (a==a2)
return true;
@@ -3205,6 +3207,7 @@
* an array of class <tt>newType</tt>
* @since 1.6
*/
+ @HotSpotIntrinsicCandidate
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
@SuppressWarnings("unchecked")
T[] copy = ((Object)newType == (Object)Object[].class)
@@ -3474,6 +3477,7 @@
* an array of class <tt>newType</tt>.
* @since 1.6
*/
+ @HotSpotIntrinsicCandidate
public static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) {
int newLength = to - from;
if (newLength < 0)
--- a/jdk/src/java.base/share/classes/java/util/stream/Streams.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/stream/Streams.java Fri Jul 03 07:23:45 2015 +0200
@@ -31,6 +31,7 @@
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* Utility methods for operating on and creating streams.
@@ -98,6 +99,7 @@
}
@Override
+ @HotSpotIntrinsicCandidate
public void forEachRemaining(IntConsumer consumer) {
Objects.requireNonNull(consumer);
--- a/jdk/src/java.base/share/classes/java/util/zip/CRC32.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/zip/CRC32.java Fri Jul 03 07:23:45 2015 +0200
@@ -26,7 +26,10 @@
package java.util.zip;
import java.nio.ByteBuffer;
+import java.util.Objects;
+
import sun.nio.ch.DirectBuffer;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* A class that can be used to compute the CRC-32 of a data stream.
@@ -123,9 +126,49 @@
return (long)crc & 0xffffffffL;
}
+ @HotSpotIntrinsicCandidate
private native static int update(int crc, int b);
- private native static int updateBytes(int crc, byte[] b, int off, int len);
+
+ private static int updateBytes(int crc, byte[] b, int off, int len) {
+ updateBytesCheck(b, off, len);
+ return updateBytes0(crc, b, off, len);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private native static int updateBytes0(int crc, byte[] b, int off, int len);
+
+ private static void updateBytesCheck(byte[] b, int off, int len) {
+ if (len <= 0) {
+ return; // not an error because updateBytesImpl won't execute if len <= 0
+ }
+
+ Objects.requireNonNull(b);
+
+ if (off < 0 || off >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(off);
+ }
- private native static int updateByteBuffer(int adler, long addr,
- int off, int len);
+ int endIndex = off + len - 1;
+ if (endIndex < 0 || endIndex >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndex);
+ }
+ }
+
+ private static int updateByteBuffer(int alder, long addr,
+ int off, int len) {
+ updateByteBufferCheck(addr);
+ return updateByteBuffer0(alder, addr, off, len);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private native static int updateByteBuffer0(int alder, long addr,
+ int off, int len);
+
+ private static void updateByteBufferCheck(long addr) {
+ // Performs only a null check because bounds checks
+ // are not easy to do on raw addresses.
+ if (addr == 0L) {
+ throw new NullPointerException();
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/java/util/zip/CRC32C.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/java/util/zip/CRC32C.java Fri Jul 03 07:23:45 2015 +0200
@@ -26,6 +26,8 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
@@ -204,6 +206,7 @@
/**
* Updates the CRC-32C checksum with the specified array of bytes.
*/
+ @HotSpotIntrinsicCandidate
private static int updateBytes(int crc, byte[] b, int off, int end) {
// Do only byte reads for arrays so short they can't be aligned
@@ -278,6 +281,7 @@
/**
* Updates the CRC-32C checksum reading from the specified address.
*/
+ @HotSpotIntrinsicCandidate
private static int updateDirectByteBuffer(int crc, long address,
int off, int end) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/HotSpotIntrinsicCandidate.java Fri Jul 03 07:23:45 2015 +0200
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 jdk.internal;
+
+import java.lang.annotation.*;
+
+/**
+ * The {@code @HotSpotIntrinsicCandidate} annotation is specific to the Oracle Java
+ * HotSpot Virtual Machine implementation and indicates that an annotated method
+ * may be (but is not guaranteed to be) intrinsified by the HotSpot VM. A method
+ * is intrinsified if the HotSpot VM replaces the annotated method with hand-written
+ * assembly and/or hand-written compiler IR -- a compiler intrinsic -- to improve
+ * performance. The {@code @HotSpotIntrinsicCandidate} annotation is internal to the
+ * Java libraries and is therefore not supposed to have any relevance for application
+ * code.
+ *
+ * Maintainers of the Java libraries must consider the following when
+ * modifying methods annotated with {@code @HotSpotIntrinsicCandidate}.
+ *
+ * <ul>
+ * <li>When modifying a method annotated with {@code @HotSpotIntrinsicCandidate},
+ * the corresponding intrinsic code in the HotSpot VM implementation must be
+ * updated to match the semantics of the annotated method.</li>
+ * <li>For some annotated methods, the corresponding intrinsic may omit some low-level
+ * checks that would be performed as a matter of course if the intrinsic is implemented
+ * using Java bytecodes. This is because individual Java bytecodes implicitly check
+ * for exceptions like {@code NullPointerException} and {@code ArrayStoreException}.
+ * If such a method is replaced by an intrinsic coded in assembly language, any
+ * checks performed as a matter of normal bytecode operation must be performed
+ * before entry into the assembly code. These checks must be performed, as
+ * appropriate, on all arguments to the intrinsic, and on other values (if any) obtained
+ * by the intrinsic through those arguments. The checks may be deduced by inspecting
+ * the non-intrinsic Java code for the method, and determining exactly which exceptions
+ * may be thrown by the code, including undeclared implicit {@code RuntimeException}s.
+ * Therefore, depending on the data accesses performed by the intrinsic,
+ * the checks may include:
+ *
+ * <ul>
+ * <li>null checks on references</li>
+ * <li>range checks on primitive values used as array indexes</li>
+ * <li>other validity checks on primitive values (e.g., for divide-by-zero conditions)</li>
+ * <li>store checks on reference values stored into arrays</li>
+ * <li>array length checks on arrays indexed from within the intrinsic</li>
+ * <li>reference casts (when formal parameters are {@code Object} or some other weak type)</li>
+ * </ul>
+ *
+ * </li>
+ *
+ * <li>Note that the receiver value ({@code this}) is passed as a extra argument
+ * to all non-static methods. If a non-static method is an intrinsic, the receiver
+ * value does not need a null check, but (as stated above) any values loaded by the
+ * intrinsic from object fields must also be checked. As a matter of clarity, it is
+ * better to make intrinisics be static methods, to make the dependency on {@code this}
+ * clear. Also, it is better to explicitly load all required values from object
+ * fields before entering the intrinsic code, and pass those values as explicit arguments.
+ * First, this may be necessary for null checks (or other checks). Second, if the
+ * intrinsic reloads the values from fields and operates on those without checks,
+ * race conditions may be able to introduce unchecked invalid values into the intrinsic.
+ * If the intrinsic needs to store a value back to an object field, that value should be
+ * returned explicitly from the intrinsic; if there are multiple return values, coders
+ * should consider buffering them in an array. Removing field access from intrinsics
+ * not only clarifies the interface with between the JVM and JDK; it also helps decouple
+ * the HotSpot and JDK implementations, since if JDK code before and after the intrinsic
+ * manages all field accesses, then intrinsics can be coded to be agnostic of object
+ * layouts.</li>
+ *
+ * Maintainers of the HotSpot VM must consider the following when modifying
+ * intrinsics.
+ *
+ * <ul>
+ * <li>When adding a new intrinsic, make sure that the corresponding method
+ * in the Java libraries is annotated with {@code @HotSpotIntrinsicCandidate}
+ * and that all possible call sequences that result in calling the intrinsic contain
+ * the checks omitted by the intrinsic (if any).</li>
+ * <li>When modifying an existing intrinsic, the Java libraries must be updated
+ * to match the semantics of the intrinsic and to execute all checks omitted
+ * by the intrinsic (if any).</li>
+ * </ul>
+ *
+ * Persons not directly involved with maintaining the Java libraries or the
+ * HotSpot VM can safely ignore the fact that a method is annotated with
+ * {@code @HotSpotIntrinsicCandidate}.
+ *
+ * The HotSpot VM defines (internally) a list of intrinsics. Not all intrinsic
+ * are available on all platforms supported by the HotSpot VM. Furthermore,
+ * the availability of an intrinsic on a given platform depends on the
+ * configuration of the HotSpot VM (e.g., the set of VM flags enabled).
+ * Therefore, annotating a method with {@code @HotSpotIntrinsicCandidate} does
+ * not guarantee that the marked method is intrinsified by the HotSpot VM.
+ *
+ * If the {@code CheckIntrinsics} VM flag is enabled, the HotSpot VM checks
+ * (when loading a class) that (1) all methods of that class that are also on
+ * the VM's list of intrinsics are annotated with {@code @HotSpotIntrinsicCandidate}
+ * and that (2) for all methods of that class annotated with
+ * {@code @HotSpotIntrinsicCandidate} there is an intrinsic in the list.
+ *
+ * @since 1.9
+ */
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HotSpotIntrinsicCandidate {
+}
--- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java Fri Jul 03 07:23:45 2015 +0200
@@ -31,6 +31,8 @@
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
+import jdk.internal.HotSpotIntrinsicCandidate;
+
/**
* A collection of methods for performing low-level, unsafe operations.
@@ -148,6 +150,7 @@
* @throws RuntimeException No defined exceptions are thrown, not even
* {@link NullPointerException}
*/
+ @HotSpotIntrinsicCandidate
public native int getInt(Object o, long offset);
/**
@@ -170,12 +173,14 @@
* @throws RuntimeException No defined exceptions are thrown, not even
* {@link NullPointerException}
*/
+ @HotSpotIntrinsicCandidate
public native void putInt(Object o, long offset, int x);
/**
* Fetches a reference value from a given Java variable.
* @see #getInt(Object, long)
*/
+ @HotSpotIntrinsicCandidate
public native Object getObject(Object o, long offset);
/**
@@ -188,35 +193,50 @@
* are updated.
* @see #putInt(Object, long, int)
*/
+ @HotSpotIntrinsicCandidate
public native void putObject(Object o, long offset, Object x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native boolean getBoolean(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putBoolean(Object o, long offset, boolean x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native byte getByte(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putByte(Object o, long offset, byte x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native short getShort(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putShort(Object o, long offset, short x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native char getChar(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putChar(Object o, long offset, char x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native long getLong(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putLong(Object o, long offset, long x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native float getFloat(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putFloat(Object o, long offset, float x);
/** @see #getInt(Object, long) */
+ @HotSpotIntrinsicCandidate
public native double getDouble(Object o, long offset);
/** @see #putInt(Object, long, int) */
+ @HotSpotIntrinsicCandidate
public native void putDouble(Object o, long offset, double x);
// These read VM internal data.
@@ -257,6 +277,7 @@
*
* @see #allocateMemory
*/
+ @HotSpotIntrinsicCandidate
public native byte getByte(long address);
/**
@@ -266,31 +287,44 @@
*
* @see #getByte(long)
*/
+ @HotSpotIntrinsicCandidate
public native void putByte(long address, byte x);
/** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
public native short getShort(long address);
/** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
public native void putShort(long address, short x);
/** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
public native char getChar(long address);
/** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
public native void putChar(long address, char x);
/** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
public native int getInt(long address);
/** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
public native void putInt(long address, int x);
/** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
public native long getLong(long address);
/** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
public native void putLong(long address, long x);
/** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
public native float getFloat(long address);
/** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
public native void putFloat(long address, float x);
/** @see #getByte(long) */
+ @HotSpotIntrinsicCandidate
public native double getDouble(long address);
/** @see #putByte(long, byte) */
+ @HotSpotIntrinsicCandidate
public native void putDouble(long address, double x);
/**
@@ -307,6 +341,7 @@
*
* @see #allocateMemory
*/
+ @HotSpotIntrinsicCandidate
public native long getAddress(long address);
/**
@@ -319,6 +354,7 @@
*
* @see #getAddress(long)
*/
+ @HotSpotIntrinsicCandidate
public native void putAddress(long address, long x);
/// wrappers for malloc, realloc, free:
@@ -406,6 +442,7 @@
*
* @since 1.7
*/
+ @HotSpotIntrinsicCandidate
public native void copyMemory(Object srcBase, long srcOffset,
Object destBase, long destOffset,
long bytes);
@@ -651,6 +688,7 @@
* Allocates an instance but does not run any constructor.
* Initializes the class if it has not yet been.
*/
+ @HotSpotIntrinsicCandidate
public native Object allocateInstance(Class<?> cls)
throws InstantiationException;
@@ -666,6 +704,7 @@
*
* @return {@code true} if successful
*/
+ @HotSpotIntrinsicCandidate
public final native boolean compareAndSwapObject(Object o, long offset,
Object expected,
Object x);
@@ -679,6 +718,7 @@
*
* @return {@code true} if successful
*/
+ @HotSpotIntrinsicCandidate
public final native boolean compareAndSwapInt(Object o, long offset,
int expected,
int x);
@@ -692,6 +732,7 @@
*
* @return {@code true} if successful
*/
+ @HotSpotIntrinsicCandidate
public final native boolean compareAndSwapLong(Object o, long offset,
long expected,
long x);
@@ -700,60 +741,78 @@
* Fetches a reference value from a given Java variable, with volatile
* load semantics. Otherwise identical to {@link #getObject(Object, long)}
*/
+ @HotSpotIntrinsicCandidate
public native Object getObjectVolatile(Object o, long offset);
/**
* Stores a reference value into a given Java variable, with
* volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)}
*/
+ @HotSpotIntrinsicCandidate
public native void putObjectVolatile(Object o, long offset, Object x);
/** Volatile version of {@link #getInt(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native int getIntVolatile(Object o, long offset);
/** Volatile version of {@link #putInt(Object, long, int)} */
+ @HotSpotIntrinsicCandidate
public native void putIntVolatile(Object o, long offset, int x);
/** Volatile version of {@link #getBoolean(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native boolean getBooleanVolatile(Object o, long offset);
/** Volatile version of {@link #putBoolean(Object, long, boolean)} */
+ @HotSpotIntrinsicCandidate
public native void putBooleanVolatile(Object o, long offset, boolean x);
/** Volatile version of {@link #getByte(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native byte getByteVolatile(Object o, long offset);
/** Volatile version of {@link #putByte(Object, long, byte)} */
+ @HotSpotIntrinsicCandidate
public native void putByteVolatile(Object o, long offset, byte x);
/** Volatile version of {@link #getShort(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native short getShortVolatile(Object o, long offset);
/** Volatile version of {@link #putShort(Object, long, short)} */
+ @HotSpotIntrinsicCandidate
public native void putShortVolatile(Object o, long offset, short x);
/** Volatile version of {@link #getChar(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native char getCharVolatile(Object o, long offset);
/** Volatile version of {@link #putChar(Object, long, char)} */
+ @HotSpotIntrinsicCandidate
public native void putCharVolatile(Object o, long offset, char x);
/** Volatile version of {@link #getLong(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native long getLongVolatile(Object o, long offset);
/** Volatile version of {@link #putLong(Object, long, long)} */
+ @HotSpotIntrinsicCandidate
public native void putLongVolatile(Object o, long offset, long x);
/** Volatile version of {@link #getFloat(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native float getFloatVolatile(Object o, long offset);
/** Volatile version of {@link #putFloat(Object, long, float)} */
+ @HotSpotIntrinsicCandidate
public native void putFloatVolatile(Object o, long offset, float x);
/** Volatile version of {@link #getDouble(Object, long)} */
+ @HotSpotIntrinsicCandidate
public native double getDoubleVolatile(Object o, long offset);
/** Volatile version of {@link #putDouble(Object, long, double)} */
+ @HotSpotIntrinsicCandidate
public native void putDoubleVolatile(Object o, long offset, double x);
/**
@@ -765,12 +824,15 @@
*
* Corresponds to C11 atomic_store_explicit(..., memory_order_release).
*/
+ @HotSpotIntrinsicCandidate
public native void putOrderedObject(Object o, long offset, Object x);
/** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */
+ @HotSpotIntrinsicCandidate
public native void putOrderedInt(Object o, long offset, int x);
/** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */
+ @HotSpotIntrinsicCandidate
public native void putOrderedLong(Object o, long offset, long x);
/**
@@ -785,6 +847,7 @@
*
* @param thread the thread to unpark.
*/
+ @HotSpotIntrinsicCandidate
public native void unpark(Object thread);
/**
@@ -798,6 +861,7 @@
* because {@code unpark} is, so it would be strange to place it
* elsewhere.
*/
+ @HotSpotIntrinsicCandidate
public native void park(boolean isAbsolute, long time);
/**
@@ -831,6 +895,7 @@
* @return the previous value
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public final int getAndAddInt(Object o, long offset, int delta) {
int v;
do {
@@ -850,6 +915,7 @@
* @return the previous value
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public final long getAndAddLong(Object o, long offset, long delta) {
long v;
do {
@@ -869,6 +935,7 @@
* @return the previous value
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public final int getAndSetInt(Object o, long offset, int newValue) {
int v;
do {
@@ -888,6 +955,7 @@
* @return the previous value
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public final long getAndSetLong(Object o, long offset, long newValue) {
long v;
do {
@@ -907,6 +975,7 @@
* @return the previous value
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public final Object getAndSetObject(Object o, long offset, Object newValue) {
Object v;
do {
@@ -928,6 +997,7 @@
* provide a LoadLoad barrier also provide a LoadStore barrier for free.
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public native void loadFence();
/**
@@ -942,6 +1012,7 @@
* provide a StoreStore barrier also provide a LoadStore barrier for free.
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public native void storeFence();
/**
@@ -953,6 +1024,7 @@
* Corresponds to C11 atomic_thread_fence(memory_order_seq_cst).
* @since 1.8
*/
+ @HotSpotIntrinsicCandidate
public native void fullFence();
/**
@@ -1010,6 +1082,7 @@
* {@link NullPointerException}
* @since 1.9
*/
+ @HotSpotIntrinsicCandidate
public final long getLongUnaligned(Object o, long offset) {
if ((offset & 7) == 0) {
return getLong(o, offset);
@@ -1048,6 +1121,7 @@
}
/** @see #getLongUnaligned(Object, long) */
+ @HotSpotIntrinsicCandidate
public final int getIntUnaligned(Object o, long offset) {
if ((offset & 3) == 0) {
return getInt(o, offset);
@@ -1067,6 +1141,7 @@
}
/** @see #getLongUnaligned(Object, long) */
+ @HotSpotIntrinsicCandidate
public final short getShortUnaligned(Object o, long offset) {
if ((offset & 1) == 0) {
return getShort(o, offset);
@@ -1081,9 +1156,11 @@
}
/** @see #getLongUnaligned(Object, long) */
+ @HotSpotIntrinsicCandidate
public final char getCharUnaligned(Object o, long offset) {
return (char)getShortUnaligned(o, offset);
}
+
/** @see #getLongUnaligned(Object, long, boolean) */
public final char getCharUnaligned(Object o, long offset, boolean bigEndian) {
return convEndian(bigEndian, getCharUnaligned(o, offset));
@@ -1117,6 +1194,7 @@
* {@link NullPointerException}
* @since 1.9
*/
+ @HotSpotIntrinsicCandidate
public final void putLongUnaligned(Object o, long offset, long x) {
if ((offset & 7) == 0) {
putLong(o, offset, x);
@@ -1142,6 +1220,7 @@
(byte)(x >>> 56));
}
}
+
/**
* As {@link #putLongUnaligned(Object, long, long)} but with an additional
* argument which specifies the endianness of the value as stored in memory.
@@ -1158,6 +1237,7 @@
}
/** @see #putLongUnaligned(Object, long, long) */
+ @HotSpotIntrinsicCandidate
public final void putIntUnaligned(Object o, long offset, int x) {
if ((offset & 3) == 0) {
putInt(o, offset, x);
@@ -1179,6 +1259,7 @@
}
/** @see #putLongUnaligned(Object, long, long) */
+ @HotSpotIntrinsicCandidate
public final void putShortUnaligned(Object o, long offset, short x) {
if ((offset & 1) == 0) {
putShort(o, offset, x);
@@ -1194,6 +1275,7 @@
}
/** @see #putLongUnaligned(Object, long, long) */
+ @HotSpotIntrinsicCandidate
public final void putCharUnaligned(Object o, long offset, char x) {
putShortUnaligned(o, offset, (short)x);
}
--- a/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java Fri Jul 03 07:23:45 2015 +0200
@@ -32,6 +32,9 @@
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.util.Arrays;
+import java.util.Objects;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
class ISO_8859_1
extends Charset
@@ -147,9 +150,16 @@
private final Surrogate.Parser sgp = new Surrogate.Parser();
- // JVM may replace this method with intrinsic code.
+ // Method possible replaced with a compiler intrinsic.
private static int encodeISOArray(char[] sa, int sp,
- byte[] da, int dp, int len)
+ byte[] da, int dp, int len) {
+ encodeISOArrayCheck(sa, sp, da, dp, len);
+ return implEncodeISOArray(sa, sp, da, dp, len);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private static int implEncodeISOArray(char[] sa, int sp,
+ byte[] da, int dp, int len)
{
int i = 0;
for (; i < len; i++) {
@@ -161,6 +171,34 @@
return i;
}
+ private static void encodeISOArrayCheck(char[] sa, int sp,
+ byte[] da, int dp, int len) {
+ if (len <= 0) {
+ return; // not an error because encodeISOArrayImpl won't execute if len <= 0
+ }
+
+ Objects.requireNonNull(sa);
+ Objects.requireNonNull(da);
+
+ if (sp < 0 || sp >= sa.length) {
+ throw new ArrayIndexOutOfBoundsException(sp);
+ }
+
+ if (dp < 0 || dp >= da.length) {
+ throw new ArrayIndexOutOfBoundsException(dp);
+ }
+
+ int endIndexSP = sp + len - 1;
+ if (endIndexSP < 0 || endIndexSP >= sa.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndexSP);
+ }
+
+ int endIndexDP = dp + len - 1;
+ if (endIndexDP < 0 || endIndexDP >= da.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndexDP);
+ }
+ }
+
private CoderResult encodeArrayLoop(CharBuffer src,
ByteBuffer dst)
{
--- a/jdk/src/java.base/share/classes/sun/reflect/Reflection.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/reflect/Reflection.java Fri Jul 03 07:23:45 2015 +0200
@@ -28,6 +28,7 @@
import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Map;
+import jdk.internal.HotSpotIntrinsicCandidate;
/** Common utility routines used by both java.lang and
java.lang.reflect */
@@ -56,6 +57,7 @@
ignoring frames associated with java.lang.reflect.Method.invoke()
and its implementation. */
@CallerSensitive
+ @HotSpotIntrinsicCandidate
public static native Class<?> getCallerClass();
/**
@@ -74,6 +76,7 @@
to compatibility reasons; see 4471811. Only the values of the
low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
valid. */
+ @HotSpotIntrinsicCandidate
public static native int getClassAccessFlags(Class<?> c);
/** A quick "fast-path" check to try to avoid getCallerClass()
--- a/jdk/src/java.base/share/classes/sun/security/provider/DigestBase.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DigestBase.java Fri Jul 03 07:23:45 2015 +0200
@@ -28,6 +28,9 @@
import java.security.MessageDigestSpi;
import java.security.DigestException;
import java.security.ProviderException;
+import java.util.Objects;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* Common base message digest implementation for the Sun provider.
@@ -136,12 +139,36 @@
// compress complete blocks
private int implCompressMultiBlock(byte[] b, int ofs, int limit) {
+ implCompressMultiBlockCheck(b, ofs, limit);
+ return implCompressMultiBlock0(b, ofs, limit);
+ }
+
+ @HotSpotIntrinsicCandidate
+ private int implCompressMultiBlock0(byte[] b, int ofs, int limit) {
for (; ofs <= limit; ofs += blockSize) {
implCompress(b, ofs);
}
return ofs;
}
+ private void implCompressMultiBlockCheck(byte[] b, int ofs, int limit) {
+ if (limit < 0) {
+ return; // not an error because implCompressMultiBlockImpl won't execute if limit < 0
+ // and an exception is thrown if ofs < 0.
+ }
+
+ Objects.requireNonNull(b);
+
+ if (ofs < 0 || ofs >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(ofs);
+ }
+
+ int endIndex = (limit / blockSize) * blockSize + blockSize - 1;
+ if (endIndex >= b.length) {
+ throw new ArrayIndexOutOfBoundsException(endIndex);
+ }
+ }
+
// reset this object. See JCA doc.
protected final void engineReset() {
if (bytesProcessed == 0) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/SHA.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SHA.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,7 +25,10 @@
package sun.security.provider;
+import java.util.Objects;
+
import static sun.security.provider.ByteArrayAccess.*;
+import jdk.internal.HotSpotIntrinsicCandidate;
/**
* This class implements the Secure Hash Algorithm (SHA) developed by
@@ -114,8 +117,27 @@
* "old" NIST Secure Hash Algorithm.
*/
void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig64'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2iBig64(buf, ofs, W);
+ }
+ // The method 'implCompressImpl seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ @HotSpotIntrinsicCandidate
+ private void implCompress0(byte[] buf, int ofs) {
// The first 16 ints have the byte stream, compute the rest of
// the buffer
for (int t = 16; t <= 79; t++) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/SHA2.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SHA2.java Fri Jul 03 07:23:45 2015 +0200
@@ -25,6 +25,9 @@
package sun.security.provider;
+import java.util.Objects;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
import static sun.security.provider.ByteArrayAccess.*;
/**
@@ -186,8 +189,27 @@
* Process the current block to update the state variable state.
*/
void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig64'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2iBig64(buf, ofs, W);
+ }
+ // The method 'implCompressImpl' seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ @HotSpotIntrinsicCandidate
+ private void implCompress0(byte[] buf, int ofs) {
// The first 16 ints are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/SHA5.java Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/classes/sun/security/provider/SHA5.java Fri Jul 03 07:23:45 2015 +0200
@@ -26,8 +26,10 @@
package sun.security.provider;
import java.security.*;
+import java.util.Objects;
import java.math.BigInteger;
+import jdk.internal.HotSpotIntrinsicCandidate;
import static sun.security.provider.ByteArrayAccess.*;
/**
@@ -205,8 +207,27 @@
* "old" NIST Secure Hash Algorithm.
*/
final void implCompress(byte[] buf, int ofs) {
+ implCompressCheck(buf, ofs);
+ implCompress0(buf, ofs);
+ }
+
+ private void implCompressCheck(byte[] buf, int ofs) {
+ Objects.requireNonNull(buf);
+
+ // The checks performed by the method 'b2iBig128'
+ // are sufficient for the case when the method
+ // 'implCompressImpl' is replaced with a compiler
+ // intrinsic.
b2lBig128(buf, ofs, W);
+ }
+ // The method 'implCompressImpl' seems not to use its parameters.
+ // The method can, however, be replaced with a compiler intrinsic
+ // that operates directly on the array 'buf' (starting from
+ // offset 'ofs') and not on array 'W', therefore 'buf' and 'ofs'
+ // must be passed as parameter to the method.
+ @HotSpotIntrinsicCandidate
+ private final void implCompress0(byte[] buf, int ofs) {
// The first 16 longs are from the byte stream, compute the rest of
// the W[]'s
for (int t = 16; t < ITERATION; t++) {
--- a/jdk/src/java.base/share/native/libzip/CRC32.c Thu Jul 02 17:50:25 2015 -0700
+++ b/jdk/src/java.base/share/native/libzip/CRC32.c Fri Jul 03 07:23:45 2015 +0200
@@ -43,8 +43,8 @@
}
JNIEXPORT jint JNICALL
-Java_java_util_zip_CRC32_updateBytes(JNIEnv *env, jclass cls, jint crc,
- jarray b, jint off, jint len)
+Java_java_util_zip_CRC32_updateBytes0(JNIEnv *env, jclass cls, jint crc,
+ jarray b, jint off, jint len)
{
Bytef *buf = (*env)->GetPrimitiveArrayCritical(env, b, 0);
if (buf) {
@@ -61,8 +61,8 @@
}
JNIEXPORT jint JNICALL
-Java_java_util_zip_CRC32_updateByteBuffer(JNIEnv *env, jclass cls, jint crc,
- jlong address, jint off, jint len)
+Java_java_util_zip_CRC32_updateByteBuffer0(JNIEnv *env, jclass cls, jint crc,
+ jlong address, jint off, jint len)
{
Bytef *buf = (Bytef *)jlong_to_ptr(address);
if (buf) {