Re: EG meeting, 2020-07-15

2020-07-15 Thread Dan Smith
Notes from the discussion:

> On Jul 15, 2020, at 12:01 AM, Dan Smith  wrote:
> 
> The next EG Zoom meeting is tomorrow, 4pm UTC (9am PDT, 12pm EDT).
> 
> Recent threads to discuss:
> 
> - "JEP draft: Identity Warnings for Inline Class Candidates": I drafted a JEP 
> that lists candidates for inline class migration and describes the compiler 
> and runtime warnings needed to prepare for their migration

Remi wondered whether changing the semantics of '==' for wrapper classes will 
be a problem. Answer: constructors will be deprecated; for the small integers 
(-128 to 127?) produced by 'valueOf', == will have the same behavior; for the 
large integers produced by 'valueOf', behavior of == is currently unspecified, 
so we're fine to change behavior.

There's a consensus that we should probably track the inline class candidates 
(or maybe all value-based classes?) with an annotation.

> 
> - "Revisiting default values": I described use cases for different treatments 
> of inline types' default values, and then summarized various strategies for 
> supporting some of the nontrivial use cases

General agreement that the "Bucket #3" group (classes without a natural 
default) is what we should focus on, not the "Bucket #2" group (classes that 
want a nontrivial default).

We talked through various "Bucket #3" approaches. The preferred approaches seem 
to be:

- Guards on member access, either compiler-generated or JVM-enforced. Fields 
and default methods require special attention. (May involve making the invalid 
default equivalent to "null", but there are complexity concerns.)

- Tracking uninitialized fields/arrays in the JVM. There's concern about 
performance of array reads, best optimization might be adding a boolean 
"isInitialized" flag to each flattened value. There's also concern about 
tearing producing unexpected default values in corner cases, possibly mitigated 
with our story for atomicity.

- Bucket #3 classes must be reference-default, and fields/arrays of their 
inline type are illegal outside of the declaring class. The declaring class can 
provide a flat array factory if it wants to. (A new idea from Tobi, he'll write 
it up for the thread.)



Re: Revisiting default values

2020-07-15 Thread Remi Forax
So the default value may a valid value or may be an invalid value,
if it's an invalid value it should be the author of the class that say that 
because in Java we prefer declaration site to use site.

One way is to try to teach the VM how to do the conversions, i want to explore 
another way where we try to solve that issue at the language level, to avoid to 
have a more complex VM.

A default value which is invalid should behave like null, i.e. calling any 
methods on the default value should result in an exception.
Doing that at the language level means adding a check before calling any 
instance methods and before accessing any instance fields.

So there are two parts to solve,
1/ how to specify the check, is it just this == Inline.default or is it 
whatever the user want (or something in the middle, like a field check)
2/ how to execute that check when accessing a field or a method ?

Let explore the solution that offers the maximum freedom for the author of the 
inline class, i.e. for 1/, the check is user defined.
For that we can introduce a new kind of initializer, like the static block, 
let's call it the invariant block
  inline class Foo {
private final Object o;

invariant {
  if (o == null) {
throw new InvalidFooException();
  }
}
  }
this invariant block is translated into a method (that has the name  
see later why) and is called each time a method or a field is accessed.

For 2/, we can either change the spec of the VM so the invariant block is 
called automatically by the VM or we can use invokedynamic.
invokedynamic has the advantage of not requiring more VM support at the expanse 
of the bootstrap issue. 

The main issue with invokedynamic is that it's not a backward compatible change 
because it requires to change the call sites.
So we can lessen the requirement like this, requiring only the call to 
 when accessing an instance method because
we suppose that people will not be foolish enough to declare the fields public,
In that case, there is no need for using invokedynamic because a call to the 
invariant method can be inserted by the compiler at the beginning of any 
instance method.
This solution also has the advantage of lowering the cost at runtime compared 
to using invokedynamic.

In term of performance, i believe the language spec should say that the 
invariant block has to be idempotent.
Because in that case, the VM is free to not execute several calls to the 
 method once one is executed on a specific instance
(like the JITs do nullchecks collapsing currently).

To summarize, i believe we should allow more value based classes to be 
retrofitted as inline class by adding the concept of invariant block to the 
Java language spec.
An invariant block being a simple idempotent method called at the beginning of 
every instance methods.  

Rémi

- Mail original -
> De: "daniel smith" 
> À: "valhalla-spec-experts" 
> Envoyé: Vendredi 10 Juillet 2020 20:23:25
> Objet: Revisiting default values

> Brian pointed out that my list of candidate inline classes in the Identity
> Warnings JEP (JDK-8249100) includes a number of classes that, despite being
> "value-based classes" and disavowing their identity, might not end up as 
> inline
> classes. The problem? Default values.
> 
> This might be a good time to revisit the open design issues surrounding 
> default
> values and see if we can make some progress.
> 
> Background/status quo: every inline class has a default instance, which 
> provides
> the initial value of fields and array components that have the inline type
> (e.g., in 'new Point[10]'). It's also the prototype instance used to create 
> all
> other instances (start with 'vdefault', then apply 'withfield' as needed). The
> default value is, by fiat, the class instance produced by setting all fields 
> to
> *their* default values. Often, but not always, this means field/array
> initialization amounts to setting all the bits to 0. Importantly, no user code
> is involved in creating a default instance.
> 
> Real code is always useful for grounding design discussions, so let's start
> there. Among the classes I listed as inline class candidates, we can put them
> in three buckets:
> 
> Bucket #1: Have a reasonable default, as declared.
> - wrapper classes (the primitive zeros)
> - Optional & friends (empty)
> - From java.time: Instant (start of 1970-01-01), LocalTime (midnight), 
> Duration
> (0s), Period (0d), Year (1 BC, if that's acceptable)
> 
> Bucket #2: Could have a reasonable default after re-interpreting fields.
> - From java.time: LocalDate, YearMonth, MonthDay, LocalDateTime, 
> ZonedDateTime,
> OffsetTime, OffsetDateTime, ZoneOffset, ZoneRegion, MinguoDate, HijrahDate,
> JapaneseDate, ThaiBuddhistDate (months and days should be nonzero; null
> Strings, ZoneIds, HijrahChronologies, and JapaneseEras require special
> handling)
> - ListN, SetN, MapN (null array interpreted as empty)
> 
> Bucket #3: No good default.
> - Runtime.Version 

EG meeting, 2020-07-15

2020-07-15 Thread Dan Smith
The next EG Zoom meeting is tomorrow, 4pm UTC (9am PDT, 12pm EDT).

Recent threads to discuss:

- "JEP draft: Identity Warnings for Inline Class Candidates": I drafted a JEP 
that lists candidates for inline class migration and describes the compiler and 
runtime warnings needed to prepare for their migration

- "Revisiting default values": I described use cases for different treatments 
of inline types' default values, and then summarized various strategies for 
supporting some of the nontrivial use cases