Valhalla user-model
João Mendonça
jf.mend at gmail.com
Sun Jun 12 11:55:02 UTC 2022
Hello,
I would like to bring to your consideration the following set of
observations and user-model suggestions as I am hopeful they will be useful
in the context of the Valhalla project.
*Definition*
*shared-mutable* - a variable that is mutable (non-final) and can be shared
between threads; shared-mutables are the non-final subset of the
shared-variables (§17.4.1.)
*Observations*
Shared-mutables are the only variables that have these two apparently
independent properties:
1. lack definite-assignment (§16.) - the variable is initialized with a
default-value if not definitely assigned (§4.12.5.)
2. allow data-races - the variable may be read/written while being
written by another thread, with both events happening with an unpredictable
order (§17.4.5.)
Property 1 and 2 share a unique characteristic: the external behavior of
the variable is automatically altered when, respectively, the nullability
and the representation mode (inlined/reference) of the variable is changed:
1. if not definitely-assigned, the variable is initialized with:
- if nullable: the null value, regardless of the variable's type
- if not nullable: the zero_value of the variable's type
2. in a data-race, the value read/written:
- if reference: has unpredictable origin in *one* of the various
writes
- if inlined, either:
- has unpredictable origin in one of the various writes
- is teared i.e. has distinct internal parts with separate
unpredictable origins in *more than one* of the various writes
(§17.7.)
These are the 3 kinds of shared-mutable variables (§4.12.3.):
- non-final class variables
- non-final instance variables
- array components
The remaining kinds of variables don't have any of the above properties:
- final class variables
- final instance variables
- method parameters
- constructor parameters
- lambda parameters
- exception parameters
- local variables
*User-model*
For class-authors:
- *value-knob* to reject identity - Applicable on class declarations, if
used by a class-author to indicate that the class instances don't require
identity (a value-class), the runtime will be free to copy these instances
and swap between reference and inlined representations everywhere except in
shared-mutables, as doing so does not introduce any changes to the external
behavior of the program.
- *atomicity-knob* to forbid tearing - Applicable on value-class
declarations, may be used by the class-author to ensure tearing cannot
happen on shared-mutables in order to preserve constructor invariants that
may be useful for class-users to rely upon. The runtime is free to
implement this through a reference representation or by ensuring
inlined-write atomicity.
- *noDefault-knob* forbids the zero-value being used as a default-value
- Aplicable on value-class declarations, may be used by the class-author to
force shared-mutables of this class to either be definitely-assigned or
nullable. (Actually, I don't believe this knob will be useful, since I
think all zero-values are equally bad. Moving across the spectrum from
useful to useless to out-of-domain default-values is moving from hidden to
noticeable to obvious missed-initialization-bugs. Ex: false -> 0.0 -> Jan
1, 1970 -> 0/0 -> null)
For class-users:
- *nullable-knob* includes null in the value-set of a variable -
Applicable on any variable declaration, in either mode of representation.
The runtime is free to choose the encoding for the extra bit of information
required to represent null. In shared-mutables that are not
definitely-assigned, controls the default-value: either null or the
zero_value of the value-type. Since identity-types lack a default-value,
any non-nullable shared-mutable of an identity-type must be
definitely-assigned.
- *atomic-knob* to avoid tearing - Applicable on shared-mutable
declarations, may be used by the class-user to ensure tearing does not
happen. The runtime is free to implement this through a reference
representation or by ensuring inlined-write atomicity.
If, for compatibility, the representation modes must remain complected with
nullability, the nullable-knob and the atomic-knob above can be replaced
with:
- *inline-knob* to require inlined/reference representation - Applicable
on shared-mutable declarations with a value-class type, gives the
class-user control over the tradeoffs between performance, footprint,
nullability and implied default-values, and if/how to manually avoid
tearing.
Kind regards,
João Mendonça
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20220612/51ca71ea/attachment.htm>
More information about the valhalla-spec-observers
mailing list