Valhalla EG minutes Nov 22

Karen Kinnear karen.kinnear at
Wed Dec 6 15:47:48 UTC 2017

Attendees: Remi, Tobi, Dan H, Ron, Frederic, John, Karen

Welcome Tobi Ajila from IBM!

Nestmates overriding review - Graham and Dan H
Reflection API review for nestmates - email thread: <>

Feedback on new LWorld email thread (“abandon all U-types”): <>
Feedback on Template Classes in the VM:

1. ConstantDynamic
Moved from JDK 18.3 to JDK 18.9
No one voice concerns. In fact since Remi is restructuring ASM this makes the timing easier.

2. ClassFileVersion: 
Plan: this will change for every JDK release regardless of whether there were ClassFile changes in the jVMS.
Goal: mid December change for JDK 18.3, then in future make the change very early in the release cycle.
Remi: thumbs up

3. Nestmates: JEP 181
Note that the JEP covers both the JVM changes and javac changes to add nestmate information for inner classes.
The inner class information will not go away - it contains additional information. A set of currently generated
package-private bridges will no longer be generated.

If you have reviews for the nestmates JVMS or reflection API please respond in email.

4. Minimal Value Types
Oracle status - bug fixing and release engineering/licensing - working through logistics of getting an Early Access open project out.
ASM state - refactoring and branching - ~ 1 month behind
would very much like binaries to remove the overhead of downloading and building the repository

5. Value Types next step

John described an overview of L-world - see email “abandon all U-types” : <>

A few folks from Oracle’s VM team, Dan Smith, Rolan Westrelin and John met for a week to discuss the next steps in Value Types - post MVT.
Initially we were brainstorming a proposal for universal types - U-type - which could be a disjoint union of an L-type (reference) or a Q-type (value type)
so that we could solve problems such as creating default methods in interfaces that could support subtypes that were either value types or references)
To fill out the potential kind space we introduced an R-type - which is a “legacy” L-type. This allowed us to clearly break out migration issues for
existing code that currently expects a reference when it for instance has a parameter of java.lang.Object or an interface.

John highlighted a few of the things we learned during MVT prototyping:
   - interpreter buffering mechanism for Q-Types - which can be buffered either off heap (potentially thread local) or on heap and the benefits of using the same header layout in both cases
   - JIT handling of Q-types which can have a 1+N representation - i.e. in addition to scalarizing the needed fields, might keep a pointer as well
   - between these we realized that a 64 bit pointer can represent object references, nulls or ValueTypes
   - looks like a 128 bit pointer is not needed
   - key is - if we keep the indirection and unpack opportunistically, can we get the performance we need? 
       - from our prototyping so far we think we can - more prototyping needed 

Question arose: do we need new carrier types - e.g. a U-type? Or do we even need a Q-type, and if so where?

One option that we explored is to re-use the existing L-Type to represent either a reference or a value-type
  +  bridging goes away, default boxes go away
  + legacy code operates on values
  risk: some legacy code will not work and we will need to defend against values
     - e.g. synchronization
 risk: performance of if_acmp_eq/ne - and some other byte codes

Dan H: what about identity?
John: NO identity for value types, they can be flattened or buffered, but there is no accidental identity, no heisenboxes
    e.g. acmp: 
      John will send a follow-up email: 
        choices (discussed with Guy Steele): an acmp in which both operands are not references could always return false or could throw an exception
        - model is that people have been trained to use acmp or .equals, so the false would allow the .equals to work
Remi: likes
John: note: this was a vm level discussion, still need to discuss with language folks

Karen: brief summary of proposal:
   L-Type as reference or value type
   Q-Type - as value type - AI: where do we need this?
   R-Type - as reference only - open question - do we need this at all?

Root: LObject - keep the top type, have it be a top type for ALL types: references, value types, more like an interface

Value types are:
   immutable (not all the way down)
   not nullable
   no identity
   flattenable (not guaranteed flattened)
   no default box - if you want identity, create a reference storing a value type field - we buffer value types, we do not box them
   support interfaces

   author must opt-in for a class to become a value type

Discussion of when we might want to explicitly use a Q-Type?
   - propose - for a field or array declaration
   - for a field declaration goal is to only preload value types not all references - want faster startup and reduced circularity issues

Remi: a Q descriptor might cause incompatibility
C# objects — (I missed the rest of the sentence - something about Dynamic and must map as same type)

Dan H: packed objects used annotations (list of packed classes) if Packed - and threw errors if mismatched. This was not well loved.

If you call a Q-type - if it is actually not a value type, could throw an error
Could have a modifier bit in the field vs. a QDescriptor?

Remi: flattening is dynamic
  For an array - at array creation we know the element so we might not need a Type

Frederic: for fields
   - for performance we precompute the layout of fields
Remi: agrees needed for fields

Method arguments? Do we need a Q Descriptor

John: for arrays - does the verifier need to check element and therefore need to load the element class? Or would this be a runtime failure if there
were a mismatch?

John : silver lining: Q means - can not observe object identity, null is not allowed, value-based, immutable
   Note: talked about an Ljava/util/List could not pass through a Qjava/util/List descriptor unless you ran List.copyOf first
(editor’s note - I don’t get this - is this a “freeze” operation? or dynamic conversion to a value type? We don’t have a default box ?)

Remi: If we have a Q in a method descriptor - do we need a bridge?
John: overloads? handle covariant return types?
Remi: QType <= LType? John :yes
  If you have a QType as a return type and it calls a method that returns an LType, then you need a covariant bridge and current code does NOT work
  John: recompile to make a bridge

John: method signature might need to use Q or R - if it only works for one or the other
C# solves this: Tony Hoare’s null problem
Remi: if you store null in a QType field - throw an exception

Remi with generics - added bridges to fix JLS/JVMS overriding rules mismatch
  looks like we would need bridges in current code
Issue with dynamic languages if interact with Java

John: “BSM” everywhere
  bridge-o-matic concept - “near miss” linkage error -> call BSM
  will need to explore what “near miss” means

Karen: what if we had no Q method descriptors and all byte codes worked for both Q and L types?
   - performance risk - need to find out
   - still able to do a string search on method descriptor match

Remi: Do we need Q-types at all?
Real constraint is the object layout which we need to know before we finish loading the class containing the field
John JIT wants to know as well
what about a modifier on a field? flattenable?
Note verifier can not check nullability if we don’t have Types
Note: verifier will check differently based on class file version

Remi: what about frozen arrays rather than declaring in the type system?
  What if we start trying to not ever use Q, and see where we need to add it
John: same for R - think about

Karen: performance of byte codes is the other key requirement for the L-world

John: Dan H & Tobi: did you ever add tag bits to managed references?
Dan H: not now - ask the GC guys
John: acmp - pointers with tag bits could allow fast check for is this a reference rather than a value type

John: We also discussed potential JVM exploration for Generics with Value Types and References
Starting with templates from C++

issues: heap layouts of parameterized classes
   - different sizes
   - different optionality (i.e. potential to be null)

Proposal: (JVM perspective)
  Create constant pools with holes for: classes, method handles, fields, method, …
  Track dependencies of constant pool entries on parameters
  Segment constant pool - associate a set of constant pool entries with a segment
  have a common/root segment

  If holes are not filled, there is very little you can do (e.g. wildcards)
  If hole is not filled: “Riddled”, so you can’t resolve
Class concept
  species as instantiation of a template
  new relationship between the template class and the species

Dan H: Descriptors?
John only unriddled descriptors can be resolved
  structured descriptors which are not the same as flattened strings, however
  if the constant pool Riddle is Solved, then a descriptor could be flattened into a string

  caveat: if a template client creates a species by requesting holes filled  - it fills them with live types which are resolved by
     the template client - and must be visible to the template client’s class loader, module, etc.
     they do NOT have to be resolvable from the template class’ class loader
     ed. note: all the species have to be created in the same runtime package/module/ class loader/ protection domain

Remi: MethodTypes will have the same issue
John: will need some extensions on class loader constraints
Note: can only verify after filling the holes

1. wildcare types
2. generic methods - need a carrier for genericity
3. generic virtual method in generic class (infinite table size?) (stretchable table? or change to non-viable?)

Template invariant parts are shared
  variant parts are not shared
John: if no global dictionary of keys? Need constant pool links


More information about the valhalla-spec-observers mailing list