EG help please with getting to LW1 re: Value Types Consistency Checking

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Jul 13 10:55:50 UTC 2018


Let's try ...

First, what we want is to have an algorithm that find the calling layout of a method, unlike with references were there is only one possible calling layout, because value types can be flattened, there are several possible calling layouts when value types are involved.

We want:
- to defer the loading of a value type class until we need to actually call a method that contains that value type in its descriptor 
- a familly of methods (the tree of overridden methods) to have the same calling layout so VMs can use vtables if they want

The ideas:
- decouple the construction of the vtable from finding the calling layout of a method, so instead of having one pass that constructs the vtable, creates the slots etc and determines the calling layout, we now separate in two phases. Building the vtable only find the slots but not the calling layout of the methods, we need a supplementary phase to determine the calling layout of a method
- the calling layout of a method is determined by the information (the value types declared in the ValueTypes attribute) of the class that creates the vtable slot for that method

So vtables are created as usual, and when the interpreter does a method call, after having found the vtable slot, it will try to resolve the calling layout using the ValueTypes attribute of the class that have created that slot. So value type of that ValueTypes attribute that are part of the method descriptor will be loaded at that point. 

For default methods (which are injected in the vtable hierarchy), if we follow this algorithm, the calling layout of a default method should be deteermined using the information of the class that receives the default methods (the one that creates the vtable slot) and not from the ValueTypes attribute of the interface making the attribute ValueTypes in an interface useless. I don't know if it's a good idea or not ?

Rémi

----- Mail original -----
> De: "John Rose" <john.r.rose at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>, "Tobi Ajila" <Tobi_Ajila at ca.ibm.com>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> Envoyé: Jeudi 12 Juillet 2018 21:02:02
> Objet: Re: EG help please with getting to LW1 re: Value Types Consistency Checking

> Thanks, Tobi and Remi, for the helpful observations.
> 
> On Jul 10, 2018, at 2:43 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>> 
>> I think the answer to the question of lazy loading of method parameter types is
>> rooted to the question of what is a value type exactly for Java.
>> Is it an optimization, a first class concept i.e one that should work as if it
>> was integrated in the language from the beginning ?
>> The other problem is the more we diverge from the class behavior, the harder it
>> will be to allow a class to become a value type.
>> 
>> I firmly believe that value type should be first class because they are useless
>> in a lot of scenario if they are not. The main limitation of a value type is
>> its immutable characteristic, what save them from uselessness is that their
>> creation cost should be zero or very close to zero alleviating the burden of
>> think in term of object creation and making us, developers, free to use
>> functional idioms.
>> With that in mind, i believe a value type should not be "boxed" because it's not
>> loaded yet (it can still be boxed due to separate compilation but that's
>> another story) so value type present in method descriptor should be loaded
>> eagerly.
> 
> So value types should diverge from object types enough to allow accurate
> unboxing in hot paths.
> But they should not diverge more than necessary.  That means no eager loading
> that's not needed.
> 
>> About loading all value type of the attribute ValueTypes, from one side Java has
>> a strong tradition to not pay for the code you do not use. This power today's
>> applications, an average application has an hundred jars as dependencies, if
>> all value types are preloaded it's at waste of memory and cpu cycles. BTW, it's
>> also what's make jaotc useless in its current incarnation because it AOTs
>> things your application don't care.
> 
> This is a very specific set of reasons why eager loading is a bad idea:  Against
> Java tradition,
> harmful to startup, and liable to tickle bugs that otherwise would sleep
> quietly.
> 
> On Jul 12, 2018, at 11:41 AM, Tobi Ajila <Tobi_Ajila at ca.ibm.com> wrote:
> 
>> > I'm looking for reasons that
>> > this is a *bad* idea, so we can say in the end, "here's exactly why we had to
>> > make
>> > the loading logic for VTs so tricky"–if we must.
>> 
>> Karen's initial post mentions our two biggest concerns. If there is no guarantee
>> that the VTs in the method descriptors will be used, loading them is an
>> overhead. We would like to minimize the cost to startup as much as possible.
>> The other reason is eager loading may trigger failures that would otherwise
>> never occur if the method wasn't run, which is change from how the JVM normally
>> behaves.
> 
> OK, those points align with the discussion above.
> 
> IMO there's still a possibility that we will want to eagerly load signature
> types
> declared as value types, at preparation time.  This could happen if two bad
> things happen first:  (a) We can't figure out how to assign calling sequences
> properly to virtual methods (including those connected by v-table/override
> relations) without preparation time loadings, and (b) we regretfully realize
> that we would rather get the calling sequences right than follow the Java
> traditions noted above.
> 
> (For the moment, let's define the term "method family" to mean any group
> of methods which is connected by override/v-table relations in such a way
> that the methods are all constrained to have a common calling sequence.
> I can't think offhand of a standard term for this, but we need a term.)
> 
> To solve (a) we need a story, for any given method family F, how the
> common calling sequence (including unboxed values) is assigned during
> startup, even if dynamically loaded class hierarchies are being loaded
> in a data-dependent fashion, concurrently with executions of members
> of F.
> 
> I don't think appealing to speculation and deoptimization is a good answer
> for (a), because it slows startup unpredictably.  If that's the answer, I'd
> rather just take the predictable startup hit of loading signature value types.
> That is, given an inaccurate solution for (a), I think we'd decide in the end,
> regarding point (b), to regretfully break tradition.
> 
> So, is there a reasonably simple way to get good enough calling sequences
> non-speculatively?
> 
> The answer might be yes, along the lines you mentioned Tobi, but I don't
> see it yet.  I think maybe the whole family F needs a linkage barrier,
> which involves delayed loading of signature value types used in F.
> Although preparation of F's various classes would have assigned
> v-table slots (or whatever preconstructed dictionary V8 might use
> instead of v-tables), the calling sequences of those v-table slots would
> remain mysterious until the first execution of a method in F.
> 
> Can we do that?  It sort of feels like a mini-preparation pass just for F.
> 
> — John


More information about the valhalla-spec-observers mailing list