8150463: StringConcat MH_INLINE_SIZED_EXACT should skip storage initialization

Reviewed-by: plevart, chegar
This commit is contained in:
Aleksey Shipilev 2016-03-24 12:52:03 +03:00
parent 05feaeeecd
commit ccdf984e57

@ -1478,6 +1478,7 @@ public final class StringConcatFactory {
* 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 @@ public final class StringConcatFactory {
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 @@ public final class StringConcatFactory {
@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 @@ public final class StringConcatFactory {
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);
}
}