Limitations of the Calling Convention Optimization
Remi Forax
forax at univ-mlv.fr
Wed Oct 21 21:49:19 UTC 2020
----- Mail original -----
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>, "John Rose" <john.r.rose at oracle.com>, "Tobias Hartmann"
> <tobias.hartmann at oracle.com>
> Cc: "valhalla-dev" <valhalla-dev at openjdk.java.net>
> Envoyé: Mercredi 21 Octobre 2020 20:25:19
> Objet: Re: Limitations of the Calling Convention Optimization
>>
>> Unfortunately, the problematic idioms referred to in this thread shows
>> up quite a bit throughout the API; these are only some of the methods
>> which return new instances of these classes:
>>
>> For instance, in MemoryAddress we find the following methods:
>>
>> MemoryAddress addOffset(long offset); // returns _new_ address with
>> given offset from existing one
>> static MemoryAddress ofLong(long value); // create _new_ address with
>> given long value
>
> Let's try and invert the question. Rather than beating up the JIT guys
> with "Y U no scalarize", let's ask: what information would the JIT need
> (and _when_) in order to routinely scalarize methods like this?
>
> It seems that one part of it is knowing that these will never return a
> null reference. Here's one way we might express this constraint in
> source code, using idioms the language already has:
>
> sealed interface MA permits Impl { MA offset(long offset); }
>
> primitive class Impl implements MA {
> @Override // covariant override
> Impl addOffset(long offset) { ... }
> }
>
> From a language perspective, this makes sense to developers (and, this
> is hidden in the implementation); we're returning a more constrained
> type, which the language already allows. Ignoring the translation story
> here (MA::offset and Impl::offset might have different descriptors,
> bridge methods, yada yada), would having information like this strewn
> throughout the implementation be sufficient to hint the JIT that no
> nulls will be forthcoming?
It doesn't work in the general case because it still requires inlining to work. If there is no inlining, the caller doesn't inline the bridge method.
Until we have something like the bridge-o-matic proposal, I propose this hack, it's not pretty but it should work.
sealed interface Ma permits Impl { @ForceInline default MA add(MA ma) { return Impl.add(this, (Impl)ma); } }
primitive class Impl implements MA {
/* package private */ static Impl add(Impl impl1, Impl impl2) { ... }
}
cheers,
Rémi
More information about the valhalla-dev
mailing list