On Wed, 8 Jun 2022 12:11:30 GMT, Сергей Цыпанов <d...@openjdk.java.net> wrote:

>> To take optimal advantage of the pre-existing optimization for repeated 
>> filters we could split the application of different types of stringifiers.
>> 
>> The resulting difference in order of evaluation is not observable by 
>> conventional means since all reference type share the same object 
>> stringifier, and the others are filtering primitives (floats and doubles) 
>> which have been passed by value already. 
>> 
>> This change neutral on many concatenation expression shapes, but for any 
>> complex expressions with interleaving float/double and reference parameters 
>> it brings a straightforward reduction in rebinds and underlying LFs 
>> generated. For example on the 
>> [MixedStringCombinations.java](https://gist.github.com/cl4es/08fb581dece3a73e89bfa52337bc4248)
>>  test there's a modest 2% reduction in total classes loaded with this change 
>> (from 16209 to 15872)
>
> src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java line 
> 509:
> 
>> 507:                     doubleFilters = new MethodHandle[ptypes.length];
>> 508:                 }
>> 509:                 doubleFilters[i] = doubleStringifier();
> 
> Why do we have `ptypes[i] = int.class` for `int` and `short`, `ptypes[i] = 
> String.class` for `float`, `double` and `Object` and none for `boolean` and 
> `char`? 🧐

`Object`, `float` and `double` arguments are all eagerly transformed to 
`String` (this is what the "stringifiers" do). Since we apply these as filters 
as a last step (which means that's the first thing that will run) we then must 
change the internal type to `String`. Ultimately means we have fewer types to 
worry about in the combinator.

We also widen integral subword types to `int` (`short` and `byte`). This 
doesn't need to be adapted by filtering but can lean on implicit conversion 
(subword primitives are widened to int anyhow, what we care about is matching 
the correct logic). This mainly matters insofar that the same direct method 
handle will be used for these three types, as it can (and will) be adapted 
without modification by the `viewAsType` call that ensures the `MH` returned 
from the BSM has the exact type asked for. 

`boolean` and `char` types can't use the `int` mixers/prependers and instead 
have specialized methods that will be adapted into the concat MH tree. This 
means the parameter type stays `boolean` and `char` throughout, respectively.

-------------

PR: https://git.openjdk.java.net/jdk/pull/9082

Reply via email to