[asm] Re: bootstrap methods in the constant pool
John Rose
john.r.rose at oracle.com
Wed Aug 11 23:20:03 PDT 2010
I just posted a prototype patch for local BSMs which works on my unit tests.
http://hg.openjdk.java.net/mlvm/mlvm/hotspot/file/tip/asm
There is also an updated "ldc" patch.
I've put the patches with some good examples here:
http://cr.openjdk.java.net/~jrose/pres/asm-jsr292-examples.zip
On Jul 13, 2010, at 5:39 AM, Eugene Kuleshov wrote:
> Perhaps we could split it into two visit calls... or introduce a micro language, e.g. in desc field.
I handled the extra degrees of freedom for indy instructions by replacing the "class" string (of a normal invokeinterface) with a microlanguage (distinct from valid class names). The microlanguage shows up in places like this:
INVOKEDYNAMIC invokeStatic.meth/IndyLocalBootstrap$FancySite.make.(Ljava/lang/Class;Ljava/lang/String;Ljava/dyn/MethodType;)Ljava/dyn/CallSite;.foo3 ()Ljava/lang/Object;
Everything before the "foo3" is a reference to the BSM. Awkward but workable.
When we do new instructions, the MethodVisitor needs new methods. This would be a good application for "defender methods". A weak substitute would be a V2 interface which extends the V1 interface, and a default implementation of the new methods (as a static method) in an associated V2 implementation module.
> BTW, what would be the meaning of bootstrap method pointing to a method handle of get/putField or get/putStatic type?
The JVM would reject it at run time (not verify time) because the thing can't have the signature of a real BSM. Only invokestatic and newInvokespecial make interesting BSMs. But, both do, so there's a reasonable exercise of the CONSTANT_MethodHandle data type.
> An alternative way to represent bootstrap method in the bytecode could be to introduce a new attribute at the class, method and code level. This would be also closer to semantic John is suggesting. Though that way you couldn't enforce constrains on a pretense of the bootstrap methods, but that can be done in the verifier.
I think such a design is inadequate for code weaving applications. A code weaver is not likely to want the same BSM as the pre-existing invokedynamic instructions, but it may want to weave new instructions between the old ones. I think this may be a good way to make AOT work: You pre-inject your cut points as indy instructions, which link immediately to (cheap) no-ops. When you want to dynamically vary a cut-point, you relink the affected indy instructions. This clearly uses a different BSM than any pre-existing BSM used by the original compiler.
-- John
> regards,
> Eugene
>
> Rémi Forax wrote:
>> Le 13/07/2010 04:59, John Rose a écrit :
>>> Folks, the 292 EG has decided to register bootstrap methods in the constant pool, instead of via a call from the <clinit> method.
>>>
>>> Here's a summary of constant pool formats as of the latest push to mlvm.
>>>
>>> This will require further changes to asm, Mirah, and other bytecode-aware tools.
>>
>> The biggest problem of this change is that at first look it requires an incompatible
>> change of current ASM instruction visitor.
>>
>>>
>>> For now, the JVM accepts both old and new formats of invokedynamic. But old format support will go away when 292 is finalized.
>>>
>>> Best wishes,
>>> -- John
>>
>> cheers,
>> Rémi
>>
>>>
>>> Begin forwarded message:
>>>
>>> *From: *John Rose <john.r.rose at oracle.com <mailto:john.r.rose at oracle.com>>
>>> *Date: *July 12, 2010 4:20:03 PM PDT
>>> *To: *jsr-292-eg at jcp.org <mailto:jsr-292-eg at jcp.org>
>>> *Subject: **ISSUE: explicit bootstrap methods (resolution)*
>>>
>>> ...
>>>
>>> Here are the constant pool entries defined by JSR 292:
>>>
>>> CONSTANT_MethodHandle = 15
>>> u1 RefType ref_type
>>> u2 NameAndType ref_index
>>>
>>> enum RefType {
>>> REF_getField = 1,
>>> REF_getStatic = 2,
>>> REF_putField = 3,
>>> REF_putStatic = 4,
>>> REF_invokeVirtual = 5,
>>> REF_invokeStatic = 6,
>>> REF_invokeSpecial = 7,
>>> REF_newInvokeSpecial = 8,
>>> REF_invokeInterface = 9
>>> }
>>>
>>> CONSTANT_MethodType = 16
>>> u2 Utf8 signature_index
>>>
>>> CONSTANT_InvokeDynamic = 17
>>> u2 MethodHandle bootstrap_method_index
>>> u2 NameAndType name_and_type_index
>>>
>>> The format of the invokedynamic instruction is {u1 op = 186; u2 invokedynamic_index; u2 zero}.
>>>
>>> The EDR RI has a backward-compatibility mode which (a) allows the Java app. to call the deprecated methods Linkage.registerBootstrapMethod and (b) allows (but does not require) the invokedynamic instruction to specify merely a NameAndType instead of a full InvokeDynamic CP entry. The PFD will not include this mode.
>>>
>>> The CONSTANT_InvokeDynamic CP entry does not allow a null bootstrap_method index.
>>>
>>> The call to the BSM specified for a given invokedynamic instruction will be made as if by invokeGeneric, not invokeExact. This allows direct access to constructors via REF_newInvokeSpecial, as well more flexible linkage to factory method calls via REF_invokeStatic. (Other ref-types are not relevant, unless somebody puts an interesting virtual method on java.lang.Class.)
>>>
>>> There seems to be no benefit to defining a default BSM notation in the class file (e.g., attribute DefaultBootstrapMethod {u2 MethodHandle default_bootstrap_method_index). Let the constant pool deal with it. Pack200's column-wise compression will chew up the slack.
>>>
>>> Language notes: I expect the Java language support to allow an annotation-like mechanism to specify the BSM, as a symbolic method reference, for a whole class, and/or a whole method, and/or a single InvokeDynamic expression. (I have prototyped this in terms of @BootstrapMethod annotations, but I don't think this will fly with the language mavens.) Such a notation (if adopted) will enable refactoring at the source level at two "cut points": First, by editing the annotation-like syntax for the per-class or per-method defaults, and second by using a private class-local BSM whose body can be edited at will.
>>>
>>> ...
>>>
>>>
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev at openjdk.java.net
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>>
>>
>
More information about the mlvm-dev
mailing list