< prev index next >

src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java

Print this page

        

*** 1476,1485 **** --- 1476,1486 ---- * particular implementation details for String, this opens the door for * building a very optimal concatenation sequence. This is the only strategy * 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 }
*** 1510,1523 **** MethodHandle mh; 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); - } // 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 // *ending* index. for (RecipeElement el : recipe.getElements()) { --- 1511,1523 ---- MethodHandle mh; mh = MethodHandles.dropArguments(NEW_STRING, 2, ptypes); mh = MethodHandles.dropArguments(mh, 0, int.class); ! // 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 // *ending* index. for (RecipeElement el : recipe.getElements()) {
*** 1648,1664 **** } } @ForceInline private static byte[] newArray(int length, byte coder) { ! return new byte[length << coder]; } @ForceInline private static int checkIndex(int index) { if (index != 0) { ! throw new AssertionError("Exactness check failed: " + index + " characters left in the buffer."); } return index; } private static MethodHandle prepender(Class<?> cl) { --- 1648,1664 ---- } } @ForceInline private static byte[] newArray(int length, byte coder) { ! return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, length << coder); } @ForceInline private static int checkIndex(int index) { if (index != 0) { ! throw new IllegalStateException("Storage is not completely initialized, " + index + " bytes left"); } return index; } private static MethodHandle prepender(Class<?> cl) {
*** 1719,1734 **** LENGTH_MIXERS = new ConcurrentHashMap<>(); CODER_MIXERS = new ConcurrentHashMap<>(); 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; - } } } /** * Public gateways to public "stringify" methods. These methods have the form String apply(T obj), and normally --- 1719,1729 ----
< prev index next >