8212597: Optimize String concatenation setup when using primitive operands
Reviewed-by: shade
This commit is contained in:
parent
da989adeb7
commit
b3b41df70f
@ -66,6 +66,15 @@ public class HelloClasslist {
|
|||||||
Stream.of(helloWorld.split(","))
|
Stream.of(helloWorld.split(","))
|
||||||
.forEach(System.out::println);
|
.forEach(System.out::println);
|
||||||
|
|
||||||
|
// Common concatenation patterns
|
||||||
|
String const_I = "string" + args.length;
|
||||||
|
String const_S = "string" + String.valueOf(args.length);
|
||||||
|
String S_const = String.valueOf(args.length) + "string";
|
||||||
|
String S_S = String.valueOf(args.length) + String.valueOf(args.length);
|
||||||
|
String const_J = "string" + System.currentTimeMillis();
|
||||||
|
String I_const = args.length + "string";
|
||||||
|
String J_const = System.currentTimeMillis() + "string";
|
||||||
|
|
||||||
String newDate = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(
|
String newDate = DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(
|
||||||
LocalDateTime.now(ZoneId.of("GMT")));
|
LocalDateTime.now(ZoneId.of("GMT")));
|
||||||
|
|
||||||
|
@ -138,61 +138,6 @@ final class StringConcatHelper {
|
|||||||
return (byte)(current | value.coder());
|
return (byte)(current | value.coder());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Mix coder into current coder
|
|
||||||
* @param current current coder
|
|
||||||
* @param value value to mix in
|
|
||||||
* @return new coder
|
|
||||||
*/
|
|
||||||
static byte mixCoder(byte current, boolean value) {
|
|
||||||
// Booleans are represented with Latin1
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mix coder into current coder
|
|
||||||
* @param current current coder
|
|
||||||
* @param value value to mix in
|
|
||||||
* @return new coder
|
|
||||||
*/
|
|
||||||
static byte mixCoder(byte current, byte value) {
|
|
||||||
// Bytes are represented with Latin1
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mix coder into current coder
|
|
||||||
* @param current current coder
|
|
||||||
* @param value value to mix in
|
|
||||||
* @return new coder
|
|
||||||
*/
|
|
||||||
static byte mixCoder(byte current, short value) {
|
|
||||||
// Shorts are represented with Latin1
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mix coder into current coder
|
|
||||||
* @param current current coder
|
|
||||||
* @param value value to mix in
|
|
||||||
* @return new coder
|
|
||||||
*/
|
|
||||||
static byte mixCoder(byte current, int value) {
|
|
||||||
// Ints are represented with Latin1
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mix coder into current coder
|
|
||||||
* @param current current coder
|
|
||||||
* @param value value to mix in
|
|
||||||
* @return new coder
|
|
||||||
*/
|
|
||||||
static byte mixCoder(byte current, long value) {
|
|
||||||
// Longs are represented with Latin1
|
|
||||||
return current;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepends the stringly representation of boolean value into buffer,
|
* Prepends the stringly representation of boolean value into buffer,
|
||||||
* given the coder and final index. Index is measured in chars, not in bytes!
|
* given the coder and final index. Index is measured in chars, not in bytes!
|
||||||
|
@ -1588,9 +1588,26 @@ public final class StringConcatFactory {
|
|||||||
|
|
||||||
Class<?> argClass = ptypes[ac];
|
Class<?> argClass = ptypes[ac];
|
||||||
MethodHandle lm = lengthMixer(argClass);
|
MethodHandle lm = lengthMixer(argClass);
|
||||||
MethodHandle cm = coderMixer(argClass);
|
|
||||||
|
|
||||||
// Read this bottom up:
|
// Read these bottom up:
|
||||||
|
|
||||||
|
if (argClass.isPrimitive() && argClass != char.class) {
|
||||||
|
|
||||||
|
// 3. Drop old index, producing ("new-index", "coder", <args>)
|
||||||
|
mh = MethodHandles.dropArguments(mh, 1, int.class);
|
||||||
|
|
||||||
|
// 2. Compute "new-index", producing ("new-index", "old-index", "coder", <args>)
|
||||||
|
// Length mixer needs old index, plus the appropriate argument
|
||||||
|
mh = MethodHandles.foldArguments(mh, 0, lm,
|
||||||
|
1, // old-index
|
||||||
|
3 + ac // selected argument
|
||||||
|
);
|
||||||
|
|
||||||
|
// 1. The mh shape here is ("old-index", "coder", <args>); we don't need to recalculate
|
||||||
|
// the coder for non-char primitive arguments
|
||||||
|
|
||||||
|
} else {
|
||||||
|
MethodHandle cm = coderMixer(argClass);
|
||||||
|
|
||||||
// 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
|
// 4. Drop old index and coder, producing ("new-index", "new-coder", <args>)
|
||||||
mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
|
mh = MethodHandles.dropArguments(mh, 2, int.class, byte.class);
|
||||||
@ -1610,6 +1627,8 @@ public final class StringConcatFactory {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 1. The mh shape here is ("old-index", "old-coder", <args>)
|
// 1. The mh shape here is ("old-index", "old-coder", <args>)
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new StringConcatException("Unhandled tag: " + el.getTag());
|
throw new StringConcatException("Unhandled tag: " + el.getTag());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user