APIdia Launch Partner
Top Description Inners Fields Constructors Methods
java.lang.runtime

public final Class SwitchBootstraps

extends Object
Class Inheritance
Imports
java.lang.Enum.EnumDesc, java.lang.classfile.CodeBuilder, .ClassFile, .Label, java.lang.classfile.attribute.StackMapFrameInfo, .StackMapTableAttribute, java.lang.constant.ClassDesc, .ConstantDesc, .MethodTypeDesc, java.lang.invoke.CallSite, .ConstantCallSite, .MethodHandle, .MethodHandles, .MethodType, java.lang.reflect.AccessFlag, java.util.ArrayList, .List, .Objects, .Optional, .Arrays, .HashMap, .Map, java.util.function.BiPredicate, .Consumer, jdk.internal.access.SharedSecrets, java.lang.classfile.instruction.SwitchCase, jdk.internal.classfile.impl.DirectCodeBuilder, jdk.internal.constant.ClassOrInterfaceDescImpl, .ConstantUtils, .MethodTypeDescImpl, jdk.internal.misc.PreviewFeatures, jdk.internal.vm.annotation.Stable, sun.invoke.util.Wrapper

Bootstrap methods for linking invokedynamic call sites that implement the selection functionality of the switch statement. The bootstraps take additional static arguments corresponding to the case labels of the switch, implicitly numbered sequentially from [0..N).
Since
21

Nested and Inner Type Summary

Modifier and TypeClass and Description
private static class
private static class
private static class
pack-priv static record

Field Summary

Modifier and TypeField and Description
private static final ClassDesc
private static final ClassDesc
private static final MethodTypeDesc
private static final MethodHandles.Lookup
private static final MethodType
private static final MethodType
private static final MethodTypeDesc
private static final MethodTypeDesc
private static final boolean
private static final Object
private static final List<StackMapFrameInfo.VerificationTypeInfo>
private static final List<StackMapFrameInfo.VerificationTypeInfo>

Constructor Summary

AccessConstructor and Description
private

Method Summary

Modifier and TypeMethod and Description
private static <E extends Enum<E>> Object
convertEnumConstants(Class<?> enumClassTemplate, Object label)

public static CallSite

Returns:

a CallSite returning the first matching element as described above
enumSwitch
(MethodHandles.Lookup
the full-privilege lookup context of the caller
lookup
,
String
unused, null is permitted
invocationName
,
MethodType
The invocation type of the CallSite with two parameters, an enum type, an int, and int as a return type.
invocationType
,
Object...
case labels - String constants and Class instances, in any combination
labels
)

Bootstrap method for linking an invokedynamic call site that implements a switch on a target of an enum type.

private static MethodHandle
generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants)

private static Consumer<CodeBuilder>
generateTypeSwitchSkeleton(Class<?> selectorType, Object[] labelConstants, List<Enum.EnumDesc<?>> enumDescs, List<Class<?>> extraClassLabels)

private static boolean
isNotValidPair(Class<?> selectorType, Object caseLabel)

private static <T extends Enum<T>> int
mappedEnumSwitch(T value, int restartIndex, MethodHandles.Lookup lookup, Class<T> enumClass, Enum.EnumDesc<?>[] labels, SwitchBootstraps.MappedEnumCache enumCache)

private static boolean
needsExtraInfo(Class<?> selectorType, Object[] labelConstants)

Check if the labelConstants can be converted statically to bytecode, or whether we'll need to compute and pass in extra information at the call site.

public static CallSite

Returns:

a CallSite returning the first matching element as described above
typeSwitch
(MethodHandles.Lookup
the full-privilege lookup context of the caller
lookup
,
String
unused, null is permitted
invocationName
,
MethodType
The invocation type of the CallSite with two parameters, a target type, an int, and int as a return type.
invocationType
,
Object...
case labels as described above
labels
)

Bootstrap method for linking an invokedynamic call site that implements a switch over a target value.

private static String
typeSwitchClassName(Class<?> targetClass)

private static boolean
unconditionalExactnessCheck(Class<?> selectorType, Class<?> targetType)

private static void
verifyLabel(Object label, Class<?> selectorType)

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

CD_BiPredicateback to summary
private static final ClassDesc CD_BiPredicate
CD_Objectsback to summary
private static final ClassDesc CD_Objects
CHECK_INDEX_DESCRIPTORback to summary
private static final MethodTypeDesc CHECK_INDEX_DESCRIPTOR
LOOKUPback to summary
private static final MethodHandles.Lookup LOOKUP
MT_TYPE_SWITCHback to summary
private static final MethodType MT_TYPE_SWITCH
MT_TYPE_SWITCH_EXTRAback to summary
private static final MethodType MT_TYPE_SWITCH_EXTRA
MTD_TYPE_SWITCHback to summary
private static final MethodTypeDesc MTD_TYPE_SWITCH
MTD_TYPE_SWITCH_EXTRAback to summary
private static final MethodTypeDesc MTD_TYPE_SWITCH_EXTRA
previewEnabledback to summary
private static final boolean previewEnabled
SENTINELback to summary
private static final Object SENTINEL
TYPE_SWITCH_EXTRA_LOCALSback to summary
private static final List<StackMapFrameInfo.VerificationTypeInfo> TYPE_SWITCH_EXTRA_LOCALS
TYPE_SWITCH_LOCALSback to summary
private static final List<StackMapFrameInfo.VerificationTypeInfo> TYPE_SWITCH_LOCALS

Constructor Detail

SwitchBootstrapsback to summary
private SwitchBootstraps()

Method Detail

convertEnumConstantsback to summary
private static <E extends Enum<E>> Object convertEnumConstants(Class<?> enumClassTemplate, Object label)
enumSwitchback to summary
public static CallSite enumSwitch(MethodHandles.Lookup lookup, String invocationName, MethodType invocationType, Object... labels)

Bootstrap method for linking an invokedynamic call site that implements a switch on a target of an enum type. The static arguments are used to encode the case labels associated to the switch construct, where each label can be encoded in two ways:

  • as a String value, which represents the name of the enum constant associated with the label
  • as a Class value, which represents the enum type associated with a type test pattern

The returned CallSite's method handle will have a return type of int and accepts two parameters: the first argument will be an Enum instance (target) and the second will be int (restart).

If the target is null, then the method of the call site returns -1.

If the target is not null, then the method of the call site returns the index of the first element in the labels array starting from the restart index matching one of the following conditions:

  • the element is of type Class that is assignable from the target's class; or
  • the element is of type String and equals to the target enum constant's Enum#name().

If for a given target there is no element in the labels fulfilling one of the above conditions, then the method of the call site returns the length of the labels array.

The value of the restart index must be between 0 (inclusive) and the length of the labels array (inclusive), or an IndexOutOfBoundsException is thrown.

API Note

It is permissible for the labels array to contain String values that do not represent any enum constants at runtime.

Parameters
lookup:MethodHandles.Lookup

the full-privilege lookup context of the caller

invocationName:String

unused, null is permitted

invocationType:MethodType

The invocation type of the CallSite with two parameters, an enum type, an int, and int as a return type.

labels:Object[]

case labels - String constants and Class instances, in any combination

Returns:CallSite

a CallSite returning the first matching element as described above

Exceptions
IllegalArgumentException:
  • if any element in the labels array is null
  • if any element in the labels array is an empty String
  • if the invocation type is not a method type whose first parameter type is an enum type, second parameter of type int and whose return type is int
  • if labels contains an element that is not of type String or Class equal to the target enum type
Java Virtual Machine Specification
4.4.6 The CONSTANT_NameAndType_info Structure, 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures
generateTypeSwitchback to summary
private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants)
generateTypeSwitchSkeletonback to summary
private static Consumer<CodeBuilder> generateTypeSwitchSkeleton(Class<?> selectorType, Object[] labelConstants, List<Enum.EnumDesc<?>> enumDescs, List<Class<?>> extraClassLabels)
isNotValidPairback to summary
private static boolean isNotValidPair(Class<?> selectorType, Object caseLabel)
mappedEnumSwitchback to summary
private static <T extends Enum<T>> int mappedEnumSwitch(T value, int restartIndex, MethodHandles.Lookup lookup, Class<T> enumClass, Enum.EnumDesc<?>[] labels, SwitchBootstraps.MappedEnumCache enumCache) throws Throwable
needsExtraInfoback to summary
private static boolean needsExtraInfo(Class<?> selectorType, Object[] labelConstants)

Check if the labelConstants can be converted statically to bytecode, or whether we'll need to compute and pass in extra information at the call site.

typeSwitchback to summary
public static CallSite typeSwitch(MethodHandles.Lookup lookup, String invocationName, MethodType invocationType, Object... labels)

Bootstrap method for linking an invokedynamic call site that implements a switch over a target value. The static arguments labels are an array of case labels which must be non-null and of type String, Integer, Class, or EnumDesc. In addition, when preview features are enabled, Long, Float, Double, and Boolean labels are also permitted.

The type of the returned CallSite's method handle will have a return type of int. It has two parameters: the first argument will be a value of the (target) type and the second will be int (restart).

If the target is null, then the method of the call site returns -1.

If the target is not null, then the method of the call site returns the index of the first element in the labels array starting from the restart index matching one of the following conditions:

  • the element is of type Class that is assignable from the target's class
  • the element is of type String and equals to the target
  • the element is of type Integer and == to the target after unboxing if necessary
  • (Preview) the element is of type Long or Boolean and == to the target after unboxing if necessary
  • (Preview) the element is of type Float or Double and equals to the target after boxing if necessary
  • the element is of type EnumDesc, that describes an enum constant that is == to the target

If no element in the labels array matches the target, then the method of the call site return the length of the labels array.

The value of the restart index must be between 0 (inclusive) and the length of the labels array (inclusive), both or an IndexOutOfBoundsException is thrown.

Parameters
lookup:MethodHandles.Lookup

the full-privilege lookup context of the caller

invocationName:String

unused, null is permitted

invocationType:MethodType

The invocation type of the CallSite with two parameters, a target type, an int, and int as a return type.

labels:Object[]

case labels as described above

Returns:CallSite

a CallSite returning the first matching element as described above

Exceptions
IllegalArgumentException:
  • if any element in the labels array is null
  • if the invocation type is not a method type of first parameter of a target type, second parameter of type int and with int as its return type
  • if labels contains an element that is not of type String, Integer, Long, Float, Double, Boolean, Class or EnumDesc
  • if preview features are disabled and if labels contains an element that is of type Long, Float, Double, or Boolean
Java Virtual Machine Specification
4.4.6 The CONSTANT_NameAndType_info Structure, 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures
typeSwitchClassNameback to summary
private static String typeSwitchClassName(Class<?> targetClass)
unconditionalExactnessCheckback to summary
private static boolean unconditionalExactnessCheck(Class<?> selectorType, Class<?> targetType)
verifyLabelback to summary
private static void verifyLabel(Object label, Class<?> selectorType)
java.lang.runtime back to summary

private final Class SwitchBootstraps.MappedEnumCache

extends Object
Class Inheritance

Field Summary

Modifier and TypeField and Description
public int[]
public MethodHandle

Constructor Summary

AccessConstructor and Description
private

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

constantsMapback to summary
public int[] constantsMap
Annotations
@Stable
generatedSwitchback to summary
public MethodHandle generatedSwitch
Annotations
@Stable

Constructor Detail

MappedEnumCacheback to summary
private MappedEnumCache()
java.lang.runtime back to summary

private final Class SwitchBootstraps.ResolvedEnumLabels

extends Object
implements BiPredicate<Integer, Object>
Class Inheritance
All Implemented Interfaces
java.util.function.BiPredicate

Field Summary

Modifier and TypeField and Description
private final Enum.EnumDesc<?>[]
private final MethodHandles.Lookup
private final Object[]

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
public boolean
test(Integer labelIndex, Object value)

Implements java.util.function.BiPredicate.test.

Evaluates this predicate on the given arguments.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

enumDescsback to summary
private final Enum.EnumDesc<?>[] enumDescs
lookupback to summary
private final MethodHandles.Lookup lookup
resolvedEnumback to summary
private final Object[] resolvedEnum
Annotations
@Stable

Constructor Detail

ResolvedEnumLabelsback to summary
public ResolvedEnumLabels(MethodHandles.Lookup lookup, Enum.EnumDesc<?>[] enumDescs)

Method Detail

testback to summary
public boolean test(Integer labelIndex, Object value)

Implements java.util.function.BiPredicate.test.

Doc from java.util.function.BiPredicate.test.

Evaluates this predicate on the given arguments.

Annotations
@Override
java.lang.runtime back to summary

private Class SwitchBootstraps.StaticHolders

extends Object
Class Inheritance

Field Summary

Modifier and TypeField and Description
private static final MethodHandle

Constructor Summary

AccessConstructor and Description
private

Method Summary

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

MAPPED_ENUM_SWITCHback to summary
private static final MethodHandle MAPPED_ENUM_SWITCH

Constructor Detail

StaticHoldersback to summary
private StaticHolders()
java.lang.runtime back to summary

pack-priv final Record SwitchBootstraps.TypePairs

extends Record
Class Inheritance
Record Components
from:Class<?> 
to:Class<?> 

Field Summary

Modifier and TypeField and Description
private final Class<?>
from

Record Component accessed by from().

private final Class<?>
to

Record Component accessed by to().

private static final Map<SwitchBootstraps.TypePairs, String>

Constructor Summary

AccessConstructor and Description
pack-priv
TypePairs(Class<?> from, Class<?> to)

Method Summary

Modifier and TypeMethod and Description
public boolean
equals(Object other)

Implements abstract java.lang.Record.equals.

Indicates whether some other object is "equal to" this one.

public Class<?>
from()

Record Component getter of from.

public int
hashCode()

Implements abstract java.lang.Record.hashCode.

Returns a hash code value for the record.

public static Map<SwitchBootstraps.TypePairs, String>
public static SwitchBootstraps.TypePairs
of(Class<?> from, Class<?> to)

public Class<?>
to()

Record Component getter of to.

public final String
toString()

Implements abstract java.lang.Record.toString.

Returns a string representation of the record.

Field Detail

fromback to summary
private final Class<?> from

Record Component accessed by from().

toback to summary
private final Class<?> to

Record Component accessed by to().

typePairToNameback to summary
private static final Map<SwitchBootstraps.TypePairs, String> typePairToName

Constructor Detail

TypePairsback to summary
pack-priv TypePairs(Class<?> from, Class<?> to)

Method Detail

equalsback to summary
public boolean equals(Object other)

Implements abstract java.lang.Record.equals.

Doc from java.lang.Record.equals.

Indicates whether some other object is "equal to" this one. In addition to the general contract of Object.equals, record classes must further obey the invariant that when a record instance is "copied" by passing the result of the record component accessor methods to the canonical constructor, as follows:

    R copy = new R(r.c1(), r.c2(), ..., r.cn());
then it must be the case that r.equals(copy).
fromback to summary
public Class<?> from()

Record Component getter of from.

hashCodeback to summary
public int hashCode()

Implements abstract java.lang.Record.hashCode.

Doc from java.lang.Record.hashCode.

Returns a hash code value for the record. Obeys the general contract of Object.hashCode. For records, hashing behavior is constrained by the refined contract of Record.equals, so that any two records created from the same components must have the same hash code.

initializeback to summary
public static Map<SwitchBootstraps.TypePairs, String> initialize()
ofback to summary
public static SwitchBootstraps.TypePairs of(Class<?> from, Class<?> to)
toback to summary
public Class<?> to()

Record Component getter of to.

toStringback to summary
public final String toString()

Implements abstract java.lang.Record.toString.

Doc from java.lang.Record.toString.

Returns a string representation of the record. In accordance with the general contract of Object#toString(), the toString method returns a string that "textually represents" this record. The result should be a concise but informative representation that is easy for a person to read.

In addition to this general contract, record classes must further participate in the invariant that any two records which are equal must produce equal strings. This invariant is necessarily relaxed in the rare case where corresponding equal component values might fail to produce equal strings for themselves.