attendees: David Simms, John, Frederic, Dan S, Tobi, Dan H, Remi, Karen apologies for not noting the meeting time change in US/Canada relative to Europe - should be all set now Corrections as always - welcome
AIs: John: Check Nashorn usage of BSM with Object as 1st parameter John: email proposal about usage of MethdHandle for ldc including usage examples All: review https://bugs.openjdk.java.net/browse/JDK-8171335- - dynamic nestmates (+) proposal - read it through - comments have updated the proposal from the initial description All: John issued a challenge - non-vacuous meaning of final for Value Types I. Condy Dan S - are folks ok with the BSM descriptor change - distinguishing with Lookup as 1st parameter, and throwing error if not to allow this as a future differentiator? Karen: Lois, Karen ok Dan H: decreases ability to use BSM with Object today - expect this is vanishingly small use case - so OK What about Nashorn usage? John : AI: check Dan H: believe JRuby started with Lookup John: in practice - this could be an unambiguous distinguisher for condy - since it is new for indy - if we adopt the restriction they can be similar alternative: we could add a new combinator in front of a new BSM with a new protocol to get the new capability Dan S: condy is often simpler to create, creating a CallSite is more complex John: today: condy is adding an invocation to do what we wanted the VM to do for us Brian has an example in Amber handling symbolic expressions creating syntax trees, with an BSM per level of expression, all named “invoke” - which is a “smell” A bigger cleanup would combine all three invokes into one, i.e. a multi invoke BSM with args perhaps 1 multiinvoke BSM with constants and delimiters in the right order which invokes an expression tree no longer 1:1 CP entry to function call we may not need the VM to cache the intermediate steps Dan S: the natural way to express syntax trees in the the CP is to have each node with its own constant and BSM map John: need ways to deal with sub-expressions John: another future idea invoke dynamic constants to be LDC able - i.e. to return a MethodHandle rather than a CallSite completes a matrix: constants have 2 forms: 1 field type, 1 method type indy constant: MethodType type (actually MethodHandle) if indy constant mentions a MethodType give me a MethodHandle with signature ldc - invoke exact or ldc -> MethodHandle behavior want JVM to ensure signature is an exact match Dan H: Is the MethodHandle a dynamic invoker invoked through the CallSite or a 1 time? John: dynamic invoker as if a free floating CallSite as a forward compatibility direction - allow indy BSM to return a MethodHandle as well as CallSites if need a CallSite and get MethodHandle - wrap a constant CallSite around it note: Mutable CallSites - used by dynamic languages - only work for indy and are not in the CP [ed. note - is that accurate? an indy BSM can not return a Mutable CallSite?] Dan H: If VM creates the CallSite - no one could change it if no references leak Karen: indy BSM today is not shareable, ldc has 1:1 CP entry and resolved value would a BSM for ldc MH be shareable? John: [ed. note - missed the answer?] Karen: who creates the CallSite if ldc resolves to a MethodHandle? John: Not the VM Dan H: already have condy, struggling to find use case John: get MH w/signature w/out creating asType and MH constant Dan S: Lambda produces a MH John: we can do this with condy today but it neds an extra layer - could reduce noise in CP Karen: is there a write up? John: AI: email a proposal Dan S: With BSCI, one of the goals is to move the complexity to the library John: concept of a “butterfly network” Allow any use case to use any constants - relative to field and method types. Move the type mixups to low levels of library code Dan H: does this negate the need for condy? John: VM has a natural type system - with separate field types and method types represented in the CP and bootstrap level combinators, pattern matchers, lambdas - still work with j.l.Class and j.l.MethodType which are the reflected field and method types where possible, nice to have a low level approach that works for both one doesn’t reduce to the other except for simulators Dan H: aware we can do this easily, where do users see this? John: users are classfile translation strategy designers, currently using lots of MH want to create expression trees out of field types and invocation Karen: can you provide examples? Dan H: yes please Remi: concerns: not want two different ways to do the same thing - will send comments in reply to the minutes II. Nestmates Karen : Sealed classes will not make JDK 11 Dynamic nestmates - exploring - possibly part for JDK 11 https://bugs.openjdk.java.net/browse/JDK-8171335 Proposed approach: extend MethodHandles.Lookup Karen: summary Goals: 1. Create dynamic nestmates For static nestmates, explicitly designed so that the NestHost “authorizes” NestMembers. For dynamic nestmates, propose using providing a Lookup with appropriate mode on the NestHost as authorization to create a NestMate John pointed out we need to distinguish between a Private Lookup and a Full Power Lookup and we need to have that conversation for appropriate mode here. In JDK9 we added a Lookup.defineClass with Package mode which allows defining a class within a package. Intention is to extend this to allow defining a dynamic Nestmate with the same capabilities as a static nestmate, with the exception that the java.lang.Class.getNestMembers()” will only return the statically declared members. Dan H pointed out: we will need an API to get the dynamic members 2. evolve unsafe.DefineAnonymousClass to a supported mechanism Proposal is to extend Lookup.defineClass with the appropriate mode to allow - defining an UNNAMED class - i.e. not findable in the SystemDictionary - defining a TEMPORARY class - which must also be UNNAMED - allowing class unloading on a different lifecycle than the creator or host See RFE: https://bugs.openjdk.java.net/browse/JDK-8171335 The intention is that the three flags/enums: NESTMATE, UNNAMED, TEMPORARY are independent, so you can use this to create non-nestmates. Need to look at the required Lookup modes and make a matrix. In addition, there is a proposal to replace the constant pool patching with the ability to pass in a single live type which is as if you had a pre-initialized static, not in the constant pool, which can only be retrieved via an API on the Lookup. Dan H: is this live type necessary given condy? John: yes - you need at least one object reference which you can inject in a class to associate with user data so that you have this when you run the static initializer Dan H: note: never implemented the constant pool patching for unsafe.DefineAnonymousClass - never found a use for it. John: relates to condy condy does symbolic resolution from the current class’ context this mechanism can have a different context Dan H: users could have a condy BSM which they write themselves John: only via symbolic references - if the class is temporary, i.e. has no name - they would need a local namespace shared between the definer and the defined class itself Dan H: or a common named class to communicate through John: concerns about race conditions and privacy problems, this is not a class loader isolation model which is considered less safe today Dan H: how look up live data? John: method call on Lookup on your own class - no one else can get to it as if injected class has an extra static variable pre-initialized library API: getUserData, not getStatic if you can think of another way to initialize a private static final variable with a value that is unnamed and unknown to the definer (and not trust thread locals) Dan H: sounds similar to ClassValue John: alternative trick? Can’t print if it is not yet loaded Remi: or thread local John: assume initiating loader Karen: intentional - not required to be seen by initiating loader? John: this is a live class, avoid name/symbolic reference, not required to be in a shared namespace Remi: want to ensure that when the class’ lifecycle is over, the live type is not kept alive John: for class lifecycle - ensure UserData can be acted. UserData lifecycle should not keep the class alive. [ed. note - I added that note to the RFE] John: computed before class is defined as if set static before class initializer is run Remi: use case - AST - want to pass in with bytecode John: could serialize AST into CP of the new class Remi: would have to reconstruct and lose profile data Karen: you are using the CP patching today, right? Remi: yes John: Remi - ok with you to replace with UserData? Remi: yes III. lworld <init> JohnL not expect <init> to play a big role with value types, it is a Object initializer, moving toward factory methods Remi: need to test Srikanth’s changes for withfield syntax John: repurpose constructor syntax Remi: could use static methods Karen: checked with verifier - ok to reuse name <init> if helpful “final” value type fields: John: can we skip marking value type fields as “final” - no benefit - might want to have meaning in future Dan H: expected the other way - preserve final now so semantics don’t change if future more options Remi: javac use final to detect changing a field of VT John: benefit of final bit? Remi: vm - no, javac -yes Dan H: if we take it away in future, it will need to be meaningful John: potential future option: not stateful values final for Object means can only be set in a constructor (write once) westfield means withfield state changes only in constructor Dan H: that is a discussion of the scope of withfield John: constructor or nest? if final means restrict setting - nonfatal could allow setting based on access controls always do Copy-on-Write who is allowed to replace single fields? Remi: that is a class level, not a field level decision John: final - want smaller than class, maybe just constructors? Remi: that would change the meaning of final - change all reflection and all tools that process bytecodes Dan H: VM would require a known factory? John: codes like a class - marker for all classe - final allows limited writers use cases - e.g. serialization - that need to set final fields outside of a constructor Remi: they could call a constructor John: simulation of “new” bytecode - e.g. Cloneable - no way to clone all final fields writing up Reconstructor/Deconstructor Reconstructor - like a constructor - acts as a factory secretly temporarily cloning object and patch new fields even if final Remi: how to create factories on VT - see if they will apply to Object rather than changing semantics of final base this on withfield access John: if final means access to withfield - maybe another modifier bit for new tricks Question: if final in VT fields now - what would be the meaning if unset in future? Dan S: bar higher if unset by default precedent: classfile has redundant info for consistency require opt-in Remi: clone - is a class level decision, not a field decision look at the class semantics for the new modifier John: final-withdraw set operation: objects: putfield, values: withfield Dan S: final bit for VT: default put final - i.e. not mutable John: can be mutated? what about a field initializer? Create a constant for a field? No. Dan S: sort out with VT how to interpret nonfinal vs. final John: challenge - find non-vacuous meaning for final for VT - which have different physics Remi: plenty of modifiers can use - at the class level, not the field level e.g. volatile John: volatile - need atomic marking - use ACC_VOLATILE? Remi: use a different bit if you want a different semantic - first get a clear design of a factory John: another model: withfield allows setting with no side effects nesmates can use withfield - not confined to factories/constructors/reconstructors final means can’t use withfield outside nest RemiL VM vs. Reflection & JDK: can’t call set on it DanH: putfield will not verify on a value type John: link time will throw ICCE thanks, Karen