From 5d1df35fe7e3317a6b3af4fb280a15f37df28c96 Mon Sep 17 00:00:00 2001 From: Claes Redestad Date: Thu, 9 May 2019 17:28:27 +0200 Subject: [PATCH] 8223454: Reduce String concatenation shapes by folding initialLengthCoder into last mixer Reviewed-by: jlaskey --- .../java/lang/invoke/StringConcatFactory.java | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index 6e96e9beafe..569112c8f45 100644 --- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -1666,25 +1666,33 @@ public final class StringConcatFactory { // and deduce the coder from there. Arguments would be either converted to Strings // during the initial filtering, or handled by specializations in MIXERS. // - // The method handle shape before and after all mixers are combined in is: + // The method handle shape before all mixers are combined in is: // (long, )String = ("indexCoder", ) + // + // We will bind the initialLengthCoder value to the last mixer (the one that will be + // executed first), then fold that in. This leaves the shape after all mixers are + // combined in as: + // ()String = () + int ac = -1; + MethodHandle mix = null; for (RecipeElement el : recipe.getElements()) { switch (el.getTag()) { case TAG_CONST: // Constants already handled in the code above break; case TAG_ARG: - int ac = el.getArgPos(); + if (ac >= 0) { + // Compute new "index" in-place using old value plus the appropriate argument. + mh = MethodHandles.filterArgumentsWithCombiner(mh, 0, mix, + 0, // old-index + 1 + ac // selected argument + ); + } + ac = el.getArgPos(); Class argClass = ptypes[ac]; - MethodHandle mix = mixer(argClass); - - // Compute new "index" in-place using old value plus the appropriate argument. - mh = MethodHandles.filterArgumentsWithCombiner(mh, 0, mix, - 0, // old-index - 1 + ac // selected argument - ); + mix = mixer(argClass); break; default: @@ -1692,9 +1700,19 @@ public final class StringConcatFactory { } } - // Insert initial length and coder value here. + // Insert the initialLengthCoder value into the final mixer, then + // fold that into the base method handle + if (ac >= 0) { + mix = MethodHandles.insertArguments(mix, 0, initialLengthCoder); + mh = MethodHandles.foldArgumentsWithCombiner(mh, 0, mix, + 1 + ac // selected argument + ); + } else { + // No mixer (constants only concat), insert initialLengthCoder directly + mh = MethodHandles.insertArguments(mh, 0, initialLengthCoder); + } + // The method handle shape here is (). - mh = MethodHandles.insertArguments(mh, 0, initialLengthCoder); // Apply filters, converting the arguments: if (filters != null) {