invokedynamic and subclasses

Jochen Theodorou blackdrag at gmx.org
Wed Jun 24 14:16:23 UTC 2015


Hi Mike,

First of all, the bootstrap method does not have to be in the same 
class. In Groovy we have for example one bootstrap method for all 
classes only. It is part of the runtime then you could say.


We do it like this. We have two bootstrap methods in the Groovy runtime 
(you don't need to have them in the class). The first one is normally 
called and will produce a handle to call the second one. I tend to call 
the first one the static bootstrapper and the second one the dynamic 
bootstrapper. The dynamic bootstrapper will be called like a method 
(takes an Object[]), thus I will have all the arguments of the call as 
well as the receiver. This I can use to identify runtime classes and 
produce a new handle that fits my needs and replaces the first one. This 
method also is a fallback. The installed handle usually has to be 
guarded (like first call with B, second with C), and we use the dynamic 
bootstrapper as fallback. Of course you can easily check more cases and 
implement a polymorphic inline cache.

Of course that implies, that if the dynamic bootstrapper is called it 
will also have to do the first execution of the target (like getting the 
value of the field foo). We use (part of) the produced method handle for 
this. And of course the callsite will have to be mutable then

Does this help you out? It works quite good for Groovy.

bye blackdrag

Am 24.06.2015 14:19, schrieb Mike Jarmy:
> I've been experimenting with invokedynamic in a compiler for a dynamic
> language
> that I'm working on, and I've run into a problem that I'm having difficulty
> solving.
>
> Let's say I have a class called A (Java syntax used for clarity):
>
>      public class A {
>      }
>
> And another called B, that is a subclass of A:
>
>      public class B extends A {
>          public Value foo;
>          public Value bar;
>      }
>
> There will be lots of other subclasses of A as well (let's call them C,
> D, E,
> etc), some of which will have a field called foo, and some of which
> won't. The
> class A will never have any fields -- its sole purpose is to be the base
> class
> of everything else.
>
> I have been able to successfully use a static bootstrap method in B, so
> that I
> can compile a call to invokedynamic on the imaginary method get_foo() of an
> instance of B, and then reroute the call inside B's bootstrap method via
> MethodHandles.Lookup.findGetter(), and finally return the current value
> of foo.
> So far, so good.
>
> However, at the place where I am compiling the invokedynamic instruction, I
> have no idea if the target is a B, C, D, or what.  All I know is that it
> must
> be an A.
>
> So what I really want to be able to do (I think) is to use a static
> bootstrap
> method in A. I want get_foo() to succeed for every invokedynamic call to an
> instance of A who's *subclass* really does have a field called foo.
>
> Unfortunately there doesn't seem to be a way to make A do what I want. I
> understand why that is -- foo doesn't exist in A, so there is no way to
> create
> a findGetter() call.  But I'm hoping there might be some clever way to do it
> anyway.  I've tried all kinds of different approaches (making yet another
> invokedynamic call from inside A, etc, etc) but I can't come up with
> anything
> that works.
>
> Any ideas?
>
> By the way, I've figured out how to do this the "old" way, by generating
> interfaces for each class that has e.g. a foo field, and casting to that
> interface every time I compile a get_foo() invocation.  This works, and its
> reasonably performant, but using invokedynamic seems like it would be a more
> elegant and flexible solution.
>
>
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>


-- 
Jochen "blackdrag" Theodorou
blog: http://blackdragsview.blogspot.com/



More information about the mlvm-dev mailing list