Here's a concrete proposal for how we'll evolve the wrapper classes (Byte, 
Short, Integer, Long, Float, Double, Character, and Boolean) to be inline 
classes whose ".val" representations are (in the Java language) the primitive 
types.

This has the effect of replacing boxing conversions in the Java language with 
lighter-weight reference conversions (no identity is imposed), and will 
facilitate specialization in the JVM by wrapping primitive values in 
lightweight inline class instances.

Important concepts in this approach:

- The wrapper classes are reference-default classes—'Integer' is a '.ref' type.
- In the language, 'int' is an alias for 'Integer.val'. These are the same type.
- In the JVM, there are three distinct types: 'Ljava/lang/Integer;', 
'Qjava/lang/Integer$val;', and 'I'

The below outline feels pretty complete to me, as far as the core 
library/JVM/compiler components are concerned, and quite achievable. Please 
raise anything I'm overlooking (I'm sure there's something...).

---

Step 1: Warnings

In the near future, we implement a variety of warnings for clients of the 
wrapper classes who rely on features that will break when the wrapper classes 
are inline classes:

Library changes:
- The constructors, currently marked deprecated, are deprecated for removal. 
This should amplify warnings about their use.

Java compiler changes:
- Attempts to synchronize on or invoke wait/notify methods of expressions with 
wrapper class static types produce a new warning.
- Possibly, uses of '==', 'identityHashCode', or 'clone' on these expressions 
produce a warning.
- Possibly, any uses of 'getClass' that compare with '==' to wrapper class 
literals produce a warning.

JVM changes:
- Possibly, runtime warnings occur mimicking some of the compiler warnings, but 
using runtime types.

(Note that all of these warnings may also apply to Value-based Classes. The 
wrapper classes happen to fall short of the value-based class requirements in 
their factories' guarantees about identity; these rules about factories and 
equality are probably unnecessary limitations, given the current deterministic 
behavior of acmp.)

---

Step 2: Preview Feature

When, or sometime after, we ship inline classes as a preview feature, we 
support treating the wrapper classes as inline.

JVM changes (when --enable-preview is set):
- References to java/lang/Integer and java/lang/Integer$val are hacked to load 
special class files corresponding to the .ref and .val types of inline class 
Integer.
- The type [I is considered by the verifier to be equivalent to 
[java/lang/Integer$val. Array operations (aaload, iaload, etc.) support this.

Java language/compiler changes (when --enable-preview is set):
- The class file reader knows how to find the special Integer.class and 
Integer$val.class.
- The type 'Integer.val' is equivalent to 'int'. Primitive types are inline 
types—they have members, support method invocation, etc.
- Where necessary (depending on the operations being performed), the compiler 
generates conversions between 'I' and 'java/lang/Integer$val'. 'I' is preferred 
wherever possible.
- Boxing can be specified with stronger guarantees about '=='.

---

Step 3: Standard Feature

When we're ready to leave preview, we'll need to raise the profile of "those 
things we warned about are going to blow up now!".

Library changes:
- The wrapper classes are declared in source as reference-default inline 
classes.
- The constructors are removed, replaced with private constructors.

JVM changes:
- Wrapper classes are loaded using standard processes.

Java language/compiler changes:
- The wrapper classes have special permission to declare fields of their own 
type.
- Wrapper classes are read using standard processes.


Reply via email to