a new way to play with invokedynamic

John Rose john.r.rose at oracle.com
Tue Nov 16 12:22:44 PST 2010


Thanks.  Yes, there's a need for something better than <clinit> to create interesting constants.

Here are some "cookbook" notes about constants and JSR 292...

JSR 292 is designed to allow "live constants", by allowing the bootstrap method of an invokedynamic instruction to take a relatively open-ended set of parameters (all CP entries), and apply arbitrary program logic to them.  The BSM can then return a MethodHandles.constant MH which returns the desired constant value, every time the invokedynamic instruction is invoked.

This approach also scales nicely to semi-constants (like `(foo ,x) or "foo=$x" as opposed to '(foo bar) or "foo=bar"), since the invokedynamic instruction can take non-constant arguments (like x) and insert them into a template.  The BSM for such an instruction can choose optimal code for constructing the templated object.

Of course, the JIT can easily see through expressions like MethodHandles.constant(Foo.class, x).

Also, I don't know why people don't use this more, but you can put large-ish constant data into resource files associated with the class files of your code.  The class file (<clinit> before JSR 292, invokedynamic after) can load part or all of the resource file, and process it into the desired constant.  If the missing bit of usability is good laziness (create constant on first actual use) then invokedynamic adds that missing bit, since the BSM is guaranteed to be called on first execution of the instruction.

I suppose that some language runtimes will eventually include constant-creation functions which will be used as bootstrap methods, parameterized by extra constant pool constants and/or resource files.  The constants will be created lazily and bound to individual invokedynamic sites.

-- John

On Nov 16, 2010, at 11:11 AM, BGB wrote:

> On 11/16/2010 4:53 AM, John Rose wrote:
>> Folks, here's a small tool for JSR 292 that may have its uses:
>> 
>>   http://blogs.sun.com/jrose/entry/a_modest_tool_for_writing
>> 
> 
> yep, interesting.
> 
> 
> sorry, this is unrelated, but in my own (hobby/experimental) VM effort (here using an extended JBC), I came up with a design idea that might be relevant (I have little idea what to do with it otherwise, so mentioning it here):
> having a "VarLump" constant-pool entry which basically has and a similar format and function as an attribute (there is also "MiniVarLump" which does the same thing but uses a smaller header).
> 
> so:
> VarLump
> {
> u1 tag;
> u1 pad;    //reserved, 0
> u2 name_index;    //CONSTANT_UTF8
> u4 size;
> u1 data[size];
> }
> 
> MiniVarLump
> {
> u1 tag;
> u1 name_index;    //CONSTANT_UTF8
> u2 size;
> u1 data[size];
> }
> 
> basically, it would be to allow user/compiler/VM-specific extensions to the constant pool (semantics are that the VM will ignore unknown entries unless referenced in an unsupported way, in which case the VM can reject the module).
> 
> internally, I have used constant tags 70(VarLump) and 71(MiniVarLump), but this is not particularly important (I started my numbering at 64 to hopefully avoid clashes).
> 
> one of my uses for it thus far is to put binary-XML globs in the constant pool (with XML namespaces and tags to identify purpose), ... (binary XML also used with attributes, encoding vaguely similar to WBXML).
> 
> sorry, I don't know if similar exists in more canonical JVM's, as at the moment I don't know where to find more up to date specs on the bytecode or similar (implementation is based mostly off "The Java Virtual Machine Specification, Second Edition", among others...).
> 
> 
> yeah, some other extensions exist, but for now they are mostly irrelevant...
> 



More information about the mlvm-dev mailing list