again on megamorphic problems
Jochen Theodorou
blackdrag at gmx.org
Fri Dec 21 00:17:32 PST 2012
Am 21.12.2012 06:03, schrieb Charles Oliver Nutter:
> On Thu, Dec 20, 2012 at 7:10 AM, Jochen Theodorou <blackdrag at gmx.org> wrote:
>> let us assume the following example... I have a method foo
>>
>> public Object foo(Object arg){return bar(arg)}
>>
>> nothing fancy, quite simple... and let us assume foo is called from
>> dozens of places with differing argument types.
>>
>> If I understood right, then the call site in foo will become
>> megamorphic, making it impossible to inline bar into the place from
>> where foo is called. foo becomes like a inlining barrier so to say.
>
> This is no different than for Java code, of course.
Yes, and especially in the light of lambda I am a bit hoping for the
bright minds to have a plan of action ;)
[...]
> It's not a problem in indy, it's just a limitation of how Hotspot
> inlines.
I am aware of this. But I have a missing bit of information here. If you
have an indy call site that involves different runtime types, but the
call site is not invalidated, can then Hotspot still inline? I assume it
could, so I guess the question should be more: will Hotspot still inline
then? If I get Remis test about Hotspot profiles right, then I have the
tendency to answer that it will still not be inlined... but that is an
interpretation of sparse information and likely to be wrong.
> This also impacts any methods that accept a closure as an
> argument;
and as such it should affect lambda a lot too, or not?
> if there's more than a couple different closures, the
> callback is megamorphic.
internal iterators have this problem imho very fast
> The only solution for you (and for Hotspot)
> is to specialize the foo method on a per-type (argument type, that is)
> basis, so that the type profile carries all the way through to a
> unique call target at bar.
>
> We are experimenting with that in JRuby, since we usually have the
> full AST available for every method (so we can emit multiple
> specialized versions of it). If you can't, then your best bet is just
> failing the bar call size (in JRuby, we do it if we see more than
> three types) and forever bind a simple non-indy cache to it (we bind a
> simple single-element, MRU inline cache).
imho generating methods at runtime is... well, I wrote already to Mark,
that I am worried about memory here. But maybe I worry too much. Nothing
in the generated code needs to refer other classes than those in the
original method. Actually all I have to do is to copy the method into a
new class. Well, it is not exactly so easy, but that is what I think is
to be done.
The question though is, if it is that easy, why doesn't hotspot do this?
To citate Remi: """
The main issue with the duplication of methods at bytecode level to have
several profiles is that the freshly generated bytecode have the wrong
performance counter and can be considered by the JIT has never been
called or at least not called enough to be JITed.
This is a known issue of the current implementation of JDart.
A compromise can be to have a way to read/write the profile and the perf
counter of any methods, Graal already provides these features.
It will be also very useful when you want to test a Java code to be able
to inject a profile artificially.
"""
In my own words... such a duplicated method would, for a long time, not
be considered for optimization by the JIT, because the original profile
information is lost. I mean if at least the old path is still fast, then
this is maybe less a problem.
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
More information about the mlvm-dev
mailing list