Lworld and calling convention
Frederic Parain
frederic.parain at oracle.com
Wed Apr 18 19:38:03 UTC 2018
Roland,
Thank you for this summary.
Would it help to have javac to annotate which arguments are expected
to be value classes? In this case:
- only classes of annotated arguments would be pre-loaded (no additional
pre-loading for old code)
- after pre-loading, if the class is a value class, the calling convention could
use scalarisation, otherwise argument is passed by reference
- arguments without the annotation would always be passed by reference
With this proposal, the calling convention would depend only on the
information provided by javac, not on the value of the arguments being
passed (passing null would not impact the determination of the calling
convention).
However, I’m not sure it would solve the issue with method inlining if the
method candidate for in-lining are not known before the compilation starts.
Fred
> On Apr 5, 2018, at 11:53, Roland Westrelin <rwestrel at redhat.com> wrote:
>
>
> I started to work on bringing the calling convention from MVT to the
> Lworld.
>
> The first problem I hit is that when adapters are generated, classes of
> the method's signature may not have been loaded yet so it's impossible
> to tell which argument is a value and which is not.
>
> I then looked at what it would take to make adapter generation lazy. I
> have a prototype that seems to allow for lazy generation but then the
> question is what are the events that should trigger adapter generation?
>
> Going from interpreter to compiled code (where the i2c is needed) is
> fairly simple. We don't need the i2c until compiled code exists. We
> already load the classes of the signature before we trigger the
> compilation of the method so generating the adapters at that point would
> be fine.
>
> Going from compiled code to the interpreter seems much trickier. Let's
> say we compile m(). The compiler will trim some untaken paths and inline
> some methods so it's only possible to tell what call sites will be in
> the compiled m() as it's being compiled or once it's compiled. There's
> no guarantee that the classes of the signatures of these call sites are
> loaded when the call sites are compiled because, in legacy code, null
> may be passed for a value argument.
>
> We can't load classes as we compile the method because the compiler
> threads don't perform class loading.
>
> If compiled method m() has a call site:
>
> m2(v1, v2)
>
> and v1 and v2 are values (from 2 different classes), that call site may
> be compiled as:
>
> m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..)
>
> (passing fields) if when the call site was compiled, classes for v1 & v2
> are loaded.
>
> or:
>
> m2(v1, v2.f1, v2.f2, ..)
>
> (passing a reference to v1) if the class for v1 was not loaded when the
> call site was compiled
>
> or:
>
> m2(v1.f1, v1.f2, .., v2)
>
> if the class for v2 was not loaded when the call site was compiled
>
> or:
>
> m2(v1, v2)
>
> if both classes were not loaded when the call site was compiled.
>
> So for a single call site with 2 value arguments, there are 4 ways of
> compiling the call site.
>
> We could generate the adapters the first time the call in compiled
> method m() is executed (at call resolution time) but then we need to
> generate an adapter that matches how the call site was compiled. How do
> we know which of the 4 ways of performing the call it is?
>
> As code executes and classes get loaded, we might need several adapters
> generated. Maybe some m2() call site was compiled as:
>
> m2(v1, v2)
>
> but then one class got loaded so another one got compiled as:
>
> m2(v1, v2.f1, v2.f2, ..)
>
> and then another one as:
>
> m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..)
>
> and we need 3 different c2i adapters.
>
> Add to this, that we can't deoptimize at call resolution time because
> compiled code only has debug info to resume execution after the call.
>
> I see 2 ways forward with this. Either we eagerly load classes of
> signatures so we can generate the adapters eagerly as is done
> currently. Or we refuse to compile a call site for which the classes of
> the signature are not loaded (replace the call with an uncommon trap and
> trigger class loading?). In that case, we would sometime drop perfectly
> good code.
>
> Comments?
>
> Roland.
>
More information about the valhalla-dev
mailing list