ConstantDynamic JVMS comments

Remi Forax forax at univ-mlv.fr
Wed Sep 27 16:14:23 UTC 2017


ping ! 

Rémi 

> De: "Remi Forax" <forax at univ-mlv.fr>
> À: "John Rose" <john.r.rose at oracle.com>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Samedi 2 Septembre 2017 00:39:42
> Objet: Re: ConstantDynamic JVMS comments

> 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