< prev index next >

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

Print this page

        

@@ -1476,10 +1476,11 @@
      * 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,14 +1511,13 @@
             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) {
+            // 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,17 +1648,17 @@
             }
         }
 
         @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;
         }
 
         private static MethodHandle prepender(Class<?> cl) {

@@ -1719,16 +1719,11 @@
             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
< prev index next >