Notes from Minimal Value Types review May 10, 2017 attendees: Bjorn, John, Maurizio, Frederic, Vladimir, Karen
AIs: All - please review Shady 0.4 update from John - http://cr.openjdk.java.net/~jrose/values/shady-values.html 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 MVT 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 Concepts: 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