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

2018-06-29 Thread John Rose
On Jun 26, 2018, at 7:30 AM, Karen Kinnear  wrote:
> 
> Summary: Could we please allow eager loading for value types in the locally 
> declared method signatures
> prior to preparation  for LW1? 

My answer would be "yes, if said types are mentioned in the
ValueTypes attribute".  Otherwise, it seems impractical to do
eager loading of type names that appear in descriptors, on
the off chance that they might be value types.

> Without that we seriously risk being able to offer an LW1 early access binary 
> for the JVMLS.
> We believe it is more important to get this into people’s hands for 
> experimentation and feedback than
> to delay the eager loading at this time.
> 
> Details:
> At our EG discussion on June 20, 2018, we discussed the proposal for Value 
> Types Consistency checking
> at 
> http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf
>  
> 
> 

The value-types-consistency-checking-details document should
probably lead off by describing the ValueTypes attribute, before
giving the four bullet points about instance fields, static fields,
descriptor types, and cross-call consistency.  Otherwise, I get
totally lost in the third bullet, when it claims "these types are
eagerly loaded" but without saying exactly what triggers this
loading.  Looking at the Valhalla prototype (which not all
spec experts can do) I see that the 'is_declared_value_type'
function is queried when method adapters are created,
so we can agree that ValueTypes is the source of truth for
method arguments and return values.

(Given ValueTypes, we don't need ACC_FLATTENABLE, as has
been discussed.  AFAIK, we are using ACC_FLATTENABLE in LW1
because we don't want to destabilize the system with a cleanup,
and because we might want it later, but I'm arguing that we
don't want it at all in the long run.  Reason:  Any such marking
of fields is *also* a desirable marking of method descriptor
components.  Thus, an ACC_FLATTENABLE, applicable only
to fields, is not sufficient for our needs, while ValueTypes is
both necessary and sufficient.  For nullability in particular,
what we really need is a marker for both field and method
descriptors, along the lines of Fred's N-types.  By JVMLS,
I expect I will have a concrete proposal in this space that is a
side effect of supporting reified type parameters.)

(But as long as ACC_FLATTENABLE is in the mix, perhaps the
consistency checking rules should *also* insist that the field types
of fields so marked must also be mentioned in the ValueTypes
attribute?)


> Part of the proposal for checking value type consistency relative to the 
> actual type
> was for locally declared methods. The proposal was to check the value types 
> in arguments/return type
> before preparation of the declaring class.
> 
> During the meeting, there was a request to explore whether we could either:
> 1)  delay checking the value type consistency until an attempt to resolve the 
> method for invocation, or 
> 2) write the JVMS is such as way as to allow eager loading, but only throw an 
> error related to the eager loading at method resolution.
> 
> My understanding is that the goals of this are two-fold:
> 1) if the method is never called, the rest of the code will continue to run
> 2) reduce eager loading
> 
> We have started this investigation, and there is non-trivial complexity in 
> implementing either of these approaches,
> and we would like more time to explore how to make this possible, after 
> making LW1 available.

Yep, I am not surprised that this is hard to do.  So for the LW1 term
I say "yes" to both eager loading and method consistency checking.

If we can find a way to be explicit about nullability in value type descriptors,
then I think we can keep the rest of the L-world descriptor design.
The conversation (post LW1) which I see queuing up is whether to
go back to Q-types (or some analog) as explicitly non-nullable value
type descriptors, or whether to use some other "channel" to convey
the nullness information when it differs from some defined background
setting.  I think that conversation hinges, in part, on how useful it is
to change the meaning of LFoo; to be contextually determined as a
value type, vs. just being plain with QFoo;.  Our experiments with
a live LW1 prototype will help us scope this out.

> Some aspects of the implementation complexity that we have identified so far:
> a) At method resolution time, if there is a mismatch in value type 
> consistency between the declaring class and the actual
> type in the signature, then there is also a mismatch in all classes that have 
> overridden the current method. This is particularly
> painful with default methods in interfaces.

For LW1 we can insist that all the methods agree.  This is a brittle state
of affairs which we will (almost certainly) need to make more flexible
with on-the-fly adapter generation.  One key question post LW1 is
what 

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

2018-07-06 Thread Tobi Ajila
I would like to propose an alternative strategy, one that would effectively
provide the same consistency checks outlined in
http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf
 without requiring eager loading of value types (VT) in the return/args of
methods during the preparation phase. This is born out of our experience
with PackedObjects which took a very similar approach to the ValueTypes
attribute.

This proposal makes use of the existing ValueTypes attribute. In addition,
it requires that each classloader keeps a registry of ‘expected’ VTs.

Proposal
--
The following steps occur in the loading phase:

1. Prior to loading the current class each type in the ValueTypes attribute
is checked see if it is loaded. If it is, the type must be a VT or ICCE is
thrown. Otherwise, the type is registered with the initiating classloaders
expected VT registry (EVTR).

2. Pre-loading of ACC_FLATTENABLE instance fields follow the same rules as
the ones specified in Karen's proposal.

3. Prior to loading the current class, if the current class is a VT it must
be in the classloader's EVTR or ICCE is thrown. If the current class is not
a VT and does appear in the EVTR, ICCE is thrown.

In link phase prior to preparation:
- Same as Karen's static field rules, "static fields declared with the
ACC_FLATTENABLE flag set have their type pre-loaded..."

In preparation phase:
- Same as Karen's method overriding rules, "any method overriding needs to
perform value type consistency checking between declarer of the overridden
method ..."

At resolution time:
- Same as Karen’s CONSTANT_Class, field and method resolution rules
---

The benefit of this approach is that as soon as anyone believes a class is
a VT, it must be loaded as a VT or it fails. As a result, there is no
inconsistency of loaded VTs. This proposal doesn't guard against cases
where a class was not expecting a method return/arg type to be a VT but
then later on turned out to be a VT when it was resolved. However, I think
don’t think Karen’s proposal offered these guarantees either.

> Some aspects of the implementation complexity that we have identified so
far:
> a) At method resolution time, if there is a mismatch in value type
consistency
> between the declaring class and the actual type in the signature, then
there
> is also a mismatch in all classes that have overridden the current
method.
> This is particularly painful with default methods in interfaces.

With this proposal the only possible inconsistency here is:
Method has a return/arg type that is believed to not be a VT but turns out
to be a VT. In this case any compiled code is doing pass by reference
calling convention which works for both VT and non-VT types.

> b) We need to ensure that we catch all method resolution, through all of
the
> alternate accessor paths, including MethodHandles, VarHandles,
Reflection, JNI,
> so that we catch both the specification and implementation changes.

All these cases are covered with the class loading consistency checks
(EVTR).

> c) Our favorite, invokespecial ACC_SUPER, needs special handling, since
it
> performs selection which is not based on overriding, but based on
virtually
> re-resolving.

same as above

> e) If we modify the specification to allow eager loading, and save errors
> to throw at method resolution, we need to work through the JVMS question
> of which errors would be saved (e.g. OOME, SOE might be thrown as part of
> the implementation vs. saving LinkageError), as well as designing a new
> implementation mechanism to repeat exceptions relative to signatures used
> for method resolution.

This wouldn’t be required in this proposal

> d) Pass by value calling convention optimizations depend on loading the
> actual type. Loading of the parameter types on first method resolution
> implies that if the caller is compiled, the caller method requires
> deoptimization/recompilation to pass arguments by value for future calls,
> which is a performance cost.

Typically, a method is run a few times before it is compiled (perhaps I’m
making implementation assumptions?). At this stage, the return/arg types
are either loaded or they are always null. This seems to suggest that
deoptimization/recompilation scenario would not be a common occurrence.


--Tobi

> From: Karen Kinnear 
> To: valhalla-spec-experts 
> Date: 2018/06/26 10:32 AM
> Subject: EG help please with getting to LW1 re: Value Types
> Consistency Checking
> Sent by: "valhalla-spec-experts"  boun...@openjdk.java.net>
>
> Summary: Could we please allow eager loading for value types in the
> locally declared method signatures
> prior to preparation  for LW1?
>
> Without that we seriously risk being able to offer an LW1 early
> access binary for the JVMLS.
> We believe it is more important to get this into people’s hands for
> experimentation and feedback than
> to delay the eager loading at this time.
>
> Details:
> At our EG disc

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

2018-07-07 Thread John Rose
Hi Tobi.  Thanks for the write-up.

To be brief, your proposed technique will seems to require lazier selection of 
calling
sequences than what Karen proposed.  Argument and return registers cannot be 
assigned
to values if their size is unknown, which is the case before they are loaded.  
The JVM
must wait as late as the first actual call (with non-null parameters) to 
determine calling
sequences.

Karen's proposal allows calling sequences to be determined at preparation 
(v-table pack)
time, while yours requires them to be chosen much later, by the time of the 
first invocation
of a given v-table slot.  (For JVMs without vtables, a "v-table slot" really 
means an
equivalence class of CONSTANT_[I*]Methodrefs equated by the transitive closure 
of
override relations.)  The bytecode instruction just before that invocation 
might have been
a defaultvalue instruction on a previously unloaded class.  This means the JVM 
needs
to install traps in unused v-table slots, so it can decide calling sequences.

Karen's proposal, therefore, has the advantage of allowing the JVM more lead 
time
freedom to set up v-table calling sequences, at preparation time.  Yours 
requires
just-in-time assignment of calling sequences, which seems more difficult.

This leads to the question, what advantage did you find, with Packed Objects, 
from
making calling sequence setup lazier?  (I'm assuming that system scalarized 
arguments
into multiple registers.)  In other words, why is your phasing of the checks 
better than
Karen's?

— John

P.S. Background:

So we are extending object references (Ljava/lang/Object;) to cover references 
to values
also, at least in L-world.  This gives a simple story for the interpreter and a 
fallback for
less-optimized JIT-compiled code, but isn't enough to compete with 
statically-compiled
languages.

So the new requirement here is to make it possible for compiled calling 
sequences
to use specialized representations for value parameters and returns.  In 
particular, we
often wish to use one or more machine registers to hold scalarized fields, and 
we wish
to exclude null values (which require an extra encoding and impede some 
optimizations).

A secondary requirement is that we wish to pick the compiled calling sequence 
once
and not have to revise it.  This implies picking the calling sequence no later 
than the first
execution (compiled or interpreted) of any particular method, and getting it 
right the first
time.

Deoptimization of calling sequences–across override-trees of methods–is a trick 
we are
holding in reserve, but it seems a risky research project rather than an 
understood technique.
I think deoptimization at this scale hasn't been proven efficient yet, although 
it may be.

It seems that in order to flatten, we are obligated to load value types more 
eagerly
than object types.  Value types can't "hide behind" a polymorphic reference; any
user of a value type in its native form (not boxed) needs to "see" its complete 
field
list, which requires loading the classfile.  This is certainly true for object 
layout,
where an object that contains a value-typed field must load that value type to 
see
how much space it must reserve for it, in that object's flattened and packed 
layout.

Given that we are going to routinely pre-load value type classfiles, it is 
reasonable
to apply this technique in other places besides the layout of instances and 
fields.
In particular, the layout of calling sequences is in many ways closely analogous
to the layout of instances.  (There is a deep symmetry between calls and 
objects,
arising perhaps from the fact that function applications are isomorphic to 
curried
functions or tuples.  In any case, it seems to me that some such symmetry crops
up between the O-O notions of field extension and virtual method extension, and
so in JVM's treatment of object layout vs. its treatment of virtual dispatch, 
both of
which are examined carefully at loading and preparation time, before execution.)

Anyway, if we are going to preload field classes, it is no great additional 
burden to
preload argument classes too, if an appropriate signal can be defined (the VT 
list).
It might even be reasonable to preload *all* VTs mentioned in the list, just to 
make
the preloading process simpler and more predictable.  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.

On Jul 6, 2018, at 8:38 AM, Tobi Ajila  wrote:
> 
> I would like to propose an alternative strategy, one that would effectively 
> provide the same consistency checks outlined in 
> http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf
>  
> 
>  without requiring eager loading of value types (VT) in the return/args of 
> methods during the preparation phase. This is born out of our experience with 
> PackedO

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

2018-07-10 Thread Remi Forax
Hi all, 

> De: "John Rose" 
> À: "Tobi Ajila" 
> Cc: "valhalla-spec-experts" 
> Envoyé: Samedi 7 Juillet 2018 23:08:27
> Objet: Re: EG help please with getting to LW1 re: Value Types Consistency
> Checking

> Hi Tobi. Thanks for the write-up.

> To be brief, your proposed technique will seems to require lazier selection of
> calling
> sequences than what Karen proposed. Argument and return registers cannot be
> assigned
> to values if their size is unknown, which is the case before they are loaded.
> The JVM
> must wait as late as the first actual call (with non-null parameters) to
> determine calling
> sequences.

> Karen's proposal allows calling sequences to be determined at preparation
> (v-table pack)
> time, while yours requires them to be chosen much later, by the time of the
> first invocation
> of a given v-table slot. (For JVMs without vtables, a "v-table slot" really
> means an
> equivalence class \u0015of CONSTANT_[I*]Methodrefs equated by the transitive
> closure of
> override relations.) The bytecode instruction just before that invocation 
> might
> have been
> a defaultvalue instruction on a previously unloaded class. This means the JVM
> needs
> to install traps in unused v-table slots, so it can decide calling sequences.

> Karen's proposal, therefore, has the advantage of allowing the JVM more lead
> time
> freedom to set up v-table calling sequences, at preparation time. Yours 
> requires
> just-in-time assignment of calling sequences, which seems more difficult.

> This leads to the question, what advantage did you find, with Packed Objects,
> from
> making calling sequence setup lazier? (I'm assuming that system scalarized
> arguments
> into multiple registers.) In other words, why is your phasing of the checks
> better than
> Karen's?

> — John

> P.S. Background:

> So we are extending object references (Ljava/lang/Object;) to cover references
> to values
> also, at least in L-world. This gives a simple story for the interpreter and a
> fallback for
> less-optimized JIT-compiled code, but isn't enough to compete with
> statically-compiled
> languages.

> So the new requirement here is to make it possible for compiled calling
> sequences
> to use specialized representations for value parameters and returns. In
> particular, we
> often wish to use one or more machine registers to hold scalarized fields, and
> we wish
> to exclude null values (which require an extra encoding and impede some
> optimizations).

> A secondary requirement is that we wish to pick the compiled calling sequence
> once
> and not have to revise it. This implies picking the calling sequence no later
> than the first
> execution (compiled or interpreted) of any particular method, and getting it
> right the first
> time.

> Deoptimization of calling sequences–across override-trees of methods–is a 
> trick
> we are
> holding in reserve, but it seems a risky research project rather than an
> understood technique.
> I think deoptimization at this scale hasn't been proven efficient yet, 
> although
> it may be.

> It seems that in order to flatten, we are obligated to load value types more
> eagerly
> than object types. Value types can't "hide behind" a polymorphic reference; 
> any
> user of a value type in its native form (not boxed) needs to "see" its 
> complete
> field
> list, which requires loading the classfile. This is certainly true for object
> layout,
> where an object that contains a value-typed field must load that value type to
> see
> how much space it must reserve for it, in that object's flattened and packed
> layout.

> Given that we are going to routinely pre-load value type classfiles, it is
> reasonable
> to apply this technique in other places besides the layout of instances and
> fields.
> In particular, the layout of calling sequences is in many ways closely 
> analogous
> to the layout of instances. (There is a deep symmetry between calls and 
> objects,
> arising perhaps from the fact that function applications are isomorphic to
> curried
> functions or tuples. In any case, it seems to me that some such symmetry crops
> up between the O-O notions of field extension and virtual method extension, 
> and
> so in JVM's treatment of object layout vs. its treatment of virtual dispatch,
> both of
> which are examined carefully at loading and preparation time, before 
> execution.)

The symmetry is only true for immutable class. The main difference is that 
curried functions usually doesn't expose the value of the bounded parameters 
while tuples let you access to those values. 

>

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

2018-07-12 Thread Tobi Ajila
> 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.

--Tobi

> From: Remi Forax 
> To: John Rose 
> Cc: Tobi Ajila , valhalla-spec-experts
> 
> Date: 2018/07/10 05:44 AM
> Subject: Re: EG help please with getting to LW1 re: Value Types
> Consistency Checking
>
> Hi all,
>
> De: "John Rose" 
> À: "Tobi Ajila" 
> Cc: "valhalla-spec-experts" 
> Envoyé: Samedi 7 Juillet 2018 23:08:27
> Objet: Re: EG help please with getting to LW1 re: Value Types
> Consistency Checking
> Hi Tobi.  Thanks for the write-up.
>
> To be brief, your proposed technique will seems to require lazier
> selection of calling
> sequences than what Karen proposed.  Argument and return registers
> cannot be assigned
> to values if their size is unknown, which is the case before they
> are loaded.  The JVM
> must wait as late as the first actual call (with non-null
> parameters) to determine calling
> sequences.
>
> Karen's proposal allows calling sequences to be determined at
> preparation (v-table pack)
> time, while yours requires them to be chosen much later, by the time
> of the first invocation
> of a given v-table slot.  (For JVMs without vtables, a "v-table
> slot" really means an
> equivalence class \u0015of CONSTANT_[I*]Methodrefs equated by the
> transitive closure of
> override relations.)  The bytecode instruction just before that
> invocation might have been
> a defaultvalue instruction on a previously unloaded class.  This
> means the JVM needs
> to install traps in unused v-table slots, so it can decide calling
sequences.
>
> Karen's proposal, therefore, has the advantage of allowing the JVM
> more lead time
> freedom to set up v-table calling sequences, at preparation time.
> Yours requires
> just-in-time assignment of calling sequences, which seems more difficult.
>
> This leads to the question, what advantage did you find, with Packed
> Objects, from
> making calling sequence setup lazier?  (I'm assuming that system
> scalarized arguments
> into multiple registers.)  In other words, why is your phasing of
> the checks better than
> Karen's?
>
> — John
>
> P.S. Background:
>
> So we are extending object references (Ljava/lang/Object;) to cover
> references to values
> also, at least in L-world.  This gives a simple story for the
> interpreter and a fallback for
> less-optimized JIT-compiled code, but isn't enough to compete with
> statically-compiled
> languages.
>
> So the new requirement here is to make it possible for compiled
> calling sequences
> to use specialized representations for value parameters and returns.
> In particular, we
> often wish to use one or more machine registers to hold scalarized
> fields, and we wish
> to exclude null values (which require an extra encoding and impede
> some optimizations).
>
> A secondary requirement is that we wish to pick the compiled calling
> sequence once
> and not have to revise it.  This implies picking the calling
> sequence no later than the first
> execution (compiled or interpreted) of any particular method, and
> getting it right the first
> time.
>
> Deoptimization of calling sequences–across override-trees of
> methods–is a trick we are
> holding in reserve, but it seems a risky research project rather
> than an understood technique.
> I think deoptimization at this scale hasn't been proven efficient
> yet, although it may be.
>
> It seems that in order to flatten, we are obligated to load value
> types more eagerly
> than object types.  Value types can't "hide behind" a polymorphic
> reference; any
> user of a value type in its native form (not boxed) needs to "see"
> its complete field
> list, which requires loading the classfile.  This is certainly true
> for object layout,
> where an object that contains a value-typed field must load that
> value type to see
> how much space it must reserve for it, in that object's flattened
> and packed layout.
>
> Given that we are going to routinely pre-load value type classfiles,
> it is reasonable
> to apply this technique in other places besides the layout of

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

2018-07-12 Thread John Rose
Thanks, Tobi and Remi, for the helpful observations.

On Jul 10, 2018, at 2:43 AM, Remi Forax  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  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

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

2018-07-13 Thread forax
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" 
> À: "Remi Forax" , "Tobi Ajila" 
> Cc: "valhalla-spec-experts" 
> 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  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  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 concer

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

2018-07-13 Thread John Rose
On Jul 13, 2018, at 3:55 AM, fo...@univ-mlv.fr wrote:
> 
> Let's try …

OK!  (Caveat:  I am certain this is post-LW1.)

> 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. 

Yes.  What we are talking about here is a new resolution step for method 
descriptors.
The v-table setup (and/or override tree detection) looks only at the strings, 
but before
the first call the strings (parts of them) need resolution.

It looks like we are inventing a new JVM phase here:  value type resolution.

Or (calling Dan!) maybe we just add a bit of language to the JVMS that says
that resolving a method call entails resolving its value types.  No, it's not 
just
a little bit of language, because the resolution needs to walk up and down
the class/interface hierarchy that defines the method's override family.
These are the same paths as are walked by class loader constraint checking,
which is one of the more complex parts of the JVMS.

Basically, method overriding needs to re-run class loader constraint checking,
just for one override family, but with newly-loaded knowledge about value types.

That raises a possible counter-argument to the point that eager resolution of 
VTs is
"not JVM-like".  Yes, eager loading is not JVM-like, but if the alternative is 
a new
JVM phase, which is *even less* JVM-like, then maybe we just do the early load
and call it good.  It's a judgement call:  Is the complexity of the new phase 
warranted?

> 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 ?

I think in practice it will be necessary, especially given the delay in 
reporting
errors.  A program will be too busy doing work to tolerate ICCE's on random
method calls due to non-local effects (somebody else got to the interface
method first, with a different opinion).  This means interface default methods
(at least) need suites of varying adapters.

For me this re-raises the question of what happens if a *class* in an override
tree tries to inject a bad opinion.  That mustn't be allowed to spoil 
scalarization
but OTOH two bad classes might want to exchange nulls through their own
part of the override tree.  (Dirty habit!)  A full story needs to say how those 
guys
can continue with their nulls, without hurting optimization for the new code,
in the same override tree.  Or else we need grounds for telling the null-users
to go elsewhere, with with prejudice (ICCE) or permission (separate calling
sequence, separate v-table slot).  Yuck.





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

2018-07-24 Thread Frederic Parain




On 07/12/2018 02:41 PM, Tobi Ajila 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.


This is already the case for flattened value fields: even if the
application never use them, they can cause failures if their
pre-loading fails.

Fred




--Tobi

 > From: Remi Forax 
 > To: John Rose 
 > Cc: Tobi Ajila , valhalla-spec-experts
 > 
 > Date: 2018/07/10 05:44 AM
 > Subject: Re: EG help please with getting to LW1 re: Value Types
 > Consistency Checking
 >
 > Hi all,
 >
 > De: "John Rose" 
 > À: "Tobi Ajila" 
 > Cc: "valhalla-spec-experts" 
 > Envoyé: Samedi 7 Juillet 2018 23:08:27
 > Objet: Re: EG help please with getting to LW1 re: Value Types
 > Consistency Checking
 > Hi Tobi.  Thanks for the write-up.
 >
 > To be brief, your proposed technique will seems to require lazier
 > selection of calling
 > sequences than what Karen proposed.  Argument and return registers
 > cannot be assigned
 > to values if their size is unknown, which is the case before they
 > are loaded.  The JVM
 > must wait as late as the first actual call (with non-null
 > parameters) to determine calling
 > sequences.
 >
 > Karen's proposal allows calling sequences to be determined at
 > preparation (v-table pack)
 > time, while yours requires them to be chosen much later, by the time
 > of the first invocation
 > of a given v-table slot.  (For JVMs without vtables, a "v-table
 > slot" really means an
 > equivalence class \u0015of CONSTANT_[I*]Methodrefs equated by the
 > transitive closure of
 > override relations.)  The bytecode instruction just before that
 > invocation might have been
 > a defaultvalue instruction on a previously unloaded class.  This
 > means the JVM needs
 > to install traps in unused v-table slots, so it can decide calling 
sequences.

 >
 > Karen's proposal, therefore, has the advantage of allowing the JVM
 > more lead time
 > freedom to set up v-table calling sequences, at preparation time.
 > Yours requires
 > just-in-time assignment of calling sequences, which seems more difficult.
 >
 > This leads to the question, what advantage did you find, with Packed
 > Objects, from
 > making calling sequence setup lazier?  (I'm assuming that system
 > scalarized arguments
 > into multiple registers.)  In other words, why is your phasing of
 > the checks better than
 > Karen's?
 >
 > — John
 >
 > P.S. Background:
 >
 > So we are extending object references (Ljava/lang/Object;) to cover
 > references to values
 > also, at least in L-world.  This gives a simple story for the
 > interpreter and a fallback for
 > less-optimized JIT-compiled code, but isn't enough to compete with
 > statically-compiled
 > languages.
 >
 > So the new requirement here is to make it possible for compiled
 > calling sequences
 > to use specialized representations for value parameters and returns.
 > In particular, we
 > often wish to use one or more machine registers to hold scalarized
 > fields, and we wish
 > to exclude null values (which require an extra encoding and impede
 > some optimizations).
 >
 > A secondary requirement is that we wish to pick the compiled calling
 > sequence once
 > and not have to revise it.  This implies picking the calling
 > sequence no later than the first
 > execution (compiled or interpreted) of any particular method, and
 > getting it right the first
 > time.
 >
 > Deoptimization of calling sequences–across override-trees of
 > methods–is a trick we are
 > holding in reserve, but it seems a risky research project rather
 > than an understood technique.
 > I think deoptimization at this scale hasn't been proven efficient
 > yet, although it may be.
 >
 > It seems that in order to flatten, we are obligated to load value
 > types more eagerly
 > than object types.  Value types can't "hide behind" a polymorphic
 > reference; any
 > user of a value type in its native form (not boxed) needs to "see"
 > its complete field
 > list, which requires loading the classfile.  This is certainly true
 > for object layout,
 > where an object that contains a value-typ

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

2018-08-28 Thread Karen Kinnear
Tobi,

Thank you for the thoughtful proposal. 
Couple of questions/comments on the proposal

> On Jul 6, 2018, at 11:38 AM, Tobi Ajila  wrote:
> 
> I would like to propose an alternative strategy, one that would effectively 
> provide the same consistency checks outlined in 
> http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf
>  
> 
>  without requiring eager loading of value types (VT) in the return/args of 
> methods during the preparation phase. This is born out of our experience with 
> PackedObjects which took a very similar approach to the ValueTypes attribute. 
>   
> 
> This proposal makes use of the existing ValueTypes attribute. In addition, it 
> requires that each classloader keeps a registry of ‘expected’ VTs.  
> 
> Proposal
> --
> The following steps occur in the loading phase:
> 
> 1. Prior to loading the current class each type in the ValueTypes attribute 
> is checked see if it is loaded. If it is, the type must be a VT or ICCE is 
> thrown. Otherwise, the type is registered with the initiating classloaders 
> expected VT registry (EVTR).
> 
I have not walked through the implications of using an initiating loader to 
record EVTR. What confuses me here is that when defining a class, we look at 
the defining loader, so the class could successfully be defined, but there 
would be an ICCE when returning the type to the initiating loader so the 
loading/resolution would fail?
> 
> 2. Pre-loading of ACC_FLATTENABLE instance fields follow the same rules as 
> the ones specified in Karen's proposal.
> 
> 3. Prior to loading the current class, if the current class is a VT it must 
> be in the classloader's EVTR or ICCE is thrown. If the current class is not a 
> VT and does appear in the EVTR, ICCE is thrown.
> 
What happens if there is a call to define a class which is a VT but it has not 
yet been referenced by another class and is therefore not in any class loader’s 
EVTR? (we get a defineClass call with a byte[]). It won’t occur in an EVTR but 
we don’t want an ICCE at this point, right?

Concern: Who pays the cost of a mistake?
If we check during preparation of a local method, then the ICCE is thrown to 
the class declaring the method with the missing VT attribute.
If we check lazily, then the ICCE is given to the class that we expected to be 
a VT or not which doesn’t match some class’ expectations.
I grant that if the expected class has already been loaded, the ICCE will go to 
the referring class.
Is it the case then, that by adding the wrong class e.g. Foo to my ValueTypes 
attribute, or by accidentally leaving out Point from my ValueTypes attribute - 
then neither Foo nor Point will be able to load without getting an ICCE, and no 
one else can use them?


> 
> In link phase prior to preparation:
> - Same as Karen's static field rules, "static fields declared with the 
> ACC_FLATTENABLE flag set have their type pre-loaded..."
> 
> In preparation phase:
> - Same as Karen's method overriding rules, "any method overriding needs to 
> perform value type consistency checking between declarer of the overridden 
> method ..."
> 
> At resolution time:
> - Same as Karen’s CONSTANT_Class, field and method resolution rules
> ---
> 
> The benefit of this approach is that as soon as anyone believes a class is a 
> VT, it must be loaded as a VT or it fails. As a result, there is no 
> inconsistency of loaded VTs. This proposal doesn't guard against cases where 
> a class was not expecting a method return/arg type to be a VT but then later 
> on turned out to be a VT when it was resolved. However, I think don’t think 
> Karen’s proposal offered these guarantees either. 
> 
// Not sure if my assumptions work - my proposal is that for the case you 
describe: a class was not expecting a method return/arg to be a VT but then 
later on turned out to be a VT when it was resolved:
*5 in my proposal
- method invocation can work with NULL
- but the method invocation can not work with an actual value type - that 
gets caught when the method tries to get its hands on the actual value type
- I walked through my logic - that doesn’t count as a guarantee - love your 
double-checking
> 
> > Some aspects of the implementation complexity that we have identified so 
> > far:
> > a) At method resolution time, if there is a mismatch in value type 
> > consistency 
> > between the declaring class and the actual type in the signature, then 
> > there 
> > is also a mismatch in all classes that have overridden the current method. 
> > This is particularly painful with default methods in interfaces.
> 
> With this proposal the only possible inconsistency here is: 
> Method has a return/arg type that is believed to not be a VT but turns out to 
> be a VT. In this case any compiled code is doing pass by reference calling 
> convention which works for both VT and