Am 12.03.2015 00:13, schrieb Mark Roos:
I have to think about yours some more but I thought I would share mine.
I condensed it to
make it easier to explain.
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
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
MethodHandle gwt=MethodHandles./guardWithTest/(test, newTarget,
site._depth= site._depth+ 1; // bump the depth
inserts it at the start of the chain by making it the new target
and invokes it ( has to spread the args here as they were compressed
on the way to the fallback)
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
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org
mlvm-dev mailing list