State of javac support for lworld-values.
Srikanth
srikanth.adayapalam at oracle.com
Tue Mar 13 11:46:21 UTC 2018
Hello Frederic, Karen and list,
I have taken stock of and reviewed the changes made so far to javac to
support lworld values and I think the work looks complete as far as I
can tell (except for https://bugs.openjdk.java.net/browse/JDK-8198749:
Role of constructors and <init> methods for value classes - which is
still under discussion)
I would be happy to follow up on any errors of omission and/or
commission or to accommodate any new requirements that emerge as the
prototype work evolves.
Here is an inventory of features, constructs and behaviors already
pushed to lworld branch tip:
- A class declaration may be tagged as being a value type by using
the `__ByValue' modifier
- This feature is allowed as of now, at source level >= JDK11
- Only a class may be tagged as being a value type - interfaces,
annotation types, enums cannot be.
- Top level, inner, nested, local classes may be tagged as __ByValue.
- Value classes must be declared to be final and so abstract
classes or interfaces cannot be value types.
- Akin to enums, annotation types and interfaces, value types may
not declare an explicit super class (not even j.l.O). All value types
implicitly extend j.l.O. They may declare explicit super interfaces.
- Value types can be type arguments in generic type parameterizations.
- Value types can be explicit type witnesses in generic method
invocations
- Value types can be wildcard bounds (even if only with limited
utility on account of being final classes - a la String)
- Value types can be intersection (cast) type components (FWIW),
- Value instances can be enclosing instances in instance creation
expressions.
- At the class file, a value class is signalled by the class flag
ACC_VALUE(0x100). Javac will ignore this flag *from* class files when
compiling for a source level that does not recognize value classes as such.
- All instance fields of a value class must be declared to be final.
- Value instances are created with __MakeDefault. `new' cannot be
used with value classes and likewise __MakeDefault cannot be used with
non-value reference types.
- __MakeDefault does not accept any parameters. No constructor
invocation - not even the no-arg constructor invocation - is involved.
- Values have no instance lock and so may not be synchronized upon.
- Values have no identity and consequently the method
java.lang.System.identityHashCode may not be invoked on them
- The following methods from j.l.O are not allowed on value receivers:
clone(), finalize(), wait(), wait(long), wait(long, int),
notify(), notifyAll()
- Value instances may not be compared with == or !=. == and !=
cannot have any value operand(s)
- instance methods of value types do not have a monitor associated
with their this and so cannot be declared as synchronized
- Null cannot be assigned to value types
- Null cannot be casted to or compared with value types.
- Fields may be flagged as being__Flattenable. This results in the
ACC_FLATTENABLE(0x100) field flag bit being set in the class file.
Besides setting this flag bit, the compiler does not use this flag.
- There may not be a cycle that passes through fields tagged as
being Flattenable.
- With the compiler option -XDrejectValueMembershipCycles, javac
will not allow a value type to declare fields of its own type either
directly or indirectly (flattenable or otherwise)
- An instance field of a value class may be updated via the
__WithField "operator". This does not update the original value
instance, but produces an updated copy.
- The first operand of the __WithField operator must be an instance
field of a value class, while the second operand is of suitable type
that is assignable to the the first operand field.
- __WithField may be used to update an instance field of a value
type only from, but anywhere from the same nest.
- __Withfield may not be used to update a value field with null.
- There is no implicit write back - the result of the __WithField
operator must be assigned to a suitable *writeable* handle - There is no
relaxation of the rules around finality when it comes to value types. So
final variables cannot be written to. Nor can `this`
- (non-blank) final *instance* fields of value types that are
initialized with compile time constants are not treated as constant
expressions and do not take part in constant propagation/folding. Each
read of such a field would result in a fresh getField and the
ConstantValue attribute would be missing in the class file.
- The compiler will insert a null check when an object or interface
type is cast into a value class.
- Two new opcodes: defaultvalue(203) and withfield(204)
- Byte code library has been brought up to date
- Tests for all the above.
Thanks!
Srikanth
More information about the valhalla-dev
mailing list