--- old/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java 2016-03-16 11:05:29.135985985 +0300 +++ new/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java 2016-03-16 11:05:28.979985990 +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); } }