@FunctionalInterface
public interface GeneratedDispatcher
A per-class table of compiler-generated dispatch targets, reached by a compact integer id instead of a 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 into one constant 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.
| Modifiers | Name | Description |
|---|---|---|
interface |
GeneratedDispatcher.Arity1 |
Array-free companion for targets taking exactly one value beyond the receiver. |
interface |
GeneratedDispatcher.Arity2 |
Array-free companion for targets taking exactly two values beyond the receiver. |
class |
GeneratedDispatcher.Bundle |
The hosting class's three dispatch shapes, linked once by bootstrap and shared by all of that class's adapters. |
| Type Params | Return Type | Name and description |
|---|---|---|
|
public static CallSite |
bootstrap(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, via LambdaMetafactory with the caller's full-privilege lookup) and returns
them as one constant Bundle. |
|
public Object |
dispatch(int id, Object[] args)Invokes the dispatch target registered under id in the hosting class. |
|
public static Class<?>[] |
paramTypes(Lookup caller, String name, Class<?> type, String descriptor)Constant-dynamic bootstrap for a closure literal's declared parameter types: decodes a method descriptor (which, unlike Class constants, can carry primitive types) with
the hosting class's loader into a Class[] 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. |
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, via LambdaMetafactory with the caller's full-privilege lookup) and returns
them as one constant Bundle. Linked once per class, on first adapter creation.
Emitted bytecode reaches this through
org.codehaus.groovy.vmplugin.v8.IndyInterface#packedDispatchers — the central
bytecode-facing bootstrap surface — which delegates here.
caller - the hosting class's lookup (supplied by the JVM)name - the invoked name (unused)type - the accessor's type: () -> Object as emitted (typed loosely so the
Bundle type stays off the emitted-bytecode surface); the constant is
typed off the requested return type, so () -> Bundle also links Invokes the dispatch target registered under id in the hosting class.
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 ordernull for a void target) Constant-dynamic bootstrap for a closure literal's declared parameter types: decodes a
method descriptor (which, unlike Class constants, can carry primitive types) with
the hosting class's loader into a Class[] 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 through
org.codehaus.groovy.vmplugin.v8.IndyInterface#packedParamTypes, which delegates here.
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)