1 /* 2 * Copyright (c) 2015, 2019, 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 /** 32 * Helper for string concatenation. These methods are mostly looked up with private lookups 33 * from {@link java.lang.invoke.StringConcatFactory}, and used in {@link java.lang.invoke.MethodHandle} 34 * combinators there. 35 */ 36 final class StringConcatHelper { 37 38 private StringConcatHelper() { 39 // no instantiation 40 } 41 42 /** 43 * Check for overflow, throw exception on overflow. 44 * 45 * @param lengthCoder String length with coder packed into higher bits 46 * the upper word. 47 * @return the given parameter value, if valid 48 */ 49 private static long checkOverflow(long lengthCoder) { 50 if ((int)lengthCoder >= 0) { 51 return lengthCoder; 52 } 53 throw new OutOfMemoryError("Overflow: String length out of range"); 54 } 55 56 /** 57 * Mix value length and coder into current length and coder. 58 * @param lengthCoder String length with coder packed into higher bits 59 * the upper word. 60 * @param value value to mix in 61 * @return new length and coder 62 */ 63 static long mix(long lengthCoder, boolean value) { 64 return checkOverflow(lengthCoder + (value ? 4 : 5)); 65 } 66 67 /** 68 * Mix value length and coder into current length and coder. 69 * @param lengthCoder String length with coder packed into higher bits 70 * the upper word. 71 * @param value value to mix in 72 * @return new length and coder 73 */ 74 static long mix(long lengthCoder, byte value) { 75 return mix(lengthCoder, (int)value); 76 } 77 78 /** 79 * Mix value length and coder into current length and coder. 80 * @param lengthCoder String length with coder packed into higher bits 81 * the upper word. 82 * @param value value to mix in 83 * @return new length and coder 84 */ 85 static long mix(long lengthCoder, char value) { 86 return checkOverflow(lengthCoder + 1) | (StringLatin1.canEncode(value) ? 0 : UTF16); 87 } 88 89 /** 90 * Mix value length and coder into current length and coder. 91 * @param lengthCoder String length with coder packed into higher bits 92 * the upper word. 93 * @param value value to mix in 94 * @return new length and coder 95 */ 96 static long mix(long lengthCoder, short value) { 97 return mix(lengthCoder, (int)value); 98 } 99 100 /** 101 * Mix value length and coder into current length and coder. 102 * @param lengthCoder String length with coder packed into higher bits 103 * the upper word. 104 * @param value value to mix in 105 * @return new length and coder 106 */ 107 static long mix(long lengthCoder, int value) { 108 return checkOverflow(lengthCoder + Integer.stringSize(value)); 109 } 110 111 /** 112 * Mix value length and coder into current length and coder. 113 * @param lengthCoder String length with coder packed into higher bits 114 * the upper word. 115 * @param value value to mix in 116 * @return new length and coder 117 */ 118 static long mix(long lengthCoder, long value) { 119 return checkOverflow(lengthCoder + Long.stringSize(value)); 120 } 121 122 /** 123 * Mix value length and coder into current length and coder. 124 * @param lengthCoder String length with coder packed into higher bits 125 * the upper word. 126 * @param value value to mix in 127 * @return new length and coder 128 */ 129 static long mix(long lengthCoder, String value) { 130 lengthCoder += value.length(); 131 if (value.coder() == String.UTF16) { 132 lengthCoder |= UTF16; 133 } 134 return checkOverflow(lengthCoder); 135 } 136 137 /** 138 * Prepends the stringly representation of boolean value into buffer, 139 * given the coder and final index. Index is measured in chars, not in bytes! 140 * 141 * @param indexCoder final char index in the buffer, along with coder packed 142 * into higher bits. 143 * @param buf buffer to append to 144 * @param value boolean value to encode 145 * @return updated index (coder value retained) 146 */ 147 private static long prepend(long indexCoder, byte[] buf, boolean value) { 148 int index = (int)indexCoder; 149 if (indexCoder < UTF16) { 150 if (value) { 151 buf[--index] = 'e'; 152 buf[--index] = 'u'; 153 buf[--index] = 'r'; 154 buf[--index] = 't'; 155 } else { 156 buf[--index] = 'e'; 157 buf[--index] = 's'; 158 buf[--index] = 'l'; 159 buf[--index] = 'a'; 160 buf[--index] = 'f'; 161 } 162 return index; 163 } else { 164 if (value) { 165 StringUTF16.putChar(buf, --index, 'e'); 166 StringUTF16.putChar(buf, --index, 'u'); 167 StringUTF16.putChar(buf, --index, 'r'); 168 StringUTF16.putChar(buf, --index, 't'); 169 } else { 170 StringUTF16.putChar(buf, --index, 'e'); 171 StringUTF16.putChar(buf, --index, 's'); 172 StringUTF16.putChar(buf, --index, 'l'); 173 StringUTF16.putChar(buf, --index, 'a'); 174 StringUTF16.putChar(buf, --index, 'f'); 175 } 176 return index | UTF16; 177 } 178 } 179 180 /** 181 * Prepends constant and the stringly representation of value into buffer, 182 * given the coder and final index. Index is measured in chars, not in bytes! 183 * 184 * @param indexCoder final char index in the buffer, along with coder packed 185 * into higher bits. 186 * @param buf buffer to append to 187 * @param prefix a constant to prepend before value 188 * @param value boolean value to encode 189 * @param suffix a constant to prepend after value 190 * @return updated index (coder value retained) 191 */ 192 static long prepend(long indexCoder, byte[] buf, String prefix, boolean value, String suffix) { 193 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 194 indexCoder = prepend(indexCoder, buf, value); 195 if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); 196 return indexCoder; 197 } 198 199 /** 200 * Prepends constant and the stringly representation of value into buffer, 201 * given the coder and final index. Index is measured in chars, not in bytes! 202 * 203 * @param indexCoder final char index in the buffer, along with coder packed 204 * into higher bits. 205 * @param buf buffer to append to 206 * @param prefix a constant to prepend before value 207 * @param value boolean value to encode 208 * @param suffix a constant to prepend after value 209 * @return updated index (coder value retained) 210 */ 211 static long prepend(long indexCoder, byte[] buf, String prefix, byte value, String suffix) { 212 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 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 */ 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 prefix a constant to prepend before value 245 * @param value boolean value to encode 246 * @param suffix a constant to prepend after value 247 * @return updated index (coder value retained) 248 */ 249 static long prepend(long indexCoder, byte[] buf, String prefix, char value, String suffix) { 250 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 251 indexCoder = prepend(indexCoder, buf, value); 252 if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); 253 return indexCoder; 254 } 255 256 /** 257 * Prepends constant and the stringly representation of value into buffer, 258 * given the coder and final index. Index is measured in chars, not in bytes! 259 * 260 * @param indexCoder final char index in the buffer, along with coder packed 261 * into higher bits. 262 * @param buf buffer to append to 263 * @param prefix a constant to prepend before value 264 * @param value boolean value to encode 265 * @param suffix a constant to prepend after value 266 * @return updated index (coder value retained) 267 */ 268 static long prepend(long indexCoder, byte[] buf, String prefix, short value, String suffix) { 269 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 270 indexCoder = prepend(indexCoder, buf, (int)value); 271 if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); 272 return indexCoder; 273 } 274 275 /** 276 * Prepends the stringly representation of integer value into buffer, 277 * given the coder and final index. Index is measured in chars, not in bytes! 278 * 279 * @param indexCoder final char index in the buffer, along with coder packed 280 * into higher bits. 281 * @param buf buffer to append to 282 * @param value integer value to encode 283 * @return updated index (coder value retained) 284 */ 285 private static long prepend(long indexCoder, byte[] buf, int value) { 286 if (indexCoder < UTF16) { 287 return Integer.getChars(value, (int)indexCoder, buf); 288 } else { 289 return StringUTF16.getChars(value, (int)indexCoder, buf) | UTF16; 290 } 291 } 292 293 /** 294 * Prepends constant and the stringly representation of value into buffer, 295 * given the coder and final index. Index is measured in chars, not in bytes! 296 * 297 * @param indexCoder final char index in the buffer, along with coder packed 298 * into higher bits. 299 * @param buf buffer to append to 300 * @param prefix a constant to prepend before value 301 * @param value boolean value to encode 302 * @param suffix a constant to prepend after value 303 * @return updated index (coder value retained) 304 */ 305 static long prepend(long indexCoder, byte[] buf, String prefix, int value, String suffix) { 306 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 307 indexCoder = prepend(indexCoder, buf, value); 308 if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); 309 return indexCoder; 310 } 311 312 /** 313 * Prepends the stringly representation of long value into buffer, 314 * given the coder and final index. Index is measured in chars, not in bytes! 315 * 316 * @param indexCoder final char index in the buffer, along with coder packed 317 * into higher bits. 318 * @param buf buffer to append to 319 * @param value long value to encode 320 * @return updated index (coder value retained) 321 */ 322 private static long prepend(long indexCoder, byte[] buf, long value) { 323 if (indexCoder < UTF16) { 324 return Long.getChars(value, (int)indexCoder, buf); 325 } else { 326 return StringUTF16.getChars(value, (int)indexCoder, buf) | UTF16; 327 } 328 } 329 330 /** 331 * Prepends constant and the stringly representation of value into buffer, 332 * given the coder and final index. Index is measured in chars, not in bytes! 333 * 334 * @param indexCoder final char index in the buffer, along with coder packed 335 * into higher bits. 336 * @param buf buffer to append to 337 * @param prefix a constant to prepend before value 338 * @param value boolean value to encode 339 * @param suffix a constant to prepend after value 340 * @return updated index (coder value retained) 341 */ 342 static long prepend(long indexCoder, byte[] buf, String prefix, long value, String suffix) { 343 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 344 indexCoder = prepend(indexCoder, buf, value); 345 if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); 346 return indexCoder; 347 } 348 349 /** 350 * Prepends the stringly representation of String value into buffer, 351 * given the coder and final index. Index is measured in chars, not in bytes! 352 * 353 * @param indexCoder final char index in the buffer, along with coder packed 354 * into higher bits. 355 * @param buf buffer to append to 356 * @param value String value to encode 357 * @return updated index (coder value retained) 358 */ 359 private static long prepend(long indexCoder, byte[] buf, String value) { 360 indexCoder -= value.length(); 361 if (indexCoder < UTF16) { 362 value.getBytes(buf, (int)indexCoder, String.LATIN1); 363 } else { 364 value.getBytes(buf, (int)indexCoder, String.UTF16); 365 } 366 return indexCoder; 367 } 368 369 /** 370 * Prepends constant and the stringly representation of value into buffer, 371 * given the coder and final index. Index is measured in chars, not in bytes! 372 * 373 * @param indexCoder final char index in the buffer, along with coder packed 374 * into higher bits. 375 * @param buf buffer to append to 376 * @param prefix a constant to prepend before value 377 * @param value boolean value to encode 378 * @param suffix a constant to prepend after value 379 * @return updated index (coder value retained) 380 */ 381 static long prepend(long indexCoder, byte[] buf, String prefix, String value, String suffix) { 382 if (suffix != null) indexCoder = prepend(indexCoder, buf, suffix); 383 indexCoder = prepend(indexCoder, buf, value); 384 if (prefix != null) indexCoder = prepend(indexCoder, buf, prefix); 385 return indexCoder; 386 } 387 388 /** 389 * Instantiates the String with given buffer and coder 390 * @param buf buffer to use 391 * @param indexCoder remaining index (should be zero) and coder 392 * @return String resulting string 393 */ 394 static String newString(byte[] buf, long indexCoder) { 395 // Use the private, non-copying constructor (unsafe!) 396 if (indexCoder == LATIN1) { 397 return new String(buf, String.LATIN1); 398 } else if (indexCoder == UTF16) { 399 return new String(buf, String.UTF16); 400 } else { 401 throw new InternalError("Storage is not completely initialized, " + (int)indexCoder + " bytes left"); 402 } 403 } 404 405 /** 406 * Perform a simple concatenation between two objects. Added for startup 407 * performance, but also demonstrates the code that would be emitted by 408 * {@code java.lang.invoke.StringConcatFactory$MethodHandleInlineCopyStrategy} 409 * for two Object arguments. 410 * 411 * @param first first argument 412 * @param second second argument 413 * @return String resulting string 414 */ 415 @ForceInline 416 static String simpleConcat(Object first, Object second) { 417 String s1 = stringOf(first); 418 String s2 = stringOf(second); 419 // start "mixing" in length and coder or arguments, order is not 420 // important 421 long indexCoder = mix(initialCoder(), s2); 422 indexCoder = mix(indexCoder, s1); 423 byte[] buf = newArray(indexCoder); 424 // prepend each argument in reverse order, since we prepending 425 // from the end of the byte array 426 indexCoder = prepend(indexCoder, buf, s2); 427 indexCoder = prepend(indexCoder, buf, s1); 428 return newString(buf, indexCoder); 429 } 430 431 /** 432 * We need some additional conversion for Objects in general, because 433 * {@code String.valueOf(Object)} may return null. String conversion rules 434 * in Java state we need to produce "null" String in this case, so we 435 * provide a customized version that deals with this problematic corner case. 436 */ 437 static String stringOf(Object value) { 438 String s; 439 return (value == null || (s = value.toString()) == null) ? "null" : s; 440 } 441 442 private static final long LATIN1 = (long)String.LATIN1 << 32; 443 444 private static final long UTF16 = (long)String.UTF16 << 32; 445 446 private static final Unsafe UNSAFE = Unsafe.getUnsafe(); 447 448 /** 449 * Allocates an uninitialized byte array based on the length and coder information 450 * in indexCoder 451 * @param indexCoder 452 * @return the newly allocated byte array 453 */ 454 @ForceInline 455 static byte[] newArray(long indexCoder) { 456 byte coder = (byte)(indexCoder >> 32); 457 int index = (int)indexCoder; 458 return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, index << coder); 459 } 460 461 /** 462 * Provides the initial coder for the String. 463 * @return initial coder, adjusted into the upper half 464 */ 465 static long initialCoder() { 466 return String.COMPACT_STRINGS ? LATIN1 : UTF16; 467 } 468 469 }