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.r...@oracle.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>, "Tobi Ajila" <tobi_aj...@ca.ibm.com>
> Cc: "valhalla-spec-experts" <valhalla-spec-experts@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 <fo...@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_aj...@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

Reply via email to