Am 12.03.2015 00:13, schrieb Mark Roos:
Hi Jochen

I have to think about yours some more but I thought I would share mine.
  I condensed it to
make it easier to explain.

my pleasure

[…]
I extended callsite to hold a bunch of values one of which is the depth.
And my model for the cache is up to 10 chained GWTs after that I drop the
chain and start over.

When I get a miss in the cache off to the fallback ( look below to see
how this MH is made)
*static*RtObject fallbackSelf(RtCallSite site, Object... args)

For each guard I create a test MH which takes all of the args and
returns a bool.
Since I only look at the TOS it drops the rest,  yours is more
complicated.  This can be
different for each guard in my case.
         RtObject rcvr=(RtObject)args[args.length- 1];  // top of stack
test=MethodHandles./insertArguments/(test, 0, rcvr.classField());  //
the behavior field
  test=MethodHandles./dropArguments/(test, 0, site.dropArray());
  // match test signature

   then finds the code based on the site and the receiver in this case
         MethodHandle newTarget=rcvr.lookupSelf(site.getSelector());

   makes a new GWT with the existing chain as its slow path

my main problem is that in most cases a single test won't do. In many cases I have to check at least the class of the receiver as well as of each argument. That makes for a 2 arg call a least 3 tests. But I cannot really express a Java like &&. Instead I have to use test number 1, with slow path in the false case and the real invocation target in the true case. Then for each additional test I use the root of the MethodHandle tree as the true case and the slow path as fallback.

Or is there a better way to do this? Maybe that would be a nice addition to the MethodHandles API actually. Something to be able to express logic and/or. I imagine this could simplify code generation in the JVM and reduce the number of Objets you need.

   if the cache is full will make the bootstrap MH (see below) the
target dropping the existing cache
***if*(site._depth< 10)
         MethodHandle gwt=MethodHandles./guardWithTest/(test, newTarget,
site.getRealTarget());
site._depth= site._depth+ 1;  // bump the depth

   inserts it at the start of the chain by making it the new target
site.setRealTarget(gwt);

   and invokes it ( has to spread the args here as they were compressed
on the way to the fallback)
         MethodHandle     invoke=newTarget.asSpreader(Object[].*class*,
site.getAirity());
result=(RtObject)invoke.invokeExact((Object[])args);

yeah, in Remi's example it falls back ot a vtable like approach. But such things would in my proposal go into the megamorphicFallback and there you can of course easily make a handle that will reset the cache

Of course the API I suggested is more complicated, because it tries to abstract. Remi's code for example works and is fairly small. But since the goal was to have a certain API the JVM can look at in more detail, since it will follow a certain structure I tried to come up with something we all can use. It is far from perfect of course and surely needs simplification here and there or does not consider other things. I only thought I give that idea to the list to have some base to work with, because I am not sure how I would be able to use your suggest API for Groovy for example

bye Jochen


--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org

_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to