ConstantDynamic JVMS comments
Remi Forax
forax at univ-mlv.fr
Fri Sep 1 22:39:42 UTC 2017
Hi John,
Thinking a little bit about that,
1/ conceptually a BootstrapCallInfo and a ConstantGroup are every similar, it's a bunch of constants, the BootstrapCallInfo as just a special meaning for some of them.
2/ at runtime, it's like an array or a java.util.List (again conceptually) of stable values which is lazily populated
Bold claims:
1/ we do not need both BootstrapCallInfo and ConstantGroup, only one is enough,
yes it means that an indy of a condy BSM will have at least 4 parameters (lookup, name, type, constantgroup),
constantgroup play the role of kind of array (a new kind of Array 2.0 ?)
2/ ConstantGroup should only have two methods, size() and get(index) (and perhaps asList() for interropt), the fact that asking for a value will trigger an initialization or not should not be part of the spec.
There is a good reason for that, an image format like CDS may store the ConstantGroup directly resolved so like the class loading in Java, the user should have no way to know if a constant is resolved or not.
(John, if you wan batch/bulk copy, why not add a method copy() into the List interface (as a default method))
I'm also a little worry to introduce that type like this now knowing that get() should return 'any' and not 'Object'.
3/ I think we can 'retarget' the BootstrapMethods attribute to represent both the values of a ConstantGroup and the values of a ConstantDynamic/InvokeDynamic by saying that the constant values of a ConstantGroup constant in the constant pool is just an index to a BootstrapMethods attribute with a bootstrap_method_ref set to 0. So a ConstantGroup constant is a kind of condy with no bootstrap method.
Rémi
[....]
> Summary of the BootstrapCallInfo feature (copied from JDK-8186210):
> If the bootstrap method accepts two parameters, and it is *not* a
> variable-arity method handle, then the linkage information is
> presented to the bootstrap method by a API which allows it to *pull*
> the static arguments. This allows the bootstrap logic the ability to
> order the resolution of constants and catch linkage exceptions. For
> this mode of linkage, the bootstrap method is is invoked on just two
> values:
> * a `MethodHandles.Lookup`, a lookup object on the *caller class*
> (as in the "push" mode)
> * a `BootstrapCallInfo` object describing the linkage parameters of
> the dynamic call site or constant
> ## Java APIs
> `public interface BootstrapCallInfo<T> extends ConstantGroup`
> An interface providing full static information about a particular call
> to a bootstrap method of an dynamic call site or dynamic
> constant. This information include the method itself, the associated
> name and type, and any associated static arguments. If a bootstrap
> method declares exactly two arguments, and is not of variable arity,
> then it is fed only two arguments by the JVM, the lookup object and an
> instance of `BootstrapCallInfo` which supplies the rest of the
> information about the call.
> The API for accessing the static arguments allows the bootstrap method
> to reorder the resolution (in the constant pool) of the static
> arguments, and to catch errors resulting from the resolution. This
> mode of evaluation pulls bootstrap parameters from the JVM under
> control of the bootstrap method, as opposed to the JVM pushing
> parameters to a bootstrap method by resolving them all before the
> bootstrap method is called.
> API Note:
> The lookup object is not included in this bundle of information, so as
> not to obscure the access control logic of the program. In cases where
> there are many thousands of parameters, it may be preferable to pull
> their resolved values, either singly or in batches, rather than wait
> until all of them have been resolved before a constant or call site
> can be used.
> Method Summary
> * `MethodHandle bootstrapMethod()`
> Returns the bootstrap method for this call.
> * `String invocationName()`
> Returns the method name or constant name for this call.
> * `T invocationType()`
> Returns the method type or constant type for this call.
> * `static <T> BootstrapCallInfo<T> makeBootstrapCallInfo(MethodHandle bsm,
> String name, T type, ConstantGroup constants)`
> Make a new bootstrap call descriptor with the given components.
> `public interface ConstantGroup`
> An ordered sequence of constants, some of which may not yet be
> present. This type is used by `BootstrapCallInfo` to represent the
> sequence of bootstrap arguments associated with a bootstrap method,
> without forcing their immediate resolution. If you use the simple
> `get` method, the constant will be resolved, if this has not already
> happened. An occasional side effect of resolution is a `LinkageError`,
> which happens if the system could not resolve the constant in
> question.
> In order to peek at a constant without necessarily resolving it, use
> the non-throwing `get` method. This method will never throw a
> resolution error. Instead, if the resolution would result in an error,
> or if the implementation elects not to attempt resolution at this
> point, then the method will return the user-supplied sentinel value.
> To iterate through the constants, resolving as you go, use the
> iterator provided on the `List`-typed view. If you supply a sentinel,
> resolution will be suppressed.
> Typically the constant is drawn from a constant pool entry in the
> virtual machine. Constant pool entries undergo a one-time state
> transition from unresolved to resolved, with a permanently recorded
> result. Usually that result is the desired constant value, but it may
> also be an error. In any case, the results displayed by a
> `ConstantGroup` are stable in the same way. If a query to a particular
> constant in a `ConstantGroup` throws an exception once, it will throw
> the same kind of exception forever after. If the query returns a
> constant value once, it will return the same value forever after.
> The only possible change in the status of a constant is from the
> unresolved to the resolved state, and that happens exactly once. A
> constant will never revert to an unlinked state. However, from the
> point of view of this interface, constants may appear to spontaneously
> resolve. This is so because constant pools are global structures
> shared across threads, and because prefetching of some constants may
> occur, there are no strong guarantees when the virtual machine may
> resolve constants.
> When choosing sentinel values, be aware that a constant pool which has
> `CONSTANT_ConstantDynamic` entries can contain potentially any
> representable value, and arbitrary implementations of `ConstantGroup`
> are also free to produce arbitrary values. This means some obvious
> choices for sentinel values, such as `null`, may sometimes fail to
> distinguish a resolved from an unresolved constant in the group. The
> most reliable sentinel is a privately created object, or perhaps the
> `ConstantGroup` itself.
> Method Summary
> * `default List<Object> asList()`
> Create a view on this group as a `List` view.
> * `default List<Object> asList(Object ifNotPresent)`
> Create a view on this group as a `List` view.
> * `default int copyConstants(int start, int end, Object[] buf, int pos)`
> Copy a sequence of constant values into a given buffer.
> * `default int copyConstants(int start, int end, Object[] buf, int pos, Object
> ifNotPresent)`
> Copy a sequence of constant values into a given buffer.
> * `Object get(int index)`
> Returns the selected constant, resolving it if necessary.
> * `Object get(int index, Object ifNotPresent)`
> Returns the selected constant, or the given sentinel value if there is none
> available.
> * `boolean isPresent(int index)`
> Returns an indication of whether a constant may be available.
> * `static ConstantGroup makeConstantGroup(List<Object> constants, Object
> ifNotPresent, IntFunction<Object> constantProvider)`
> Make a new constant group with the given elements.
> * `int size()`
> Returns the number of constants in this group.
> * `default ConstantGroup subGroup(int start, int end)`
> Create a view on a sub-sequence of this group.
> Source files:
> [
> http://hg.openjdk.java.net/amber/amber/jdk/file/2744935cd215/src/java.base/share/classes/java/lang/invoke/package-info.java#l124
> |
> http://hg.openjdk.java.net/amber/amber/jdk/file/2744935cd215/src/java.base/share/classes/java/lang/invoke/package-info.java#l124
> ]
> [
> http://hg.openjdk.java.net/amber/amber/jdk/file/2744935cd215/src/java.base/share/classes/java/lang/invoke/BootstrapCallInfo.java#l63
> |
> http://hg.openjdk.java.net/amber/amber/jdk/file/2744935cd215/src/java.base/share/classes/java/lang/invoke/BootstrapCallInfo.java#l63
> ]
> [
> http://hg.openjdk.java.net/amber/amber/jdk/file/2744935cd215/src/java.base/share/classes/java/lang/invoke/ConstantGroup.java#l96
> |
> http://hg.openjdk.java.net/amber/amber/jdk/file/2744935cd215/src/java.base/share/classes/java/lang/invoke/ConstantGroup.java#l96
> ]
More information about the valhalla-spec-observers
mailing list