Summary: Introduce one more constant pool type, CONSTANT_MethodApply.
The JSR 292 EG has recognized demands for application-specific "live constants" and for application-specific optional parameters to invokedynamic bootstrap methods. This can be handled by a common mechanism for computed constants and parameterized bootstrap methods. In particular, we will add a "hook" for memoizing library-defined constants in the constant pool.
The actual semantics of the hook (which combines a "function" constant with zero or more "argument" constants) will be defined by a JDK runtime routine which invokes the function on the argument if it is a unary function, and otherwise calls MethodHandles.bindTo, effectually treating the function as if it were curried. The code will be something like:
apply(fun,arg) := fun.type.parameterCount == 1 ? fun.invokeGeneric(arg) : fun.bindTo(arg);
Combined with the pre-existing CONSTANT_MethodHandle constant pool entries, this provides a way to get a wide variety of computed constants.
The EG has discussed the trade-offs between a single argument and a sequence of arguments. It appears that a sequence of arguments is best answer, although some proposals allow only a single argument.
(Although it may seem odd to allow only one argument (and use the bindTo function to collect multiple arguments) this design matches better with the pre-existing binary constant pool structure already commonly built into JVMs, including both the HotSpot and IBM JVMs. But the extra complexity of allowing a counted series of arguments, athough it complicates constant pool parsing, appears to be justified on the grounds that it is more economical with constant pool slots, which are a scarce resource.)
The JVM change includes logic to ensure that if the initial computation of a constant causes an exception, this exception will be uniformly thrown from all points where it is referenced. This logic applies to pre-existing constants also.
Motivation: Parameterized bootstrap methods seem to be required for factoring closures and similar data structures into distinct static and dynamic specifications. The computed constants allow explicit one-time computation of static information, to be used by an ldc or a bootstrap method or both. Such "live constants" were a request from dynamic language implementors at the Summit.
A key use case for one-time computation appears to be representation selection for closures. This is best done in a runtime (decoupled from the bytecode compiler), but should not be done on every closure creation. The invokedynamic instruction can use bootstrap methods with additional parameters supplied by this mechanism to combine prepared closure bodies with closure parameters. The same pattern can also be used by other language implementations which also need to combine static with dynamic data.
This bug was broken out separately from the following bug:
6981777 implement JSR 292 EG adjustments from summer 2010
[Description from dup bug 6983708.]
JSR 292 defines a minimum set of static information which is provided to a bootstrap method when an invokedynamic instruction is first executed. This information is the calling class, the method name, and the method type descriptor.
Some uses of JSR 292 technology will require additional static parameters to pass at link time. It is not practical to pass these parameters dynamically (mixed with non-static parameters).
The most natural way to fix this is to introduce a constant pool entry type which applies a method handle to an argument (or, with nesting, to multiple arguments).
Runnable r = #bar();
//this could translate to:
ldc MethodHandle #bar
//or could use static arguments:
ldc (Apply (MethodHandle #MethodHandles.asInstance)
(MethodHandle #bar) (Class Runnable))
In the case of a mix of static and dynamic arguments, the above "ldc" would be replaced by an invokedynamic and/or followed by an invokevirtual, to apply the dynamic arguments to the constant constructed statically.
The current workaround to this limitation builds local private BSMs which contain short code sequences to push the extra constants, and then call an augmented BSM. This workaround causes an explosion of constant pool entries to support the extra BSMs. It will be much cheaper (especially in scarce CP entries) to encode the extra constants in CP entries linked to the CONSTANT_InvokeDynamic entry.