Valhalla EG minutes May 9 and Apr 25 2018
karen.kinnear at oracle.com
Wed May 23 14:11:30 UTC 2018
Corrections welcome - apologies for the delay
May 9, 2018
Attendees: Remi, Dan H, ]Dan Smith, Frederic, David Simms, Karen
JVMLS upcoming talks:
Any interest in cohosting:
2) Nestmates and the Alternate Accessors
3) VT workshop
Plan is to get this into JDK 11
JEP is targetted
Spec update was sent for review - any questions?
Remi: ASM 6.2 will be ready next week with Condy and Nestmates (later email update: and preview version handling)
John: cleaning up issues e.g. invokespecial
1) disallow override and allow call: what does it mean to return the same Value Type?
2) disallow calling clone?
Should javac give a warning?
What about backward compatibility?
For signatures that pass Object?
John: note: clone is protected so must be called from subtype
Dan H: propose prototype throw exception we can change this later
2. Null hygiene email
VM static typing model - distinguish heap vs. stack
verifier - check static type on stack
others: ensure type publishing to heap
enhance static typing model: list locally known value types - provide a classfile view
when load classfile - check if really a Value Type
lazily load other types
a) identity sensitive
most checks are dynamic type based - even if operating on “Object”
b) null suppression
(ed. note: under re-discussion)
Want static and dynamic
from classfile point of view - catch surprise nulls
Helps users, helps optimizations e.g. method scalarization
1) verifier: aconst_null
2) checkcast: if local classfile statically knows VT: add null check
3) callee checks input arguments for null
4) return: caller check
Dan H: for return - only statically declared VT known locally
John: invocations are linked, may want to cache non-nullable information
Remi: what about libraries that use null as a return type?
John: wants the VM to be locally strict
if we have to deal with occurrences of nullable VT, revisit
maybe explore: ValueRef in the language?
Remi: 1) map.get()
2) push null to a Lambda
John: does checkcast save you?
Remi: need checkcast in bridge
what about aconst_null call to erased generic?
John: NPE is thrown, location varies
checkcast could work for non null VT, could optimize away checkcast
Remi: user may get NPE
e.g. java.util.concurrent: methods take null in API spec - null as sentinel input
Remi: prefer: nullable ValueType annotation
VM has to not do null check
John: what about when erased to Object?
Remi: or implement interface?
John: need to handle this in the context of erasure
Perhaps lang and API folks fix the rest?
Remi: requires more bridges
John: don’t want to change fields, arrays, method descriptors - that ways lies pain
but may have to do this
Frederic: we have L descriptor which today implies nullable, perhaps a new descriptor for non-nullable?
John: what if map.get were to return a ValueRef of ComplexDouble?
Frederic: Concern is if we do the first prototype with the same descriptor but change the semantics,
it is confusing if we add a new descriptor with the same semantics
exploring: nonnullable container for VT - without exploring general nonnullability
might help with backward compatibility for APIs with Object/Interface/[Object/[Interface
allow generic specialization to optimize if you have nonnullable references
allow javac/verifier/runtime checks
Remi: isn’t this the same as the side table?
Frederic: No. Different signature perhaps. Key is the nonnullability as a property of the container/reference, not the type
Caller must convert
e.g. in new code: use NVT; - which is non-nullable
to pass to a method that expects Object;, safe to cast NVT; -> LVT;
do the work at the boundary
In Q-world we changed the type hierarchy of classes. In LN world - we change the property of the container/reference, not the type of the class
NVT; is a non-nullable reference to the same class VT as LVT; which is a nullable reference to VT
Trying to scale down the pain
Remi: Need adaptation, e.g. hierarchy of methods
John: prefer to try simpler approaches before new descriptors
e.g. ValueRef Interface
e.g. LComplexDouble -> LValueRef
Karen: requires changing implementation of existing code - e.g. APIs which return null
1. generic code: free to instantiate to DoubleComples, ValueRef of DoubleComplex
2. APIs which return Optional - don’t have nulls as part of the API
Concern about requiring changing existing implementations in the field: 1) erased generics and 2) APIs that assume null
e.g. new code using old APIS that passes a non-nullable [VT and the implementation stores a null -> NPE
Works like an Int - NPE is analogous to ArrayStoreException
With a null return: checkcast will catch this immediately
Also an expectation that most users will do a null check first for APIs that use null as a sentinel e.g. that no entry was found
John: we may have to go to excited types ! and ?
warning - that is a separate language discussion before it enters the vm discussion
Remi: need another kind of erasure
John: could use lazy casting: e.g. allow null check before casting - above the vm
Remi: not many APIs use null for sentinels
perhaps we don’t use those methods with VT
John: perhaps only allow ?type in the return position?
Dan H: Look at Collections?
note: Brian started looking in 2012 - there is a literature of methods like this, may need to look again
John: did a verbal introduction to Brian yesterday about value type hygiene, Brian is thinking about it
Remi: type annotation may allow javac/verifier/runtime/JIT
generics: may need special case null checks - perhaps with local annotations?
John: let’s prototype the super-strict approach and see if it helps with optimizations
Remi: there is an existing code road bock for value-based-class migration
What does == on Optional.empty do? Need VBC to use .Equals
John: libraries may need implementation changes
e.g. Class.cast() - may need to add Class.castRef? reject null for VT? call Object.equals()
Clear that a strict vm does not solve all problems
Remi: benefit to having a prototype sooner rather than later, outside world needs to see progress
John: performance depends on the strictness dial
benefits in experiment with and without strictness
Dan H: consider binaries via the adoptOpenJDK project?
talk to Brian - using this for Amber
April 25, 2018
attendees: Dan H, Tobi, John, Frederic, David Simms, Lois, Karen
1. pre-loading of classes:
needed for field flattening
JIT method calls - preload formal parameters
maybe a single mechanism
— details not worked out yet
2. proposing a new attribute
javac view vs. runtime view
javac - list all types known to be value types
runtime: classes not listed in the attribute - don’t reload, don’t flatten
if in the attribute - preload, check if VT
can decide to flatten
can use for fields and method signatures
For layout we need to check circularity errors
discussion of - if we detect a circularity error - perhaps don’t fail the load but rather treat as non-flattenable
(ed. note - not sure how this would work)
Note: VTs used in fields need to preload at class load time, used in method signatures - need to load at preparation time
JIT needs to know value types for optimization
note: calling convention: if inconsistencies between superclass and subclass lists - need to follow the least specific declaring classes’ view of ValueType
Dan H: if value type is not in the list -> throw ICCE
Remove an attractive nuisance
John: if we can be null hostile at call boundaries we can allow optimizations
migrated value types are a corner case
alternative: leave as is: JIT can be null hostile if it has VT information and deoptimize if null -> reduces performance
Frederic: a common approach is to add an additional argument to specify null
John: in new code we would never have null for a VT
Karen: concern about nullability and backward compatibility
Dan H: historically tried to avoid recompilation by javac increasing performance, discouraging javac clever optimizations
Frederic: only time this would happen would be if you migrate a VBC -> VT
Types are all nullable, verifier can’t tell, if values are nullable they are not flattenable
goal: have the vm be as null hostile as possible
Clearly we will check nullability for containers - instance fields, static fields, array elements
Verifier limitations: note: locals are NOT null hostile
one approach: javac could add null checks as necessary
or have a dial between hostility and leniency
John prefers complete hostility when possible
e.g arrays of VT are really flattenable and null hostile
Dan S: original LWorld discussion - QTypes expressed null hostility
alternative exploring: flag on fields
if you want full control over null - maybe need QTypes
arrays: preload the element, so we know it is a VT
fields: have a flag
could have QTypes in method signatures and verifier
OR: casts could allow nulls
locals - could expect javac to introduce null checks
If we use Types for identity and value type and we preload all VT
ACC_FLATTENABLE allows checking non-nullability for fields
John: want the semantic effect
if preload a VT and mismatchL -> throw ICCE
Treat Types as Types in this classfile
verifier can reject null bearing values, method call boundaries, heap containers
More information about the valhalla-spec-observers