Valhalla EG notes Feb 28, 2018
karen.kinnear at oracle.com
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.
If ACC_FLATTENABLE then:
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 openjdk.java.net, 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.
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
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
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
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