8150463: StringConcat MH_INLINE_SIZED_EXACT should skip storage initialization
Reviewed-by: plevart, chegar
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Wed Mar 23 21:45:11 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Thu Mar 24 12:52:03 2016 +0300
@@ -1478,6 +1478,7 @@
* that requires porting if there are private JDK changes occur.
*/
private static final class MethodHandleInlineCopyStrategy {
+ static final Unsafe UNSAFE = Unsafe.getUnsafe();
private MethodHandleInlineCopyStrategy() {
// no instantiation
@@ -1512,10 +1513,9 @@
mh = MethodHandles.dropArguments(NEW_STRING, 2, ptypes);
mh = MethodHandles.dropArguments(mh, 0, int.class);
- // In debug mode, check that remaining index is zero.
- if (DEBUG) {
- mh = MethodHandles.filterArgument(mh, 0, CHECK_INDEX);
- }
+ // Safety: check that remaining index is zero -- that would mean the storage is completely
+ // overwritten, and no leakage of uninitialized data occurred.
+ mh = MethodHandles.filterArgument(mh, 0, CHECK_INDEX);
// Mix in prependers. This happens when (int, byte[], byte) = (index, storage, coder) is already
// known from the combinators below. We are assembling the string backwards, so "index" is the
@@ -1650,13 +1650,13 @@
@ForceInline
private static byte[] newArray(int length, byte coder) {
- return new byte[length << coder];
+ return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, length << coder);
}
@ForceInline
private static int checkIndex(int index) {
if (index != 0) {
- throw new AssertionError("Exactness check failed: " + index + " characters left in the buffer.");
+ throw new IllegalStateException("Storage is not completely initialized, " + index + " bytes left");
}
return index;
}
@@ -1721,12 +1721,7 @@
NEW_STRING = lookupStatic(Lookup.IMPL_LOOKUP, STRING_HELPER, "newString", String.class, byte[].class, byte.class);
NEW_ARRAY = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "newArray", byte[].class, int.class, byte.class);
-
- if (DEBUG) {
- CHECK_INDEX = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "checkIndex", int.class, int.class);
- } else {
- CHECK_INDEX = null;
- }
+ CHECK_INDEX = lookupStatic(Lookup.IMPL_LOOKUP, MethodHandleInlineCopyStrategy.class, "checkIndex", int.class, int.class);
}
}