Attendees: Remi, Tobi, Dan H, John, David Simms, Frederic, Karen I. Remi: the new static <init>()this needs to work with indy, but today you can’t use “<>” in the name. John: the MethodHandle is legit Dan H: name in a BSM does not have to relate to the underling method Remi: BSM has to change so that the name allows <init> (i.e. brackets)
II. withfield - is staying III. @Contended Ignore for an inline class or within an inline class, ok for a field containing an inline class see: http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2019-May/001074.html Dan H: @Contended is for bootclasspath only, only support class level today Frederic: javadoc on the annotation: Just a hint also: “trusted" classes only ed. note: I believe trusted classes means bootclasspath or platform class loader IV. Karen: There have been some email exchanges recently and I wanted to make sure we all were using the same terminology. For example, when we get to LW20 and offer support for null-default inline classes, we have been using the symbols: NV and NV? Note - that both are nullable. My question - what is the difference between them and do we need two “types” here? Remi: presented a session last week. “?” syntax was confusing to people a. relative to Kotlin and b. why not on reference classes John: Nullable is a side issue. The difference between NV and NV? for an inline class is whether the class is handled embedded vs. indirect Remi: NV? has an L-signature, right? Still, it is an inline class? John: “L” notation - does not allow us to find out if it is an inline class before use. So consistently, it is not determinable if this is an inline class. Remi: Once we load the class we will know it is an inline class. Need to consider separate compilation handling. Karen: Note that the “L” descriptor in this model does NOT imply identity. It does imply indirect. Remi: What if we were to throw an exception if an L descriptor defined an inline class, even when lazily loaded (e.g. post verification)? Karen: Due to the current proposal of VBC migration, existing “L” signatures would be used, and some clients would be aware that this was now an inline class and some would not. Remi: If NV? is not flattenable - is it still scalarizable on stack? John: Trying to avoid corner cases - which cause a long trail of tears old contract vs. new contract old contract: always indirect references heap storage is always indirect always nullable can be treated opaquely allows lazy loading allows circularity because it allows lazy loading Remi: There is a declaration world and a runtime world. If you declare as L and actually load the class and it is an inline class - does acmp determine identity handling vs. identities handling via descriptor? [ed note: no - acmp has to check the runtime type to see if it is inline vs. supports identity) John: Container semantics - define what it can contain - old vs. new contract new contract: load before layout Karen: concern about needing to know if nullable or not both programmer’s perspective - if switching from Point to Point? not only changes to indirect, but also allows null and vm perspective - as we discussed in the past, the JIT needs to know null-free for max optimizations John: bridging will allow going from old descriptor to new descriptor maybe also allow changing name? Remi: For renaming - what if that information was in module-info? The module-infos are loaded before the containers Karen: that is a partial solution to the problem John: great when you can do it. The vm always needs to know. Remi: all value-based-classes (VBCs) are currently in java.base or JDK Karen: Do others use VBCs? We could restrict migration of VBCs to java.base or JDK or in a module John: “adhoc” types we control need to define an overall policy clear old and new contracts and bridging technology Karen: Question is: with a new (not migrated VBC) null-default inline class - e.g. Person, does it need two representations? John: When would a developer need to specify “indirect”? 1. instance field circularity 2. atomicity - for containers in the heap only if the use-site does not want to say Volatile 3. arrays: e.g. performance - for heap container - e.g. if lots of copies are performed e.g. large object John: The translation strategy makes adhoc decisions between the old and new contract (ed. note - I think what John is saying that even if a user specifies “new” contract, i.e. please inline, the vm makes the decision of whether an inline class is inlined or not - e.g. based on size or atomicity) set a default policy allow advanced users to influence the decision Remi: One challenge for power users, is that an specific optimization often applies at one point in time, and not later (changes in software or hardware) - like “register” keyword in C - the decision was meaningful at one time An annotation perhaps Dan H: This might be different - since it ties into the data structure layout A change might be a surprise to users, they might be concerned if we ignore the hint Remi: Not want the hint in JVMS, like @Contended John: there is a language syntax point of view goal: simplest default - does the desirable thing want naturally inline object might want different - e.g. for generics or performance want a syntax that implies that this would not be for general use Karen: For NV and NV? (or Person/Person?) would we be looking at a subtype relationship or a conversion? This impacts verification and array covariance John: If contract is about containers This allows the vm to check correctness - specifically for a value set e.g. checkcast/ArrayStoreException/NullPointerException - if try to add null goal: the verifier type system forces the right checks whether that is a subtype/supertype or checkcast check prefer never checkcast to LObject (ed. note - my notes are not clear here) John: new contract: load class file eagerly and look at the definition verifier - only use information you have from descriptor, still tries to not load classes eagerly old contract: you do not know if you have an inline class or an indirect class you do not know if you have null ok or null free Karen: We have already discussed that we want the verifier to not eagerly load and still be able to exclude nulls so we need a use-site signal John: That is a requirement on the descriptor format, that the container is null-hostile Karen: Need to be clear that inline vs. indirect is not about null-ok/null-hostile John: distinguish between - “can use opaquely” vs. “must eagerly load and find out from class file” Agreed: verifier specifically - without loading can check null-free In the end we might not need that Remi: Kotlin - require-not null John: shake out in prototyping null-ok/null-hostile is not the primary dimension John: Also want old/new contract with templates templatedtype as a pure symbol vs. expand e.g. Optional<int> vs. Optional<long> some uses of template type need to be opaque, to allow circularities need to distinguish - indirect with abstraction vs. inlining with eager expansion still need a pair of contracts Karen: Doesn’t the wildcard/raw type already represent the non-expanded abstract use case? Or the erased generic use of jlObject? What problem does this not solve? John: Those are both old contract This solves most problems - but not corner cases such as - changes to overloading and overriding rules based on signature matching - therefore would want different method descriptors Remi: Useful for code specialization, even if indirect type e.g. HashMap specialization is orthogonal to inline vs. indirect corrections welcome, thanks, Karen