Minimal Value Types notes May 10, 2017

Karen Kinnear karen.kinnear at
Mon May 22 15:36:08 UTC 2017

Notes from Minimal Value Types review May 10, 2017

attendees: Bjorn, John, Maurizio, Frederic, Vladimir, Karen

All - please review Shady 0.4 update from John -
John - create JEP for Minimal Value Types, linked to Shady
VM implementators: check impact of removing CONSTANT_Class “;QFoo” and necessity of adding
     vmultianewarray instead of overloading anewarray and multianewarray

1. Summary of updates from John: (reordered to match conversation)
1a. VCC/DVT relationship:
 - make relations between VCC and DVT much more definite
 - VCC is just a POJO; DVT derivation is decoupled from VCC loading
 - push DVT down beneath the woodwork: it has no separate name, mainly a view of the VCC
 - distinguish between primary (proper) mirrors and secondary (improper) mirrors
 - simplify reflection:  no sourceClass, VCC does everything as a POJO

note: reflection only supported on the VCC
New concept of a primary mirror (VCC) and a secondary mirror (DVT), which could
help in future with specialization views. 
Not clear where this is exposed.

1b. - ditch the much-unloved ";QFoo;" syntax for CONSTANT_Class (use context instead)
 - link to more focused draft JEP on CONSTANT_Dynamic (forthcoming JEP in progress in a few weeks)
Editor note: to clarify timing of CONSTANT_Dynamic (Condy) - certainly not prior to Early Access of

Meeting explored in detail requirements for verification on byte codes vs. constant pool
   ldc - this always gets a CONSTANT_Class, so always gets the primary mirror
         - if you want the secondary mirror - not allowed for Early Access
         - option 2: investigate if ldc with CONSTANT_Dynamic  works ok for MVT 

         note: piggybacking on BootStrapMethod
          - one concern: BSM allows up to 65,000 bootstrap args, today limited to 251
          - e.g. with matching switch - if each case needs a different arg and we use Condy, will need
            a way to support > 251 cases

    vgetfield vs. overload of getfield - leave as vgetfield since verifier needs to know the type
        of the receiver without a constant pool change

    anewarray, multianewarray - currently overloaded byte codes dynamically checking type
     of element. Verifier needs either constant pool or specific byte code to distinguish.
    Meeting proposal - add a new byte code - vmultianewarray (see AIs to double-check verifier requirements and update Shady)

ed. note: internal explorations of verifier changes without constant pool tagged as a value type
is bringing up issues, so this will need further discussion.

 - discuss DVT initialization and its triggers (see below for load/link/init review)
 - clarify that the JVM does not try to enforce complete initialization of values
 - update bytecode descriptions to better match Valhalla prototype
 - reminder: all this will change

Meeting also explored vdefault, vwithfield restrictions:
   vdefault and vmultianewarray are unrestricted
   vwithfield restricted to VCC
      - this implies that creation of a value type other than default must use a MethodHandle wither

note from John about vwithfield byte code allowing nestmates, e.g. if you have a Lookup object with
private access mode you could see private members. 

 2. under "more bytecodes” Shady added guidance on carriers and U-types
Exploring “sorts”, e.g. extend IJFDL to add Q and U types
  Type might be a QFoo or an LFoo
  note: if LFoo, preserves identity, but does not assume identity

note: some instructions deal with references or null, some do/will not
John: we may be able to get optimizations from having the same payload field alignment and layout
for a UType whether it is a LFoo or a QFoo

3. review of load/link/init proposal from Karen

Think of embedded value type fields as pre-loaded classes, analogous to super type handling today
Think of VCC as a pre-loaded class for the DVT.

We discuss linking and initialization of the DVT here so that the class can maintain class state requirements, even though
at this time the DVT has no static fields and no methods including no <clinit> or <init>.

Resolution of a VCC (LFoo)
   load VCC
     - today we eagerly derive the DVT class based on the annotation
   link VCC: no impact on DVT
   initialization of VCC: no impact on DVT
     triggers for VCC initialization: new, static byte codes

 Resolution of a DVT (QFoo)
    resolve the VCC, i.e. lookup Foo, classloader and  load VCC if not already loaded
    link DVT: first link VCC
    initialize DVT: first initialize VCC
      triggers for DVT initialization: vdefault, vunbox, vmultianewarray 

  Agreed: For an array with a DVT component - you must load, link and init the DVT
  You do not however need to create a DVT instance - the array can be filled with 0’s since we now know the
   element size. Vaload must create a DVT instance and can count on

  Uninitialized and partially initialized DVT:
     No such thing as 

3a. Request from Dan Smith (JVMS) - Allow lazy DVT derivation and loading
      - i.e. specify at first use of the DVT and load before linking, rather than at VCC load time
      - note: MVT may grant leeway here since this will be a non-issue long-term when there is
        only one classfile

3b. ed. note - John’s review notes comment about having a value type field embedded in an object
or value type. I explicitly took those out of the initial proposal to simplify it. Follow-on note in case
we were to add this back
  Object or DVT with an embedded DVT instance field:
     embedded DVT (including any nested embedded DVTs) are included in the pre-loaded classes list so we can
     correctly handle field layout
     Load of container: pre-load embedded DVT
     Link of container: pre-link embedded DVT
     Init of container: pre-init embedded DVT

Meeting note: embedded DVT in a static field:
     - must be loaded at preparation time, so prior to linking the container
     - this is explicitly different than the instance field, to avoid potential circularity errors

4. exposure of secondary mirror?
Need to investigate how much of java.lang.Reflect API we can avoid for MVT
Note: value type has NO methods. So you can not perform getClass on the secondary mirror returned by ValueType.forClass.
You have to box to invoke getClass, and therefore you always get the primary mirror for the VCC.

Maurizio: do we need an is_value predicate? And might we want to make this easier for the client if
for example reflection APIs such as newInstance were to throw an exception if given a secondary mirror

Explore what might be a appropriate for MVT for reflection to provide. Proposed that Early Access
throw errors to get feedback. (e.g. do not allow getting the superclass of a value type)

p.s. correction on earlier minutes - Doug’s reference was probably to
Scala’s Martin Odersky

More information about the valhalla-spec-observers mailing list