constant-dynamic specification, updated

John Rose john.r.rose at
Thu Jul 6 23:34:48 UTC 2017

On Jul 5, 2017, at 11:57 AM, Brian Goetz <brian.goetz at> wrote:
> This is very nice.  
> One thing that readers will wonder (doesn't belong in JVMS, but belongs somewhere) is what suggested practice are for using invocation name / constant name.  I don't see the name widely used in indy, but I could imagine it more widely used in condy, because constants often have names (like Pi.)  For a BSM that effectively has a single String parameter, I think we'll get more compact classfiles if we use the name and a shared no-arg BootstrapMethods entry, but is that a good reason?

Combined with one other reason it is good enough.  The other reason is that invokedynamic
BSMs already take a method name.  It is helpful to keep indy and condy BSMs similar, where
possible.  The similarity allows similar parts to be factored together, in both spec. and
implementation.  The similarity, in brief, condy:indy :: Fieldref:Methodref.  In all cases,
you have a NameAndType (field or method) accompanied by either a Class or a BSM.

> For example, for a primitive-class bootstrap, would this be a good use of the name?  

Here FTR are some use cases for constants with very simple names:

 - enums (all enums can use *one* BSM in common)
 - other ad hoc manifest constants (Math.PI; BSM must be told which class)
 - primitives (really, ad hoc access to "W.TYPE" constants, but "I" is more compact)
 - simple extended numerics ("2/3", "1i2")
 - dates, times ("12:30am")
 - any other naming system (encodings? locales? timezones? geos?)
 - format specifiers (like the 'recipe' of StringConcatFactory)

The overall effect is to keep the length of the BootstrapMethods attribute small
even if there are large numbers of simple constants floating around.

(Also, Note that integer constants divide into small–aconst_2, bipush, sipush–and
large–ldc CONSTANT_Integer.  Similarly, small numerics might be well served by
using name strings when they are short, and component-wise BSMs otherwise.)

If indy had not already set the pattern, these (taken all together) are IMO barely
enough to motivate allowing this extra-compact way of defining constants, but
only after a close accounting of the exact number of CP and BSM indexes
consumed by each proposed translation strategy.

(I should say that indy set this pattern because of a similar analysis for method names.
So the StringConcatFactory could use this trick to implement all concatenations with one BSM.
The DynaLink API can make good use of the method names, allowing one BSM to serve
all invocation instructions.)

> I don't understand this sentence: "A bootstrap specifier gives a method or field descriptor, TD."

The vague phrase "a foo specifier gives a bar" appears a lot.

It could be super-explicit:

"A bootstrap specifier gives a CONSTANT_Utf8 string which encodes a method descriptor or field descriptor; call it TD."


"A bootstrap specifier gives a method descriptor or a field descriptor; call it TD."

> On the API:
>  - The type parameter T to BCI is "dangling", in that there is nothing to constrain it.  However, IIUC, it can only be MethodType or Class.  In an ideal world, T would be bounded by the common supertype of these two things (NominalConstantRepresentingMemberDescriptor).  We generally advise against use of unconstrained tvars like this in APIs, since it provides only the illusion of type safety, though I understand why you went this way -- you can have a BSM
>     Foo bsm(Lookup lookup, BootstrapCallInfo<Class> bci) { ... }
> and just proceed without casting, and it's both convenient and self-documenting.  

Yep.  And I uses BootstrapCallInfo<Object> for generic uses, knowing
that Object is the bound type.  I don't think the types will cooperate with
anything cleaner.  (Should I try BootstrapCallInfo<?> maybe?  That might
work.  Nice wildcard… nice wildcard… ouch, down boy!)

> If we had a common supertype in the future, we'd not be able to add this as a bound in a binary-compatible manner, because invocationType()Object would be burned into client classfiles.  So it's kind of a dead-end.  In any case, I'd add a stronger note about the range of T here.  THere's room to put javadoc on tvars with "@param <T>"; you could say "Must be Class or MethodType."  

Will do.

>  - In ConstantGroup, do you want to clarify that constants described by multiple CGs might be the same constant, and therefore might share the one-time transition to resolved?  Readers could think that the one-transition lifecycle is a property of "entry #3 in CG at 234098", not the constant that CG at 234098 happens to refer to in slot 3.  

Will do.  I was being cagey.

> I'd like to see some guidance about what a constant is.  Condy will happily serve up mutable objects in the guise of dynamic constants, and the VM will have no regrets.  However, this is likely to lead to pain (or security issues) for the user.  Some sort of guidance here would be good, perhaps in the package javadoc.  

OK, will add.  This is not something the system can check or enforce, of course.

> Also, related: what sort of facilities might we want to provide for caching/interning of equivalent constants across classes?  I could easily imagine a BSM wanting to preserve the invariant that any LDC with a given set of args from any class results in the same object.  

I was going to leave that up to the user.  But I'll add a note, since String sets
the standard by making the interning behavior clear, as a reliable across
compilation units.

— John

> On 6/24/2017 7:52 PM, John Rose wrote:
>> I have updated the javadoc API that is relevant to the proposed
>> JVM features for dynamic constants and more powerful bootstrap
>> methods.
>> Here is a rough draft of the corresponding JVMS changes:
>> Please enjoy and comment.
>> — John

More information about the valhalla-spec-observers mailing list