1 /*
2  * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.lang;
27 
28 import jdk.internal.misc.Unsafe;
29 import jdk.internal.vm.annotation.ForceInline;
30 
31 import java.lang.invoke.MethodHandle;
32 import java.lang.invoke.MethodHandles;
33 import java.lang.invoke.MethodType;
34 
35 /**
36  * Helper for string concatenation. These methods are mostly looked up with private lookups
37  * from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle}
38  * combinators there.
39  */
40 final class StringConcatHelper {
41 
StringConcatHelper()42     private StringConcatHelper() {
43         // no instantiation
44     }
45 
46     /**
47      * Check for overflow, throw exception on overflow.
48      *
49      * @param lengthCoder String length with coder packed into higher bits
50      *                    the upper word.
51      * @return            the given parameter value, if valid
52      */
checkOverflow(long lengthCoder)53     private static long checkOverflow(long lengthCoder) {
54         if ((int)lengthCoder >= 0) {
55             return lengthCoder;
56         }
57         throw new OutOfMemoryError("Overflow: String length out of range");
58     }
59 
60     /**
61      * Mix value length and coder into current length and coder.
62      * @param lengthCoder String length with coder packed into higher bits
63      *                    the upper word.
64      * @param value       value to mix in
65      * @return            new length and coder
66      */
mix(long lengthCoder, boolean value)67     static long mix(long lengthCoder, boolean value) {
68         return checkOverflow(lengthCoder + (value ? 4 : 5));
69     }
70 
71     /**
72      * Mix value length and coder into current length and coder.
73      * @param lengthCoder String length with coder packed into higher bits
74      *                    the upper word.
75      * @param value       value to mix in
76      * @return            new length and coder
77      */
mix(long lengthCoder, byte value)78     static long mix(long lengthCoder, byte value) {
79         return mix(lengthCoder, (int)value);
80     }
81 
82     /**
83      * Mix value length and coder into current length and coder.
84      * @param lengthCoder String length with coder packed into higher bits
85      *                    the upper word.
86      * @param value       value to mix in
87      * @return            new length and coder
88      */
mix(long lengthCoder, char value)89     static long mix(long lengthCoder, char value) {
90         return checkOverflow(lengthCoder + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16);
91     }
92 
93     /**
94      * Mix value length and coder into current length and coder.
95      * @param lengthCoder String length with coder packed into higher bits
96      *                    the upper word.
97      * @param value       value to mix in
98      * @return            new length and coder
99      */
mix(long lengthCoder, short value)100     static long mix(long lengthCoder, short value) {
101         return mix(lengthCoder, (int)value);
102     }
103 
104     /**
105      * Mix value length and coder into current length and coder.
106      * @param lengthCoder String length with coder packed into higher bits
107      *                    the upper word.
108      * @param value       value to mix in
109      * @return            new length and coder
110      */
mix(long lengthCoder, int value)111     static long mix(long lengthCoder, int value) {
112         return checkOverflow(lengthCoder + Integer.stringSize(value));
113     }
114 
115     /**
116      * Mix value length and coder into current length and coder.
117      * @param lengthCoder String length with coder packed into higher bits
118      *                    the upper word.
119      * @param value       value to mix in
120      * @return            new length and coder
121      */
mix(long lengthCoder, long value)122     static long mix(long lengthCoder, long value) {
123         return checkOverflow(lengthCoder + Long.stringSize(value));
124     }
125 
126     /**
127      * Mix value length and coder into current length and coder.
128      * @param lengthCoder String length with coder packed into higher bits
129      *                    the upper word.
130      * @param value       value to mix in
131      * @return            new length and coder
132      */
mix(long lengthCoder, String value)133     static long mix(long lengthCoder, String value) {
134         lengthCoder += value.length();
135         if (value.coder() == String.UTF16) {
136             lengthCoder |= UTF16;
137         }
138         return checkOverflow(lengthCoder);
139     }
140 
141     /**
142      * Prepends the stringly representation of boolean value into buffer,
143      * given the coder and final index. Index is measured in chars, not in bytes!
144      *
145      * @param indexCoder final char index in the buffer, along with coder packed
146      *                   into higher bits.
147      * @param buf        buffer to append to
148      * @param value      boolean value to encode
149      * @return           updated index (coder value retained)
150      */
prepend(long indexCoder, byte[] buf, boolean value)151     private static long prepend(long indexCoder, byte[] buf, boolean value) {
152         int index = (int)indexCoder;
153         if (indexCoder < UTF16) {
154             if (value) {
155                 buf[--index] = 'e';
156                 buf[--index] = 'u';
157                 buf[--index] = 'r';
158                 buf[--index] = 't';
159             } else {
160                 buf[--index] = 'e';
161                 buf[--index] = 's';
162                 buf[--index] = 'l';
163                 buf[--index] = 'a';
164                 buf[--index] = 'f';
165             }
166             return index;
167         } else {
168             if (value) {
169                 StringUTF16.putChar(buf, --index, 'e');
170                 StringUTF16.putChar(buf, --index, 'u');
171                 StringUTF16.putChar(buf, --index, 'r');
172                 StringUTF16.putChar(buf, --index, 't');
173             } else {
174                 StringUTF16.putChar(buf, --index, 'e');
175                 StringUTF16.putChar(buf, --index, 's');
176                 StringUTF16.putChar(buf, --index, 'l');
177                 StringUTF16.putChar(buf, --index, 'a');
178                 StringUTF16.putChar(buf, --index, 'f');
179             }
180             return index | UTF16;
181         }
182     }
183 
184     /**
185      * Prepends constant and the stringly representation of value into buffer,
186      * given the coder and final index. Index is measured in chars, not in bytes!
187      *
188      * @param indexCoder final char index in the buffer, along with coder packed
189      *                   into higher bits.
190      * @param buf        buffer to append to
191      * @param value      boolean value to encode
192      * @param prefix     a constant to prepend before value
193      * @return           updated index (coder value retained)
194      */
prepend(long indexCoder, byte[] buf, boolean value, String prefix)195     static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) {
196         indexCoder = prepend(indexCoder, buf, value);
197         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
198         return indexCoder;
199     }
200 
201     /**
202      * Prepends constant and the stringly representation of value into buffer,
203      * given the coder and final index. Index is measured in chars, not in bytes!
204      *
205      * @param indexCoder final char index in the buffer, along with coder packed
206      *                   into higher bits.
207      * @param buf        buffer to append to
208      * @param value      boolean value to encode
209      * @param prefix     a constant to prepend before value
210      * @return           updated index (coder value retained)
211      */
prepend(long indexCoder, byte[] buf, byte value, String prefix)212     static long prepend(long indexCoder, byte[] buf, byte value, String prefix) {
213         indexCoder = prepend(indexCoder, buf, (int)value);
214         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
215         return indexCoder;
216     }
217 
218     /**
219      * Prepends the stringly representation of char value into buffer,
220      * given the coder and final index. Index is measured in chars, not in bytes!
221      *
222      * @param indexCoder final char index in the buffer, along with coder packed
223      *                   into higher bits.
224      * @param buf        buffer to append to
225      * @param value      char value to encode
226      * @return           updated index (coder value retained)
227      */
prepend(long indexCoder, byte[] buf, char value)228     private static long prepend(long indexCoder, byte[] buf, char value) {
229         if (indexCoder < UTF16) {
230             buf[(int)(--indexCoder)] = (byte) (value & 0xFF);
231         } else {
232             StringUTF16.putChar(buf, (int)(--indexCoder), value);
233         }
234         return indexCoder;
235     }
236 
237     /**
238      * Prepends constant and the stringly representation of value into buffer,
239      * given the coder and final index. Index is measured in chars, not in bytes!
240      *
241      * @param indexCoder final char index in the buffer, along with coder packed
242      *                   into higher bits.
243      * @param buf        buffer to append to
244      * @param value      boolean value to encode
245      * @param prefix     a constant to prepend before value
246      * @return           updated index (coder value retained)
247      */
prepend(long indexCoder, byte[] buf, char value, String prefix)248     static long prepend(long indexCoder, byte[] buf, char value, String prefix) {
249         indexCoder = prepend(indexCoder, buf, value);
250         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
251         return indexCoder;
252     }
253 
254     /**
255      * Prepends constant and the stringly representation of value into buffer,
256      * given the coder and final index. Index is measured in chars, not in bytes!
257      *
258      * @param indexCoder final char index in the buffer, along with coder packed
259      *                   into higher bits.
260      * @param buf        buffer to append to
261      * @param value      boolean value to encode
262      * @param prefix     a constant to prepend before value
263      * @return           updated index (coder value retained)
264      */
prepend(long indexCoder, byte[] buf, short value, String prefix)265     static long prepend(long indexCoder, byte[] buf, short value, String prefix) {
266         indexCoder = prepend(indexCoder, buf, (int)value);
267         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
268         return indexCoder;
269     }
270 
271     /**
272      * Prepends the stringly representation of integer value into buffer,
273      * given the coder and final index. Index is measured in chars, not in bytes!
274      *
275      * @param indexCoder final char index in the buffer, along with coder packed
276      *                   into higher bits.
277      * @param buf        buffer to append to
278      * @param value      integer value to encode
279      * @return           updated index (coder value retained)
280      */
prepend(long indexCoder, byte[] buf, int value)281     private static long prepend(long indexCoder, byte[] buf, int value) {
282         if (indexCoder < UTF16) {
283             return Integer.getChars(value, (int)indexCoder, buf);
284         } else {
285             return StringUTF16.getChars(value, (int)indexCoder, buf) | UTF16;
286         }
287     }
288 
289     /**
290      * Prepends constant and the stringly representation of value into buffer,
291      * given the coder and final index. Index is measured in chars, not in bytes!
292      *
293      * @param indexCoder final char index in the buffer, along with coder packed
294      *                   into higher bits.
295      * @param buf        buffer to append to
296      * @param value      boolean value to encode
297      * @param prefix     a constant to prepend before value
298      * @return           updated index (coder value retained)
299      */
prepend(long indexCoder, byte[] buf, int value, String prefix)300     static long prepend(long indexCoder, byte[] buf, int value, String prefix) {
301         indexCoder = prepend(indexCoder, buf, value);
302         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
303         return indexCoder;
304     }
305 
306     /**
307      * Prepends the stringly representation of long value into buffer,
308      * given the coder and final index. Index is measured in chars, not in bytes!
309      *
310      * @param indexCoder final char index in the buffer, along with coder packed
311      *                   into higher bits.
312      * @param buf        buffer to append to
313      * @param value      long value to encode
314      * @return           updated index (coder value retained)
315      */
prepend(long indexCoder, byte[] buf, long value)316     private static long prepend(long indexCoder, byte[] buf, long value) {
317         if (indexCoder < UTF16) {
318             return Long.getChars(value, (int)indexCoder, buf);
319         } else {
320             return StringUTF16.getChars(value, (int)indexCoder, buf) | UTF16;
321         }
322     }
323 
324     /**
325      * Prepends constant and the stringly representation of value into buffer,
326      * given the coder and final index. Index is measured in chars, not in bytes!
327      *
328      * @param indexCoder final char index in the buffer, along with coder packed
329      *                   into higher bits.
330      * @param buf        buffer to append to
331      * @param value      boolean value to encode
332      * @param prefix     a constant to prepend before value
333      * @return           updated index (coder value retained)
334      */
prepend(long indexCoder, byte[] buf, long value, String prefix)335     static long prepend(long indexCoder, byte[] buf, long value, String prefix) {
336         indexCoder = prepend(indexCoder, buf, value);
337         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
338         return indexCoder;
339     }
340 
341     /**
342      * Prepends the stringly representation of String value into buffer,
343      * given the coder and final index. Index is measured in chars, not in bytes!
344      *
345      * @param indexCoder final char index in the buffer, along with coder packed
346      *                   into higher bits.
347      * @param buf        buffer to append to
348      * @param value      String value to encode
349      * @return           updated index (coder value retained)
350      */
prepend(long indexCoder, byte[] buf, String value)351     private static long prepend(long indexCoder, byte[] buf, String value) {
352         indexCoder -= value.length();
353         if (indexCoder < UTF16) {
354             value.getBytes(buf, (int)indexCoder, String.LATIN1);
355         } else {
356             value.getBytes(buf, (int)indexCoder, String.UTF16);
357         }
358         return indexCoder;
359     }
360 
361     /**
362      * Prepends constant and the stringly representation of value into buffer,
363      * given the coder and final index. Index is measured in chars, not in bytes!
364      *
365      * @param indexCoder final char index in the buffer, along with coder packed
366      *                   into higher bits.
367      * @param buf        buffer to append to
368      * @param value      boolean value to encode
369      * @param prefix     a constant to prepend before value
370      * @return           updated index (coder value retained)
371      */
prepend(long indexCoder, byte[] buf, String value, String prefix)372     static long prepend(long indexCoder, byte[] buf, String value, String prefix) {
373         indexCoder = prepend(indexCoder, buf, value);
374         if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix);
375         return indexCoder;
376     }
377 
378     /**
379      * Instantiates the String with given buffer and coder
380      * @param buf           buffer to use
381      * @param indexCoder    remaining index (should be zero) and coder
382      * @return String       resulting string
383      */
newString(byte[] buf, long indexCoder)384     static String newString(byte[] buf, long indexCoder) {
385         // Use the private, non-copying constructor (unsafe!)
386         if (indexCoder == LATIN1) {
387             return new String(buf, String.LATIN1);
388         } else if (indexCoder == UTF16) {
389             return new String(buf, String.UTF16);
390         } else {
391             throw new InternalError("Storage is not completely initialized, " + (int)indexCoder + " bytes left");
392         }
393     }
394 
395     /**
396      * Perform a simple concatenation between two objects. Added for startup
397      * performance, but also demonstrates the code that would be emitted by
398      * {@code java.lang.invoke.StringConcatFactory$MethodHandleInlineCopyStrategy}
399      * for two Object arguments.
400      *
401      * @param first         first argument
402      * @param second        second argument
403      * @return String       resulting string
404      */
405     @ForceInline
simpleConcat(Object first, Object second)406     static String simpleConcat(Object first, Object second) {
407         String s1 = stringOf(first);
408         String s2 = stringOf(second);
409         if (s1.isEmpty()) {
410             // newly created string required, see JLS 15.18.1
411             return new String(s2);
412         }
413         if (s2.isEmpty()) {
414             // newly created string required, see JLS 15.18.1
415             return new String(s1);
416         }
417         // start "mixing" in length and coder or arguments, order is not
418         // important
419         long indexCoder = mix(initialCoder(), s1);
420         indexCoder = mix(indexCoder, s2);
421         byte[] buf = newArray(indexCoder);
422         // prepend each argument in reverse order, since we prepending
423         // from the end of the byte array
424         indexCoder = prepend(indexCoder, buf, s2);
425         indexCoder = prepend(indexCoder, buf, s1);
426         return newString(buf, indexCoder);
427     }
428 
429     /**
430      * Produce a String from a concatenation of single argument, which we
431      * end up using for trivial concatenations like {@code "" + arg}.
432      *
433      * This will always create a new Object to comply with JLS 15.18.1:
434      * "The String object is newly created unless the expression is a
435      * compile-time constant expression".
436      *
437      * @param arg           the only argument
438      * @return String       resulting string
439      */
440     @ForceInline
newStringOf(Object arg)441     static String newStringOf(Object arg) {
442         return new String(stringOf(arg));
443     }
444 
445     /**
446      * We need some additional conversion for Objects in general, because
447      * {@code String.valueOf(Object)} may return null. String conversion rules
448      * in Java state we need to produce "null" String in this case, so we
449      * provide a customized version that deals with this problematic corner case.
450      */
stringOf(Object value)451     static String stringOf(Object value) {
452         String s;
453         return (value == null || (s = value.toString()) == null) ? "null" : s;
454     }
455 
456     private static final long LATIN1 = (long)String.LATIN1 << 32;
457 
458     private static final long UTF16 = (long)String.UTF16 << 32;
459 
460     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
461 
462     /**
463      * Allocates an uninitialized byte array based on the length and coder
464      * information, then prepends the given suffix string at the end of the
465      * byte array before returning it. The calling code must adjust the
466      * indexCoder so that it's taken the coder of the suffix into account, but
467      * subtracted the length of the suffix.
468      *
469      * @param suffix
470      * @param indexCoder
471      * @return the newly allocated byte array
472      */
473     @ForceInline
newArrayWithSuffix(String suffix, long indexCoder)474     static byte[] newArrayWithSuffix(String suffix, long indexCoder) {
475         byte[] buf = newArray(indexCoder + suffix.length());
476         if (indexCoder < UTF16) {
477             suffix.getBytes(buf, (int)indexCoder, String.LATIN1);
478         } else {
479             suffix.getBytes(buf, (int)indexCoder, String.UTF16);
480         }
481         return buf;
482     }
483 
484     /**
485      * Allocates an uninitialized byte array based on the length and coder information
486      * in indexCoder
487      * @param indexCoder
488      * @return the newly allocated byte array
489      */
490     @ForceInline
newArray(long indexCoder)491     static byte[] newArray(long indexCoder) {
492         byte coder = (byte)(indexCoder >> 32);
493         int index = (int)indexCoder;
494         return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder);
495     }
496 
497     /**
498      * Provides the initial coder for the String.
499      * @return initial coder, adjusted into the upper half
500      */
initialCoder()501     static long initialCoder() {
502         return String.COMPACT_STRINGS ? LATIN1 : UTF16;
503     }
504 
lookupStatic(String name, MethodType methodType)505     static MethodHandle lookupStatic(String name, MethodType methodType) {
506         try {
507             return MethodHandles.lookup().findStatic(StringConcatHelper.class, name, methodType);
508         } catch (NoSuchMethodException|IllegalAccessException e) {
509             throw new AssertionError(e);
510         }
511     }
512 
513 }
514