changeset 13950:3ac7178352fc

8150463: StringConcat MH_INLINE_SIZED_EXACT should skip storage initialization Reviewed-by: plevart, chegar
author shade
date Thu, 24 Mar 2016 12:52:03 +0300
parents 1f84e73abee1
children 8bdb63271ed2
files src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
diffstat 1 files changed, 7 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Mar 23 21:45:11 2016 -0700
+++ b/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);
         }
     }