LWorld prototype - initial brainstorming goals/prototyping steps

Karen Kinnear karen.kinnear at oracle.com
Wed Dec 13 14:52:54 UTC 2017

This is a very rough draft of goals/requirements/next possible steps for the Lworld prototype for us to
discuss in our valhalla vm meeting. Corrections/additions welcome. Thanks to Frederic for brainstorming with me. thanks, Karen


I. New terminology:
 L-Type as reference or value type
 Q-Type as value type
 R-Type as reference only - open question - do we need this?

II. Assumptions:
1. New root: LObject - more like an interface
   keep the top type

2. value types are
  immutable (not all the way down)
  not nullable
  no identity
  no default box, if you want identity, create a reference storing a value type field
    (buffer not box)
  support interfaces

III. goals:
   existing interfaces should be implementable by both references and value types
    - without requiring recompilation
   existing code should be able to handle both references and value types
    - without requiring recompilation

     LType -> QType migration
       author must opt-in: language policy how to declare, requires recompilation
     Value-Based-Classes on recompilation could become value types on recompilation
     Any existing class that meets the requirements could become a value type

        j.l.Object as the only supertype
        no use of identity  (at least within the type itself)
        no sync/wait/notify
        no assumptions of nullability
        no non-private constructors

IV. Expected Behaviors:

1. Object methods
  sync: for QTypes - throw exception (ICCE? IMSE?)
  getClass: with no default box - no longer ambiguous
  finalize: throw exception for QType
  equals: QType - component-wise equals (call ucmp?)
  hashcode: TBD - needs to be based on equals
  toString: nothing special
  clone: nothing special?

2. Java level APIs
  isElementValue (for an array - not the same as is the array a Value)
  ucmp - substitutability check

3. Interface support, default methods
   must handle both L-types and Q-types

4. bytecodes
Key Challenge: can we apply the same bytecodes to QTypes and RTypes? can they check dynamically without loss of performance?
  special handling:
       try 1: false if either is a QType, they must use .equals
       try 1: false if QType (or throw exception?)
       try 1: always true if QType (or throw exception?)

   interpreter needs dynamic different handling:
     aaload/aastore: handle LType or QType dynamically
     aload/astore: handle LType or QType dynamically
     areturn: handle LType or QType dynamically

  exception if wrong kind:
     putfield: QType exception: IAE?
     monitorenter/exit: exception for QType (ICCE? IMSE?)
     new: exception for QType (ICCE?) - expects uninitialized state
     vdefault: exception for LType (ICCE?) (maybe leave current name for now)
     vwithfield: exception for LType (for now) (maybe leave current name for now)
     aconst_null: exception for LType (ICCE?)

  unchanged or already implemented or should fall out:
     getfield: handle LType or QType dynamically (already implemented)
     newarray/etc.: handle LType or QType dynamically (already implemented)
     athrow: always LType  - unchanged
     invoke*: handle LType or QType dynamically (should fall out)
     checkcast/instanceof: should fall out

V. Implementation use of explicit QType
1. Field descriptors
  Goal: not require verifier or class file parser to load all fields.
     ICCE if misclaimed, at first runtime mismatch (kind constraints)
     To allow flattening, want field and arrays to explicitly use QTypes at language level

2. Array descriptors: propose - yes
     Remi: not needed - at array creation you know the element type
     Frederic: uniformity
       - confusing to explain inconsistency
       - javac already knows the information and has done the work, why slow down?
       - safety - kind constraints - could be checked

3. Method descriptors : propose - no
   1) receivers indicated in any way? descriptor? flag?
   2) method descriptor parameters/return type
   Propose: do NOT support QTypes in Method Descriptors
    challenge: descriptor mismatches based on migration

1. support other superclasses?
  QType has no subclasses
  for now - QType has only jlO as superclass
  still open extension jlO or not?
2. acmp behavior options:
   a) failing: return false <- propose for try 1
   b) throw exception
   c) field-equality using ucmp as "substitutable" - field-wise comparison
     general bit equality including floating point
     may need to recurse on values buffereed
3. Do we need to know if an LType is an old L-Type or a new LType?
A: be on the lookout - we have not yet identified any cases
   If we do, we have CFV
4. argument passing/argument return handling/impact of dynamic type detection?
   If we have kind constraints then we should not get runtime mismatches
5. Do we need a new carrier type?
   TBD - so far requirement not identified.
6. What does it mean for LObject to be more like an interface?
   Do we disallow adding fields? policy - bad if it had fields.
A: Yes
   Is it the new superclass for all VT? Can we replace __Value?
A: Yes
     modify methods (see above)
   API to find out if value - java level API (see above)
7. What can the verifier check, what do we want to check later to avoid early class loading?
A. Expect to create kind constraints.
   When would we check these, how later ICCE?

9. What does updated Object.hashcode do?
  - field equality based hashcode
  - assume cache in header optimization
  Dan: call hashcode or identity hashcode (throw) - performance tradeoff

10. Do we need a fast way for Java to determine ValueType (isValue call?)
  Frederic proposed: e.g. give all value types a common super interface
  e.g. ValueMarker

  - verifier or class file format checking at class loading
    - ensure that this can't be a superinterface if not a value type
    - this is probably temporary, but useful

11. Frederic: migration challenges
  Karen assumed legal to go from a reference that follows restrictions to
  a Value Type upon recompilation with keyword.
  Frederic assumes customers will also go the other direction.
    instance creation:
      value type - must have a private constructor - so new will fail IAE
        - except for nestmates (dynamically added which are not same compilation)
        - except Reflection.setAccessible

Early experiment:
Add to JDK 11 (not MVT specific)
 add checks on sync for VBC (add annotation?) and VCC
 add checks for ifacmp_eq/ne NOT followed by a call to .equals?
 (todo: find Dan's corpus search results email)

Experimental steps:
1. new repo - remove MVT parts
2. finish splitting tests
  - just want -XX:+EnableValhalla

  __ByValue for class declaration
  __ByValue for static and instance fields
       super as java.lang.Object
       generate a* bytecodes except for vdefault/vwithfield - leave alone
  add restrictions checking
       allow superinterfaces

a. new static utility class for new bytecodes (Maurizio? runtime?)
   isValue, isflattened, isElementValue? default ucmp?

b. java.lang.Object methods
   Using isValue - rewrite

Runtime interpreter:
a. bytecodes - see list above
b. verifier -
   propose changes
   propose kind constraint handling
c. method handle support

a. bytecodes
b. adaptor generation
c. optimizations

Migration testing:
Try VBC -> value type -- run tests and see what breaks

More information about the valhalla-dev mailing list