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: 1) LWorld 2) Nestmates and the Alternate Accessors 3) VT workshop 4) Condy Nestmates: 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 Value Types: 1. Cloneable: options: 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 static type: 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? e.g. Map.get() 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 John: 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 Karen: 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 John: 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 Value Types 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 3. circularity 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 Nullability: John: LWorld 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 John: summary: Treat Types as Types in this classfile verifier can reject null bearing values, method call boundaries, heap containers worth exploring