Valhalla EG notes March 14, 2018

Karen Kinnear karen.kinnear at
Mon Mar 26 21:33:33 UTC 2018

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

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 - 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

Proposed approach: extend MethodHandles.Lookup

Karen: summary
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:

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 

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



More information about the valhalla-spec-observers mailing list