Valhalla EG notes Feb 28, 2018

Karen Kinnear karen.kinnear at
Fri Mar 9 22:13:54 UTC 2018

Attendees: Remi, John, Dan H, Lois, Tobi, Frederic, Karen

Corrections always welcome.

Condy, Nestmates - merging Dan’s early JVMS/JLS drafts into the next full JVMS/JLS.
We will send out a link when they get posted so we can all review the merged changes.

I. Value Types

1. Review of nullability for value fields:
   Nullability for fields is declared by the container via ACC_FLATTENABLE field modifier in the classfile.
   This only applies to value type fields.This implies non-nullable.

      must preload before completing loading of the class
      must initialize to the default value 
      attempts to store to the field (publish) throws NullPointerException

   Implementation determines if the field is actually flattened, but the semantics remain unchanged.

John: this is a JVMS, not a java language specification. Java can choose its own default as well as any language syntax later.

Frederic: rationale is the compatibility story. Allows existing value-based-classes like Optional to migrate to become value types and allow classfiles that declare Optional fields, and clients that access those fields to continue to work unchanged, including the ability to store/retrieve a null.

Note: arguments, local variables can contain a null for a value type, it is only when publishing that an NPE is thrown.

John: not calling this non-nullable from a language feature perspective. Might be something more like “probable flattening”.

Remi: why preload?
John: If we defer loading we might get circularity errors which should prevent the container from loading

2. Nullability for arrays
   Based on emails this week between Mr Simms, Remi, John on valhalla-dev at, here is a summary of a new proposal:

    Value type arrays are always flattenable, and therefore not nullable

    If the end user wants non-flattenable/nullable they can use Object[] or Interface[] or maybe a future reflective API if needed that creates a reference array - but for now let us assume that value type arrays are always flattenable, prototype that and then we can assess what the cost might be if we need dynamic checking.

     As with fields, implementation determines if the component is actually flattened.

    bytecode implications:
       aaload - returns default from default initialized value type component
       aastore - throws NPE if attempt to store null. Must store default value for component
       anewarray/multianewarray - if the component is a value type, create a value type array

    (note: rough draft JVMS needs updating)

Remi: what about compatibility?
    if you read an array that is empty today, you get null
    if you read a flattened array, you get a default value

John: with arrays we do not need to do any preloading so no benefits to not always flattenable
   believe limited use cases for non-flattenable arrays

   solving the JVM part - not the user model or language

Remi: concern Optional[] - will no longer see nulls
John: Optional is not supposed to be seen in the heap
        - with generics, there are no Optional[] that are reified - so erasure saves us
Remi: Kotlin, ??, Scala - reify
John: languages can make their own compatibility decisions
Remi: can buy argument
John: let’s prototype this and see

Dan H: sanity checking that the default value for arrays is not user supplied
   - to avoid cost of walking & storing
Dan H: assuming all value[] flattenable
Karen: yes - not nullable, no guarantee flattened

Remi: want to know if actually flattened - e.g. for performance
John: tools that give you the information of what is in the heap and the shape of the object
Remi: tool was deprecated (jhat) - want to know at runtime
Karen: serviceability issue
John: or reflection
Karen: no control over this
Frederic: might change by platform or command-line args

3. Atomics

Tobi: Concern if write a value type to a flattenable field in a container
   want to ensure atomicity of field or array component update

   need clear rules of what to expect
   e.g. doubles and longs today can tear

John: meeting with Doug Lea - guidance:
   Do not worry about flattening by default - do not lose the performance model in general
   need explicit non-tearing, e.g. for security sensitive

Need to explore possible approaches: e.g. declare a class as always atomic
e.g. atomic up to hw atomic support, or use seqlocks, or don’t flatten for performance

Tobi/Dan H: JVMS - we need to document that value types are tearable by default
   (ed. note: we need to update rough draft JVMS - yes!)

John: possibilities: volatile field or entire class as volatile
Tobi: value based class today will not tear -> migrate to value class: changes behavior
    (ed. note: for arrays - yes, for fields no - default is not flattenable so existing classes unchanged)
John: explore: if e.g. the class is ACC_VOLATILE, perhaps non-tearability for fields together, not for each field?
    - note: only on heap
Karen: need to research

Remi: only for value types?
John: yes - references are already non-tearable
Note: prototyping for atomicity - seqlocks or indirection - seqlocks slow -> ask Intel folks for help

4. Creation: scope of withfield

Remi: from a vm perspective - understand why not a vnew bytecode
   rest - language level discussion

default: anywhere
withfield: restricted to nest

Remi: not ok with restriction on withfield
  encapsulation by modifier not by opcodes
John: invoke special - some modes restricted
John: wants to restrict ‘new’ in future
  alien thing having a public field, this is as if withfield checks a different public bit
Remi: accessors are created for this
John: classfile - all value type fields are final, none are writeable outside the nest
Remi: use case: change inner class to be a top-level class - can’t use withfield
John: “Reconstructors”
   with: create a new object, want withfield inside the nest and checked access points outside nest
Remi: other languages do not want to mix opcodes and access checks
Dan H: do you need access to withfield or do you need factory methods?
Karen: want factory - e.g. validate interdependencies between fields
Remi: serialization - in jvm, not in java, to create a value type from outside data
John: serialization has to overcome final in a field, e.g. SetAccessible today
   - unless figure out a better way - why not call a Reconstructor?
Remi: what if constructor is private?
John: serialization needs to call private constructors anyway

Remi: value types will have constructors
John: yes, but not <init>
   unless maybe static <init> which does not return void?
Karen: verifier would prefer a different name
John: bikeshed - but maybe <xxx> different special name
Remi: default bytecode
Frederic: return is usable always
Remi: ValueRecord will need
  Object Classes: final fields are written by constructor
  Value classes: final fields are written by anyone in the nest
   naming: canonical universal constructor for serialization

John: maybe <make> ?
  longterm control of use of new bytecode
  only instantiable via factory methods
  vm old code - compatibility
  future: new only in factory methods. > security, still need <init> e.g. for Supers

  naming convention benefits stronger than just Records or serialization uses

Dan H: likes the move away from new/dup/<init>
   concern: legacy corpus - long-term play

Karen: like security and more shareable code - e.g. for generics - if common naming/able to call a factory

John: language decision - maybe use C++ notation, drop the “new”, e.g. (typename)arg , …

Remi: value-based-class change to value class - language level goal?
  e.g. new optional?

John: how compatible? Issue a warning? 

Dan: Why would vm offer a canonical name?

John: <init> today has special rules
   <make> - no special rules for verifier
      - naming - ensure not in valid namespace for java programmer

Dan H: new/dup/<init> in nest in future? John: yes
John: yes. <init> has signature with void return today, maybe if use <init> with non-void return?
Remi: if retrofit void as a value type -> then not distinguishable
John: maybe <make> overloaded with args. must always be static

More information about the valhalla-spec-observers mailing list