Class StringConcatFactory
Methods to facilitate the creation of String concatenation methods, that
can be used to efficiently concatenate a known number of arguments of known
types, possibly after type adaptation and partial evaluation of arguments.
These methods are typically used as bootstrap methods for
invokedynamic
call sites, to support the string concatenation
feature of the Java Programming Language.
Indirect access to the behavior specified by the provided
MethodHandle
proceeds in order through two phases:
- Linkage occurs when the methods in this class are invoked.
They take as arguments a method type describing the concatenated arguments
count and types, and optionally the String recipe, plus the
constants that participate in the String concatenation. The details on
accepted recipe shapes are described further below. Linkage may involve
dynamically loading a new class that implements the expected concatenation
behavior. The
CallSite
holds theMethodHandle
pointing to the exact concatenation method. The concatenation methods may be shared among differentCallSite
s, e.g. if linkage methods produce them as pure functions. - Invocation occurs when a generated concatenation method is
invoked with the exact dynamic arguments. This may occur many times for a
single concatenation method. The method referenced by the behavior
MethodHandle
is invoked with the static arguments and any additional dynamic arguments provided on invocation, as if byMethodHandle.invoke(Object...)
.
This class provides two forms of linkage methods: a simple version
(makeConcat(java.lang.invoke.MethodHandles.Lookup, String, MethodType)
) using only the dynamic arguments, and an advanced version
(makeConcatWithConstants(java.lang.invoke.MethodHandles.Lookup, String, MethodType, String, Object...)
using the advanced forms of capturing
the constant arguments. The advanced strategy can produce marginally better
invocation bytecode, at the expense of exploding the number of shapes of
string concatenation methods present at runtime, because those shapes would
include constant static arguments as well.
- API Note:
There is a JVM limit (classfile structural constraint): no method can call with more than 255 slots. This limits the number of static and dynamic arguments one can pass to bootstrap method. Since there are potential concatenation strategies that use
MethodHandle
combinators, we need to reserve a few empty slots on the parameter lists to capture the temporal results. This is why bootstrap methods in this factory do not accept more than 200 argument slots. Users requiring more than 200 argument slots in concatenation are expected to split the large concatenation in smaller expressions.- Since:
- 9
-
Field Summary
Modifier and TypeFieldDescriptionstatic final int
Preview.Maximum number of argument slots in String Concat call. -
Method Summary
Modifier and TypeMethodDescriptionstatic CallSite
makeConcat
(MethodHandles.Lookup lookup, String name, MethodType concatType) Facilitates the creation of optimized String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments.static CallSite
makeConcatWithConstants
(MethodHandles.Lookup lookup, String name, MethodType concatType, String recipe, Object... constants) Facilitates the creation of optimized String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments.static MethodHandle
makeConcatWithTemplate
(List<String> fragments, List<Class<?>> ptypes) Preview.Simplified concatenation method to facilitateStringTemplate
PREVIEW concatenation.static List
<MethodHandle> makeConcatWithTemplateCluster
(List<String> fragments, List<Class<?>> ptypes, int maxSlots) Preview.This method breaks up large concatenations into separateMethodHandles
based on the number of slots required perMethodHandle
.static MethodHandle
makeConcatWithTemplateGetters
(List<String> fragments, List<MethodHandle> getters, int maxSlots) Preview.This method creates aMethodHandle
expecting one input, the receiver of the supplied getters.
-
Field Details
-
MAX_INDY_CONCAT_ARG_SLOTS
public static final int MAX_INDY_CONCAT_ARG_SLOTSMAX_INDY_CONCAT_ARG_SLOTS
is a preview API of the Java platform.Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.Maximum number of argument slots in String Concat call. While the maximum number of argument slots that indy call can handle is 253, we do not use all those slots, to let the strategies with MethodHandle combinators to use some arguments.- Since:
- 21
-
-
Method Details
-
makeConcat
public static CallSite makeConcat(MethodHandles.Lookup lookup, String name, MethodType concatType) throws StringConcatException Facilitates the creation of optimized String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments. Typically used as a bootstrap method forinvokedynamic
call sites, to support the string concatenation feature of the Java Programming Language.When the target of the
CallSite
returned from this method is invoked, it returns the result of String concatenation, taking all function arguments passed to the linkage method as inputs for concatenation. The target signature is given byconcatType
. For a target accepting:- zero inputs, concatenation results in an empty string;
- one input, concatenation results in the single input converted as per JLS 5.1.11 "String Conversion"; otherwise
- two or more inputs, the inputs are concatenated as per requirements stated in JLS 15.18.1 "String Concatenation Operator +". The inputs are converted as per JLS 5.1.11 "String Conversion", and combined from left to right.
Assume the linkage arguments are as follows:
concatType
, describing theCallSite
signature
Then the following linkage invariants must hold:
- The number of parameter slots in
concatType
is less than or equal to 200 - The return type in
concatType
is assignable fromString
- Parameters:
lookup
- Represents a lookup context with the accessibility privileges of the caller. Specifically, the lookup context must have full privilege access. When used withinvokedynamic
, this is stacked automatically by the VM.name
- The name of the method to implement. This name is arbitrary, and has no meaning for this linkage method. When used withinvokedynamic
, this is provided by theNameAndType
of theInvokeDynamic
structure and is stacked automatically by the VM.concatType
- The expected signature of theCallSite
. The parameter types represent the types of concatenation arguments; the return type is always assignable fromString
. When used withinvokedynamic
, this is provided by theNameAndType
of theInvokeDynamic
structure and is stacked automatically by the VM.- Returns:
- a CallSite whose target can be used to perform String
concatenation, with dynamic concatenation arguments described by the given
concatType
. - Throws:
StringConcatException
- If any of the linkage invariants described here are violated, or the lookup context does not have private access privileges.NullPointerException
- If any of the incoming arguments is null. This will never happen when a bootstrap method is called with invokedynamic.- See Java Language Specification:
-
5.1.11 String Conversion
15.18.1 String Concatenation Operator +
-
makeConcatWithConstants
public static CallSite makeConcatWithConstants(MethodHandles.Lookup lookup, String name, MethodType concatType, String recipe, Object... constants) throws StringConcatException Facilitates the creation of optimized String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments. Typically used as a bootstrap method forinvokedynamic
call sites, to support the string concatenation feature of the Java Programming Language.When the target of the
CallSite
returned from this method is invoked, it returns the result of String concatenation, taking all function arguments and constants passed to the linkage method as inputs for concatenation. The target signature is given byconcatType
, and does not include constants. For a target accepting:- zero inputs, concatenation results in an empty string;
- one input, concatenation results in the single input converted as per JLS 5.1.11 "String Conversion"; otherwise
- two or more inputs, the inputs are concatenated as per requirements stated in JLS 15.18.1 "String Concatenation Operator +". The inputs are converted as per JLS 5.1.11 "String Conversion", and combined from left to right.
The concatenation recipe is a String description for the way to construct a concatenated String from the arguments and constants. The recipe is processed from left to right, and each character represents an input to concatenation. Recipe characters mean:
- \1 (Unicode point 0001): an ordinary argument. This input is passed through dynamic argument, and is provided during the concatenation method invocation. This input can be null.
- \2 (Unicode point 0002): a constant. This input passed
through static bootstrap argument. This constant can be any value
representable in constant pool. If necessary, the factory would call
toString
to perform a one-time String conversion. - Any other char value: a single character constant.
Assume the linkage arguments are as follows:
concatType
, describing theCallSite
signaturerecipe
, describing the String recipeconstants
, the vararg array of constants
Then the following linkage invariants must hold:
- The number of parameter slots in
concatType
is less than or equal to 200 - The parameter count in
concatType
is equal to number of \1 tags inrecipe
- The return type in
concatType
is assignable fromString
, and matches the return type of the returnedMethodHandle
- The number of elements in
constants
is equal to number of \2 tags inrecipe
- API Note:
- Code generators have three distinct ways to process a constant string operand S in a string concatenation expression. First, S can be materialized as a reference (using ldc) and passed as an ordinary argument (recipe '\1'). Or, S can be stored in the constant pool and passed as a constant (recipe '\2') . Finally, if S contains neither of the recipe tag characters ('\1', '\2') then S can be interpolated into the recipe itself, causing its characters to be inserted into the result.
- Parameters:
lookup
- Represents a lookup context with the accessibility privileges of the caller. Specifically, the lookup context must have full privilege access. When used withinvokedynamic
, this is stacked automatically by the VM.name
- The name of the method to implement. This name is arbitrary, and has no meaning for this linkage method. When used withinvokedynamic
, this is provided by theNameAndType
of theInvokeDynamic
structure and is stacked automatically by the VM.concatType
- The expected signature of theCallSite
. The parameter types represent the types of dynamic concatenation arguments; the return type is always assignable fromString
. When used withinvokedynamic
, this is provided by theNameAndType
of theInvokeDynamic
structure and is stacked automatically by the VM.recipe
- Concatenation recipe, described above.constants
- A vararg parameter representing the constants passed to the linkage method.- Returns:
- a CallSite whose target can be used to perform String
concatenation, with dynamic concatenation arguments described by the given
concatType
. - Throws:
StringConcatException
- If any of the linkage invariants described here are violated, or the lookup context does not have private access privileges.NullPointerException
- If any of the incoming arguments is null, or any constant inrecipe
is null. This will never happen when a bootstrap method is called with invokedynamic.- See Java Language Specification:
-
5.1.11 String Conversion
15.18.1 String Concatenation Operator +
-
makeConcatWithTemplate
public static MethodHandle makeConcatWithTemplate(List<String> fragments, List<Class<?>> ptypes) throws StringConcatException makeConcatWithTemplate
is a preview API of the Java platform.Programs can only usemakeConcatWithTemplate
when preview features are enabled.Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.Simplified concatenation method to facilitateStringTemplate
PREVIEW concatenation. This method returns a single concatenation method that interleaves fragments and values. fragment|value|fragment|value|...|value|fragment. The number of fragments must be one more that the number of ptypes. The total number of slots used by the ptypes must be less than or equal toMAX_INDY_CONCAT_ARG_SLOTS
PREVIEW.- Parameters:
fragments
- list of string fragmentsptypes
- list of expression types- Returns:
- the
MethodHandle
for concatenation - Throws:
StringConcatException
- If any of the linkage invariants are violated.NullPointerException
- If any of the incoming arguments is null.IllegalArgumentException
- If the number of value slots exceedMAX_INDY_CONCAT_ARG_SLOTS
PREVIEW.- Since:
- 21
-
makeConcatWithTemplateCluster
public static List<MethodHandle> makeConcatWithTemplateCluster(List<String> fragments, List<Class<?>> ptypes, int maxSlots) throws StringConcatException makeConcatWithTemplateCluster
is a preview API of the Java platform.Programs can only usemakeConcatWithTemplateCluster
when preview features are enabled.Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.This method breaks up large concatenations into separateMethodHandles
based on the number of slots required perMethodHandle
. EachMethodHandle
after the first will have an extraString
slot for the result from the previousMethodHandle
.makeConcatWithTemplate(java.util.List<java.lang.String>, java.util.List<java.lang.Class<?>>)
PREVIEW is used to construct theMethodHandles
. The total number of slots used by the ptypes is open ended. However, care must be given when combining theMethodHandles
so that the combine total does not exceed the 255 slot limit.- Parameters:
fragments
- list of string fragmentsptypes
- list of expression typesmaxSlots
- maximum number of slots perMethodHandle
.- Returns:
- List of
MethodHandles
- Throws:
IllegalArgumentException
- If maxSlots is not between 1 and MAX_INDY_CONCAT_ARG_SLOTS.StringConcatException
- If any of the linkage invariants are violated.NullPointerException
- If any of the incoming arguments is null.IllegalArgumentException
- If the number of value slots exceedMAX_INDY_CONCAT_ARG_SLOTS
PREVIEW.- Since:
- 21
-
makeConcatWithTemplateGetters
public static MethodHandle makeConcatWithTemplateGetters(List<String> fragments, List<MethodHandle> getters, int maxSlots) throws StringConcatException makeConcatWithTemplateGetters
is a preview API of the Java platform.Programs can only usemakeConcatWithTemplateGetters
when preview features are enabled.Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.This method creates aMethodHandle
expecting one input, the receiver of the supplied getters. This method usesmakeConcatWithTemplateCluster(java.util.List<java.lang.String>, java.util.List<java.lang.Class<?>>, int)
PREVIEW to create the intermediateMethodHandles
.- Parameters:
fragments
- list of string fragmentsgetters
- list of getterMethodHandles
maxSlots
- maximum number of slots perMethodHandle
in cluster.- Returns:
- the
MethodHandle
for concatenation - Throws:
IllegalArgumentException
- If maxSlots is not between 1 and MAX_INDY_CONCAT_ARG_SLOTS or if the getters don't use the same argument typeStringConcatException
- If any of the linkage invariants are violatedNullPointerException
- If any of the incoming arguments is nullIllegalArgumentException
- If the number of value slots exceedMAX_INDY_CONCAT_ARG_SLOTS
PREVIEW.- Since:
- 21
-
MAX_INDY_CONCAT_ARG_SLOTS
when preview features are enabled.