<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Jun 26, 2018, at 7:30 AM, Karen Kinnear <<a href="mailto:karen.kinnear@oracle.com" class="">karen.kinnear@oracle.com</a>> wrote:<br class=""><div><blockquote type="cite" class=""><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Summary: Could we please allow eager loading for value types in the locally declared method signatures<br class="">prior to preparation  for LW1? <br class=""></div></div></blockquote><div><br class=""></div><div>My answer would be "yes, if said types are mentioned in the</div><div>ValueTypes attribute".  Otherwise, it seems impractical to do</div><div>eager loading of type names that appear in descriptors, on</div><div>the off chance that they might be value types.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Without that we seriously risk being able to offer an LW1 early access binary for the JVMLS.<br class="">We believe it is more important to get this into people’s hands for experimentation and feedback than<br class="">to delay the eager loading at this time.<br class=""><br class="">Details:<br class="">At our EG discussion on June 20, 2018, we discussed the proposal for Value Types Consistency checking<br class="">at <a href="http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf" class="">http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf</a><br class=""><br class=""></div></div></blockquote><div><br class=""></div><div><div>The value-types-consistency-checking-details document should</div><div>probably lead off by describing the ValueTypes attribute, before</div><div>giving the four bullet points about instance fields, static fields,</div><div>descriptor types, and cross-call consistency.  Otherwise, I get</div><div>totally lost in the third bullet, when it claims "these types are</div><div>eagerly loaded" but without saying exactly what triggers this</div><div>loading.  Looking at the Valhalla prototype (which not all</div><div>spec experts can do) I see that the 'is_declared_value_type'</div><div>function is queried when method adapters are created,</div><div>so we can agree that ValueTypes is the source of truth for</div><div>method arguments and return values.</div><div><br class=""></div><div>(Given ValueTypes, we don't need ACC_FLATTENABLE, as has</div><div>been discussed.  AFAIK, we are using ACC_FLATTENABLE in LW1</div><div>because we don't want to destabilize the system with a cleanup,</div><div>and because we might want it later, but I'm arguing that we</div><div>don't want it at all in the long run.  Reason:  Any such marking</div><div>of fields is *also* a desirable marking of method descriptor</div><div>components.  Thus, an ACC_FLATTENABLE, applicable only</div><div>to fields, is not sufficient for our needs, while ValueTypes is</div><div>both necessary and sufficient.  For nullability in particular,</div><div>what we really need is a marker for both field and method</div><div>descriptors, along the lines of Fred's N-types.  By JVMLS,</div><div>I expect I will have a concrete proposal in this space that is a</div><div>side effect of supporting reified type parameters.)</div><div><br class=""></div><div>(But as long as ACC_FLATTENABLE is in the mix, perhaps the</div><div>consistency checking rules should *also* insist that the field types</div><div>of fields so marked must also be mentioned in the ValueTypes</div><div>attribute?)</div><div class=""><br class=""></div></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Part of the proposal for checking value type consistency relative to the actual type<br class="">was for locally declared methods. The proposal was to check the value types in arguments/return type<br class="">before preparation of the declaring class.<br class=""><br class="">During the meeting, there was a request to explore whether we could either:<br class="">1)  delay checking the value type consistency until an attempt to resolve the method for invocation, or <br class="">2) write the JVMS is such as way as to allow eager loading, but only throw an error related to the eager loading at method resolution.<br class=""><br class="">My understanding is that the goals of this are two-fold:<br class="">1) if the method is never called, the rest of the code will continue to run<br class="">2) reduce eager loading<br class=""><br class="">We have started this investigation, and there is non-trivial complexity in implementing either of these approaches,<br class="">and we would like more time to explore how to make this possible, after making LW1 available.<br class=""></div></div></blockquote><div><br class=""></div><div>Yep, I am not surprised that this is hard to do.  So for the LW1 term</div><div>I say "yes" to both eager loading and method consistency checking.</div><div><br class=""></div><div>If we can find a way to be explicit about nullability in value type descriptors,</div><div>then I think we can keep the rest of the L-world descriptor design.</div><div>The conversation (post LW1) which I see queuing up is whether to</div><div>go back to Q-types (or some analog) as explicitly non-nullable value</div><div>type descriptors, or whether to use some other "channel" to convey</div><div>the nullness information when it differs from some defined background</div><div>setting.  I think that conversation hinges, in part, on how useful it is</div><div>to change the meaning of LFoo; to be contextually determined as a</div><div>value type, vs. just being plain with QFoo;.  Our experiments with</div><div>a live LW1 prototype will help us scope this out.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Some aspects of the implementation complexity that we have identified so far:<br class="">a) At method resolution time, if there is a mismatch in value type consistency between the declaring class and the actual<br class="">type in the signature, then there is also a mismatch in all classes that have overridden the current method. This is particularly<br class="">painful with default methods in interfaces.<br class=""></div></div></blockquote><div><br class=""></div><div>For LW1 we can insist that all the methods agree.  This is a brittle state</div><div>of affairs which we will (almost certainly) need to make more flexible</div><div>with on-the-fly adapter generation.  One key question post LW1 is</div><div>what design choices will make adapter generation less pervasive.</div><div>Personally, I hope we'll find a way to require adapters for a small</div><div>minority of calls, all related to partially executed migrations.  This</div><div>is one reason I'm eager to avoid going back to Q-types, since those</div><div>seem to require a relatively large number of adapters.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">b) We need to ensure that we catch all method resolution, through all of the alternate accessor paths, including MethodHandles, VarHandles,<br class="">Reflection, JNI, so that we catch both the specification and implementation changes.<br class=""></div></div></blockquote><div><br class=""></div><div>Yes.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">c) Our favorite, invokespecial ACC_SUPER, needs special handling, since it performs selection which is not based on overriding, but based on virtually re-resolving.<br class=""></div></div></blockquote><div><br class=""></div>Charming.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">d) Pass by value calling convention optimizations depend on loading the actual type. Loading of the parameter types on first method resolution implies that if the caller is compiled, the caller method requires deoptimization/recompilation to pass arguments by value for future calls, which is a performance cost.<br class=""></div></div></blockquote><div><br class=""></div><div>I don't think it will pan out.  It's less invasive than deferred loading of field</div><div>types, but it's still invasive to change the calling sequence of a v-table slot.</div><div><br class=""></div><div>One design heuristic here is that fields and v-table slots are often subject</div><div>to parallel constraints.  This is true when binding physical variables (memory</div><div>locations, argument registers), and also true when creating specializations</div><div>(in our future template classes).</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">e) If we modify the specification to allow eager loading, and save errors to throw at method resolution, we need to work through the JVMS question of which errors would be saved (e.g. OOME, SOE might be thrown as part of the implementation vs. saving LinkageError), as well as designing a new implementation mechanism to repeat exceptions relative to signatures used for method resolution.<br class=""></div></div></blockquote><div><br class=""></div><div>I hope that if there is a need to telegraph a failure from loading or</div><div>preparation phases to the resolution phase, then a simple bit will</div><div>do, rather than a saved exception.  Except, of course, for quality</div><div>of service concerns; in that case a resolution-time error that stems</div><div>from a deferred value-type check could be given a getCause</div><div>of the earlier exception.  But, yes, this may require JVMS work.</div><div><br class=""></div><div>— John</div></div></body></html>