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