Interface GeneratedDispatcher
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
MethodHandle.
The compiler emits per class: an array-shaped table ($packedDispatch$(int, Object[]),
covering every target) plus array-free per-arity tables ($packedDispatch1$,
$packedDispatch2$) for the hot shapes taking one or two values beyond the receiver —
avoiding the packed argument array, which cannot be scalar-replaced when the dispatch call
does not inline. Each table is a switch over the id whose case casts the arguments to the
target's declared parameter types and invokes it directly, so the whole chain is ordinary,
JIT-friendly bytecode. A single invokedynamic accessor per class links all three
through bootstrap(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType) into one constant GeneratedDispatcher.Bundle, created lazily on first use.
Adapters such as PackedClosure hold (dispatchers, id) and make a plain
interface call per invocation. Unlike a MethodHandle held in an instance field —
which the JIT cannot treat as a constant, so every call runs the (comparatively slow)
method-handle invoker — this executes as a cheap indirect call, and inlines fully when the
call site is monomorphic. The id space is not limited to packed closure bodies: any
statically-known target the compiler wants to reach through a shared adapter (for example a
statically-resolved method reference) can claim an id in the same tables.
- Since:
- 6.0.0
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic interfaceArray-free companion for targets taking exactly one value beyond the receiver.static interfaceArray-free companion for targets taking exactly two values beyond the receiver.static final classThe hosting class's three dispatch shapes, linked once bybootstrap(java.lang.invoke.MethodHandles.Lookup, java.lang.String, java.lang.invoke.MethodType)and shared by all of that class's adapters. -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionstatic CallSitebootstrap(MethodHandles.Lookup caller, String name, MethodType type) Invokedynamic bootstrap for the hosting class's dispatcher accessor: adapts the class's three private static dispatch tables to their functional interfaces (one hidden class each, viaLambdaMetafactorywith the caller's full-privilege lookup) and returns them as one constantGeneratedDispatcher.Bundle.Invokes the dispatch target registered underidin the hosting class.static Class<?>[]paramTypes(MethodHandles.Lookup caller, String name, Class<?> type, String descriptor) Constant-dynamic bootstrap for a closure literal's declared parameter types: decodes a method descriptor (which, unlikeClassconstants, can carry primitive types) with the hosting class's loader into aClass[]resolved once per literal site and shared by every adapter created there — closure creation then loads one constant instead of allocating and filling an array.
-
Field Details
-
TABLE_METHOD
Name of the generated array-shaped dispatch table method.- See Also:
-
TABLE1_METHOD
Name of the generated one-value dispatch table method.- See Also:
-
TABLE2_METHOD
Name of the generated two-value dispatch table method.- See Also:
-
-
Method Details
-
dispatch
Invokes the dispatch target registered underidin the hosting class.- Parameters:
id- the compile-time-assigned index of the target in the hosting class's tableargs- the packed argument array:args[0]is the receiver (the adapter's owner — ignored by static targets), followed by any captured values, then the call arguments, all in the target's declared parameter order- Returns:
- the target's return value (
nullfor a void target)
-
paramTypes
static Class<?>[] paramTypes(MethodHandles.Lookup caller, String name, Class<?> type, String descriptor) Constant-dynamic bootstrap for a closure literal's declared parameter types: decodes a method descriptor (which, unlikeClassconstants, can carry primitive types) with the hosting class's loader into aClass[]resolved once per literal site and shared by every adapter created there — closure creation then loads one constant instead of allocating and filling an array. Sharing matches generated closure classes, whose parameter-type arrays are likewise cached per class. Emitted bytecode reaches this throughorg.codehaus.groovy.vmplugin.v8.IndyInterface#packedParamTypes, which delegates here.- Parameters:
caller- the hosting class's lookup (supplied by the JVM)name- the constant's name (unused)type- the constant's type:Class[]descriptor- a method descriptor whose parameter types are the closure's declared parameter types (the return type is ignored)- Returns:
- the declared parameter types
-
bootstrap
static CallSite bootstrap(MethodHandles.Lookup caller, String name, MethodType type) throws Throwable Invokedynamic bootstrap for the hosting class's dispatcher accessor: adapts the class's three private static dispatch tables to their functional interfaces (one hidden class each, viaLambdaMetafactorywith the caller's full-privilege lookup) and returns them as one constantGeneratedDispatcher.Bundle. Linked once per class, on first adapter creation. Emitted bytecode reaches this throughorg.codehaus.groovy.vmplugin.v8.IndyInterface#packedDispatchers— the central bytecode-facing bootstrap surface — which delegates here.- Parameters:
caller- the hosting class's lookup (supplied by the JVM)name- the invoked name (unused)type- the accessor's type:() -> Objectas emitted (typed loosely so theBundletype stays off the emitted-bytecode surface); the constant is typed off the requested return type, so() -> Bundlealso links- Returns:
- a constant call site producing the bundle
- Throws:
Throwable- if the tables cannot be found or linked (a compiler bug)
-