From Tobi_Ajila at ca.ibm.com Fri Jul 6 15:38:56 2018 From: Tobi_Ajila at ca.ibm.com (Tobi Ajila) Date: Fri, 6 Jul 2018 11:38:56 -0400 Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> Message-ID: I would like to propose an alternative strategy, one that would effectively provide the same consistency checks outlined in http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf without requiring eager loading of value types (VT) in the return/args of methods during the preparation phase. This is born out of our experience with PackedObjects which took a very similar approach to the ValueTypes attribute. This proposal makes use of the existing ValueTypes attribute. In addition, it requires that each classloader keeps a registry of ?expected? VTs. Proposal -------------------------- The following steps occur in the loading phase: 1. Prior to loading the current class each type in the ValueTypes attribute is checked see if it is loaded. If it is, the type must be a VT or ICCE is thrown. Otherwise, the type is registered with the initiating classloaders expected VT registry (EVTR). 2. Pre-loading of ACC_FLATTENABLE instance fields follow the same rules as the ones specified in Karen's proposal. 3. Prior to loading the current class, if the current class is a VT it must be in the classloader's EVTR or ICCE is thrown. If the current class is not a VT and does appear in the EVTR, ICCE is thrown. In link phase prior to preparation: - Same as Karen's static field rules, "static fields declared with the ACC_FLATTENABLE flag set have their type pre-loaded..." In preparation phase: - Same as Karen's method overriding rules, "any method overriding needs to perform value type consistency checking between declarer of the overridden method ..." At resolution time: - Same as Karen?s CONSTANT_Class, field and method resolution rules --------------------------- The benefit of this approach is that as soon as anyone believes a class is a VT, it must be loaded as a VT or it fails. As a result, there is no inconsistency of loaded VTs. This proposal doesn't guard against cases where a class was not expecting a method return/arg type to be a VT but then later on turned out to be a VT when it was resolved. However, I think don?t think Karen?s proposal offered these guarantees either. > Some aspects of the implementation complexity that we have identified so far: > a) At method resolution time, if there is a mismatch in value type consistency > between the declaring class and the actual type in the signature, then there > is also a mismatch in all classes that have overridden the current method. > This is particularly painful with default methods in interfaces. With this proposal the only possible inconsistency here is: Method has a return/arg type that is believed to not be a VT but turns out to be a VT. In this case any compiled code is doing pass by reference calling convention which works for both VT and non-VT types. > b) We need to ensure that we catch all method resolution, through all of the > alternate accessor paths, including MethodHandles, VarHandles, Reflection, JNI, > so that we catch both the specification and implementation changes. All these cases are covered with the class loading consistency checks (EVTR). > 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. same as above > 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. This wouldn?t be required in this proposal > 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. Typically, a method is run a few times before it is compiled (perhaps I?m making implementation assumptions?). At this stage, the return/arg types are either loaded or they are always null. This seems to suggest that deoptimization/recompilation scenario would not be a common occurrence. --Tobi > From: Karen Kinnear > To: valhalla-spec-experts > Date: 2018/06/26 10:32 AM > Subject: EG help please with getting to LW1 re: Value Types > Consistency Checking > Sent by: "valhalla-spec-experts" bounces at openjdk.java.net> > > Summary: Could we please allow eager loading for value types in the > locally declared method signatures > prior to preparation for LW1? > > Without that we seriously risk being able to offer an LW1 early > access binary for the JVMLS. > We believe it is more important to get this into people?s hands for > experimentation and feedback than > to delay the eager loading at this time. > > Details: > At our EG discussion on June 20, 2018, we discussed the proposal for > Value Types Consistency checking > at http://cr.openjdk.java.net/~acorn/value-types-consistency- > checking-details.pdf > > Part of the proposal for checking value type consistency relative to > the actual type > was for locally declared methods. The proposal was to check the > value types in arguments/return type > before preparation of the declaring class. > > During the meeting, there was a request to explore whether we could either: > 1) delay checking the value type consistency until an attempt to > resolve the method for invocation, or > 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. > > My understanding is that the goals of this are two-fold: > 1) if the method is never called, the rest of the code will continue to run > 2) reduce eager loading > > We have started this investigation, and there is non-trivial > complexity in implementing either of these approaches, > and we would like more time to explore how to make this possible, > after making LW1 available. > > Some aspects of the implementation complexity that we have identified so far: > a) At method resolution time, if there is a mismatch in value type > consistency between the declaring class and the actual > type in the signature, then there is also a mismatch in all classes > that have overridden the current method. This is particularly > painful with default methods in interfaces. > b) We need to ensure that we catch all method resolution, through > all of the alternate accessor paths, including MethodHandles, VarHandles, > Reflection, JNI, so that we catch both the specification and > implementation changes. > 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. > 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. > 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. > > thanks, > Karen From john.r.rose at oracle.com Sat Jul 7 21:08:27 2018 From: john.r.rose at oracle.com (John Rose) Date: Sat, 7 Jul 2018 14:08:27 -0700 Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> Message-ID: Hi Tobi. Thanks for the write-up. To be brief, your proposed technique will seems to require lazier selection of calling sequences than what Karen proposed. Argument and return registers cannot be assigned to values if their size is unknown, which is the case before they are loaded. The JVM must wait as late as the first actual call (with non-null parameters) to determine calling sequences. Karen's proposal allows calling sequences to be determined at preparation (v-table pack) time, while yours requires them to be chosen much later, by the time of the first invocation of a given v-table slot. (For JVMs without vtables, a "v-table slot" really means an equivalence class of CONSTANT_[I*]Methodrefs equated by the transitive closure of override relations.) The bytecode instruction just before that invocation might have been a defaultvalue instruction on a previously unloaded class. This means the JVM needs to install traps in unused v-table slots, so it can decide calling sequences. Karen's proposal, therefore, has the advantage of allowing the JVM more lead time freedom to set up v-table calling sequences, at preparation time. Yours requires just-in-time assignment of calling sequences, which seems more difficult. This leads to the question, what advantage did you find, with Packed Objects, from making calling sequence setup lazier? (I'm assuming that system scalarized arguments into multiple registers.) In other words, why is your phasing of the checks better than Karen's? ? John P.S. Background: So we are extending object references (Ljava/lang/Object;) to cover references to values also, at least in L-world. This gives a simple story for the interpreter and a fallback for less-optimized JIT-compiled code, but isn't enough to compete with statically-compiled languages. So the new requirement here is to make it possible for compiled calling sequences to use specialized representations for value parameters and returns. In particular, we often wish to use one or more machine registers to hold scalarized fields, and we wish to exclude null values (which require an extra encoding and impede some optimizations). A secondary requirement is that we wish to pick the compiled calling sequence once and not have to revise it. This implies picking the calling sequence no later than the first execution (compiled or interpreted) of any particular method, and getting it right the first time. Deoptimization of calling sequences?across override-trees of methods?is a trick we are holding in reserve, but it seems a risky research project rather than an understood technique. I think deoptimization at this scale hasn't been proven efficient yet, although it may be. It seems that in order to flatten, we are obligated to load value types more eagerly than object types. Value types can't "hide behind" a polymorphic reference; any user of a value type in its native form (not boxed) needs to "see" its complete field list, which requires loading the classfile. This is certainly true for object layout, where an object that contains a value-typed field must load that value type to see how much space it must reserve for it, in that object's flattened and packed layout. Given that we are going to routinely pre-load value type classfiles, it is reasonable to apply this technique in other places besides the layout of instances and fields. In particular, the layout of calling sequences is in many ways closely analogous to the layout of instances. (There is a deep symmetry between calls and objects, arising perhaps from the fact that function applications are isomorphic to curried functions or tuples. In any case, it seems to me that some such symmetry crops up between the O-O notions of field extension and virtual method extension, and so in JVM's treatment of object layout vs. its treatment of virtual dispatch, both of which are examined carefully at loading and preparation time, before execution.) Anyway, if we are going to preload field classes, it is no great additional burden to preload argument classes too, if an appropriate signal can be defined (the VT list). It might even be reasonable to preload *all* VTs mentioned in the list, just to make the preloading process simpler and more predictable. I'm looking for reasons that this is a *bad* idea, so we can say in the end, "here's exactly why we had to make the loading logic for VTs so tricky"?if we must. On Jul 6, 2018, at 8:38 AM, Tobi Ajila wrote: > > I would like to propose an alternative strategy, one that would effectively provide the same consistency checks outlined in http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf without requiring eager loading of value types (VT) in the return/args of methods during the preparation phase. This is born out of our experience with PackedObjects which took a very similar approach to the ValueTypes attribute. > > This proposal makes use of the existing ValueTypes attribute. In addition, it requires that each classloader keeps a registry of ?expected? VTs. > > Proposal > -------------------------- > The following steps occur in the loading phase: > > 1. Prior to loading the current class each type in the ValueTypes attribute is checked see if it is loaded. If it is, the type must be a VT or ICCE is thrown. Otherwise, the type is registered with the initiating classloaders expected VT registry (EVTR). > > 2. Pre-loading of ACC_FLATTENABLE instance fields follow the same rules as the ones specified in Karen's proposal. > > 3. Prior to loading the current class, if the current class is a VT it must be in the classloader's EVTR or ICCE is thrown. If the current class is not a VT and does appear in the EVTR, ICCE is thrown. > > In link phase prior to preparation: > - Same as Karen's static field rules, "static fields declared with the ACC_FLATTENABLE flag set have their type pre-loaded..." > > In preparation phase: > - Same as Karen's method overriding rules, "any method overriding needs to perform value type consistency checking between declarer of the overridden method ..." > > At resolution time: > - Same as Karen?s CONSTANT_Class, field and method resolution rules > --------------------------- > > The benefit of this approach is that as soon as anyone believes a class is a VT, it must be loaded as a VT or it fails. As a result, there is no inconsistency of loaded VTs. This proposal doesn't guard against cases where a class was not expecting a method return/arg type to be a VT but then later on turned out to be a VT when it was resolved. However, I think don?t think Karen?s proposal offered these guarantees either. > > > Some aspects of the implementation complexity that we have identified so far: > > a) At method resolution time, if there is a mismatch in value type consistency > > between the declaring class and the actual type in the signature, then there > > is also a mismatch in all classes that have overridden the current method. > > This is particularly painful with default methods in interfaces. > > With this proposal the only possible inconsistency here is: > Method has a return/arg type that is believed to not be a VT but turns out to be a VT. In this case any compiled code is doing pass by reference calling convention which works for both VT and non-VT types. > > > b) We need to ensure that we catch all method resolution, through all of the > > alternate accessor paths, including MethodHandles, VarHandles, Reflection, JNI, > > so that we catch both the specification and implementation changes. > > All these cases are covered with the class loading consistency checks (EVTR). > > > 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. > > same as above > > > 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. > > This wouldn?t be required in this proposal > > > 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. > > Typically, a method is run a few times before it is compiled (perhaps I?m making implementation assumptions?). At this stage, the return/arg types are either loaded or they are always null. This seems to suggest that deoptimization/recompilation scenario would not be a common occurrence. > > > --Tobi > > > From: Karen Kinnear > > To: valhalla-spec-experts > > Date: 2018/06/26 10:32 AM > > Subject: EG help please with getting to LW1 re: Value Types > > Consistency Checking > > Sent by: "valhalla-spec-experts" > bounces at openjdk.java.net> > > > > Summary: Could we please allow eager loading for value types in the > > locally declared method signatures > > prior to preparation for LW1? > > > > Without that we seriously risk being able to offer an LW1 early > > access binary for the JVMLS. > > We believe it is more important to get this into people?s hands for > > experimentation and feedback than > > to delay the eager loading at this time. > > > > Details: > > At our EG discussion on June 20, 2018, we discussed the proposal for > > Value Types Consistency checking > > at http://cr.openjdk.java.net/~acorn/value-types-consistency- > > checking-details.pdf > > > > Part of the proposal for checking value type consistency relative to > > the actual type > > was for locally declared methods. The proposal was to check the > > value types in arguments/return type > > before preparation of the declaring class. > > > > During the meeting, there was a request to explore whether we could either: > > 1) delay checking the value type consistency until an attempt to > > resolve the method for invocation, or > > 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. > > > > My understanding is that the goals of this are two-fold: > > 1) if the method is never called, the rest of the code will continue to run > > 2) reduce eager loading > > > > We have started this investigation, and there is non-trivial > > complexity in implementing either of these approaches, > > and we would like more time to explore how to make this possible, > > after making LW1 available. > > > > Some aspects of the implementation complexity that we have identified so far: > > a) At method resolution time, if there is a mismatch in value type > > consistency between the declaring class and the actual > > type in the signature, then there is also a mismatch in all classes > > that have overridden the current method. This is particularly > > painful with default methods in interfaces. > > b) We need to ensure that we catch all method resolution, through > > all of the alternate accessor paths, including MethodHandles, VarHandles, > > Reflection, JNI, so that we catch both the specification and > > implementation changes. > > 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. > > 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. > > 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. > > > > thanks, > > Karen From karen.kinnear at oracle.com Mon Jul 9 18:50:31 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Mon, 9 Jul 2018 14:50:31 -0400 Subject: Valhalla EG Notes June 20, 2018 In-Reply-To: References: <4521AAF1-AA57-425E-8A0E-24080E107441@oracle.com> Message-ID: <564B3354-3733-4775-8D56-11B23D2B9998@oracle.com> Many thanks for checking Dan and agreeing that this needs a spec fix. Working on moving that forward. thanks, Karen > On Jul 6, 2018, at 11:26 AM, Daniel Heidinga wrote: > > > AI: Karen - double check potential JVMTI bug > > I checked our code base for this and we have the same behaviour. Would be good to get this fixed at the spec level. > > --Dan > > ----- Original message ----- > From: Karen Kinnear > Sent by: "valhalla-spec-experts" > To: valhalla-spec-experts > Cc: > Subject: Valhalla EG Notes June 20, 2018 > Date: Fri, Jun 29, 2018 6:36 PM > > NO meeting July 4th, 2018 - US Independence day holiday. Next Meeting July 18th. > Karen will be on vacation week of July 18th - looking for a volunteer to run the meeting please. > > AIs: > All: review Nestmates GetNestHost minor rewording of javadoc > All: review Value Type Consistency Checking proposal: > http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf > All: see follow-up request - please approve LW1 temporary static method consistency checking before preparation, to be revisited: > http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2018-June/000717.html > > Karen: update Value Types Consistency Checking proposal with BootStrapMethod info > > attendees: John, Dan S, Tobias, Dan H, Frederic, Remi, Karen > > I. Nestmates: > Please review GetNestHost minor javadoc request > > II. Condy > Remi: when will javac use condy for constant lambdas? > Dan S: some experiments have been done, would like to do this, no timeframe yet > Condy next step: not require Looking and Name&Type argument > Remi: ElasticSearch guy: indy metafactory not do all the needed casting - works for java but not for scala and other languages - will dig and find > > III. Value Types > > 1. Equals/Hashcode/toString > Remi - saw initial prototype implementation > - two different approaches - Records in Amber vs. Valhalla > Remi has a version he could clean up and offer for all us to use - weave custom MethodHandles for each type > John: using loop combinators? > Remi - try not to > John: good - love to see it > > ** follow-on email > (many thanks Remi!) > > 2. Value Types Consistency Checking proposal > Karen walked through overview > > Summary: > Two types of checks > 1. Value Types attribute vs. reality > 2. Value Types attribute of two different classes - e.g. caller-callee > > Users of Value Types attribute: > 1. verifier (with no loading) - catching mismatched bytecode usage > 2. optimizations > > Goal: avoid eager loading > > Terminology: > pre-load: load before completing load of containing class > - analogous to supertype handling > - only proposed for flattenable instance fields, information needed for layout > - risk of circularity > eager loading: loading at other times - e.g. linking, preparation, etc. > > Proposed checking against reality: > > 1. instance fields (all flattenable in LW1) - pre-loaded: test vs. real > 2. flattenable static fields - link phase, prior to preparation (post-LW1): test vs. real > 3. local methods: prior to preparation check all (in ValueTypes attribute or not) parameters/return vs. real > 4. CONSTANT_Class resolution: for all classes (in ValueTypes attribute or not)test vs. real > > Proposed checking inter-class consistency > 5. Preparation (selection cache creation): method declarer vs. method overrider consistency > 6. Field or Method Resolution: For all types in signatures, check caller-callee consistency > Note: these checks should essentially match where loader constraint checks are performed today. > Note: all the inter-class consistency checks check all the signature types, whether or not they are in the Value Types attribute > > Remi: if a method is never called, why load parameters? > Tobi: why not load one first invocation? > John: if load before call - add a new barrier. > - challenge with overriding hierarchy - deopt - sudden unpredictable performance drop > - preparation is better than 1st call > Karen: note: if there is a null on the stack, they might not have loaded a parameter at first call > Frederic: Overriding example > A.m, B.m, C.m > if A is correct, B is incorrect, C is maybe wrong > - body of the local method may be incorrect > Remi: if the super type is correct but the subtype is not > Karen: preparation checks are NOT vs. the real type - they just check overrider/overridden - they could both be wrong and pass that check > Frederic: This is more complex with interfaces > Dan H: if never call method, want to continue to run, throw an exception when realize inconsistency > Dan S: alternative - hotspot implementation could perform the check early and cache and throw the exception at first invocation > > AI: Karen - investigate possibilities including either delaying checking or offering the option to check earlier but delay throwing any exceptions > ed. note - sent follow-up email: started the exploration - too complex for LW1 timeframe - asked for approval to keep proposal > for now and revisit after we get early access binaries into people?s hands > > John: Constant_Class resolution - need to also check BootStrapMethod evaluation for indy and condy - spec says ?as if by ldc?. > > Karen: Issue 1: Note that it is possible for class A to declare a field of V, not know it is a value type, and class C to also not know > and to store null in the field, because field resolution only checks between the caller-callee, not reality. > Folks were ok with letting this work. > > III. Static fields - flattenability > > Karen summarized some of the issues and options outlined in the Value Types Consistency Checking: > > - risk of circularity errors if we pre-load static fields that are (flattenable) value types. Since there is a requirement to allow > a static field to contain an instance of the container type, we obviously can not pre-load. > > - Preparation time issues: > - Preparation is prior to class initialization > - challenge in creating a default value instance of a class which has not yet been initialized > - theory is that you can?t actually get to the static without initializing the class > > choices: > 1. trigger class initialization early > 2. prevent a leak > > John: bytecodes and MH-like bytecodes know how to make a default instance before class initialization > > Note: there is a risk of the default value instance escaping prior to initialization > ? e.g. JVMTI - maybe spec bug - getFieldIDs/getMethodIDs - require a class to be prepared - should require a class to be initialized > (since the jfieldIDs/jmethodIDs will be used by JNI which requires the class to be initialized, and the getField/getStatic etc. JNI > methods do NOT ensure this for performance). This is a bug. > > ? JLS is explicit about hole during that allows the initializer to create an instance of itself and publish it for external view > - this is an actual problem > > - Note that once the instance escapes - there are no class initialization barriers on bytecodes for instances - it is assumed that these > are caught at ?new? or ?defaultvalue? > > Remi: agree with John - go ahead and initialize during preparation to a default value and do not trigger class initialization > > Dan S: prefer get static trigger class initialization rather than preparation > > John: concern about circularities for class initialization > Karen: circularities - only for class loading, not for initialization - logic explicitly allows same thread to ?successfully? initialize if already > in initialization > > Karen: class initialization of a container should trigger class initialization of all flattenable fields > > John: any additional class initialization barriers for hiding default - e.g. anewarray > Preparation essentially creates storage, > > AI: Karen - double check potential JVMTI bug > > Corrections welcome, > thanks, > Karen > > > > > > > > > > From forax at univ-mlv.fr Tue Jul 10 09:43:58 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 10 Jul 2018 11:43:58 +0200 (CEST) Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> Message-ID: <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> Hi all, > De: "John Rose" > ?: "Tobi Ajila" > Cc: "valhalla-spec-experts" > Envoy?: Samedi 7 Juillet 2018 23:08:27 > Objet: Re: EG help please with getting to LW1 re: Value Types Consistency > Checking > Hi Tobi. Thanks for the write-up. > To be brief, your proposed technique will seems to require lazier selection of > calling > sequences than what Karen proposed. Argument and return registers cannot be > assigned > to values if their size is unknown, which is the case before they are loaded. > The JVM > must wait as late as the first actual call (with non-null parameters) to > determine calling > sequences. > Karen's proposal allows calling sequences to be determined at preparation > (v-table pack) > time, while yours requires them to be chosen much later, by the time of the > first invocation > of a given v-table slot. (For JVMs without vtables, a "v-table slot" really > means an > equivalence class \u0015of CONSTANT_[I*]Methodrefs equated by the transitive > closure of > override relations.) The bytecode instruction just before that invocation might > have been > a defaultvalue instruction on a previously unloaded class. This means the JVM > needs > to install traps in unused v-table slots, so it can decide calling sequences. > Karen's proposal, therefore, has the advantage of allowing the JVM more lead > time > freedom to set up v-table calling sequences, at preparation time. Yours requires > just-in-time assignment of calling sequences, which seems more difficult. > This leads to the question, what advantage did you find, with Packed Objects, > from > making calling sequence setup lazier? (I'm assuming that system scalarized > arguments > into multiple registers.) In other words, why is your phasing of the checks > better than > Karen's? > ? John > P.S. Background: > So we are extending object references (Ljava/lang/Object;) to cover references > to values > also, at least in L-world. This gives a simple story for the interpreter and a > fallback for > less-optimized JIT-compiled code, but isn't enough to compete with > statically-compiled > languages. > So the new requirement here is to make it possible for compiled calling > sequences > to use specialized representations for value parameters and returns. In > particular, we > often wish to use one or more machine registers to hold scalarized fields, and > we wish > to exclude null values (which require an extra encoding and impede some > optimizations). > A secondary requirement is that we wish to pick the compiled calling sequence > once > and not have to revise it. This implies picking the calling sequence no later > than the first > execution (compiled or interpreted) of any particular method, and getting it > right the first > time. > Deoptimization of calling sequences?across override-trees of methods?is a trick > we are > holding in reserve, but it seems a risky research project rather than an > understood technique. > I think deoptimization at this scale hasn't been proven efficient yet, although > it may be. > It seems that in order to flatten, we are obligated to load value types more > eagerly > than object types. Value types can't "hide behind" a polymorphic reference; any > user of a value type in its native form (not boxed) needs to "see" its complete > field > list, which requires loading the classfile. This is certainly true for object > layout, > where an object that contains a value-typed field must load that value type to > see > how much space it must reserve for it, in that object's flattened and packed > layout. > Given that we are going to routinely pre-load value type classfiles, it is > reasonable > to apply this technique in other places besides the layout of instances and > fields. > In particular, the layout of calling sequences is in many ways closely analogous > to the layout of instances. (There is a deep symmetry between calls and objects, > arising perhaps from the fact that function applications are isomorphic to > curried > functions or tuples. In any case, it seems to me that some such symmetry crops > up between the O-O notions of field extension and virtual method extension, and > so in JVM's treatment of object layout vs. its treatment of virtual dispatch, > both of > which are examined carefully at loading and preparation time, before execution.) The symmetry is only true for immutable class. The main difference is that curried functions usually doesn't expose the value of the bounded parameters while tuples let you access to those values. > Anyway, if we are going to preload field classes, it is no great additional > burden to > preload argument classes too, if an appropriate signal can be defined (the VT > list). > It might even be reasonable to preload *all* VTs mentioned in the list, just to > make > the preloading process simpler and more predictable. I'm looking for reasons > that > this is a *bad* idea, so we can say in the end, "here's exactly why we had to > make > the loading logic for VTs so tricky"?if we must. I think the answer to the question of lazy loading of method parameter types is rooted to the question of what is a value type exactly for Java. Is it an optimization, a first class concept i.e one that should work as if it was integrated in the language from the beginning ? The other problem is the more we diverge from the class behavior, the harder it will be to allow a class to become a value type. I firmly believe that value type should be first class because they are useless in a lot of scenario if they are not. The main limitation of a value type is its immutable characteristic, what save them from uselessness is that their creation cost should be zero or very close to zero alleviating the burden of think in term of object creation and making us, developers, free to use functional idioms. With that in mind, i believe a value type should not be "boxed" because it's not loaded yet (it can still be boxed due to separate compilation but that's another story) so value type present in method descriptor should be loaded eagerly. About loading all value type of the attribute ValueTypes, from one side Java has a strong tradition to not pay for the code you do not use. This power today's applications, an average application has an hundred jars as dependencies, if all value types are preloaded it's at waste of memory and cpu cycles. BTW, it's also what's make jaotc useless in its current incarnation because it AOTs things your application don't care. R?mi > On Jul 6, 2018, at 8:38 AM, Tobi Ajila < [ mailto:Tobi_Ajila at ca.ibm.com | > Tobi_Ajila at ca.ibm.com ] > wrote: >> I would like to propose an alternative strategy, one that would effectively >> provide the same consistency checks outlined in [ >> http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf >> | >> http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf >> ] without requiring eager loading of value types (VT) in the return/args of >> methods during the preparation phase. This is born out of our experience with >> PackedObjects which took a very similar approach to the ValueTypes attribute. >> This proposal makes use of the existing ValueTypes attribute. In addition, it >> requires that each classloader keeps a registry of ?expected? VTs. >> Proposal >> -------------------------- >> The following steps occur in the loading phase: >> 1. Prior to loading the current class each type in the ValueTypes attribute is >> checked see if it is loaded. If it is, the type must be a VT or ICCE is thrown. >> Otherwise, the type is registered with the initiating classloaders expected VT >> registry (EVTR). >> 2. Pre-loading of ACC_FLATTENABLE instance fields follow the same rules as the >> ones specified in Karen's proposal. >> 3. Prior to loading the current class, if the current class is a VT it must be >> in the classloader's EVTR or ICCE is thrown. If the current class is not a VT >> and does appear in the EVTR, ICCE is thrown. >> In link phase prior to preparation: >> - Same as Karen's static field rules, "static fields declared with the >> ACC_FLATTENABLE flag set have their type pre-loaded..." >> In preparation phase: >> - Same as Karen's method overriding rules, "any method overriding needs to >> perform value type consistency checking between declarer of the overridden >> method ..." >> At resolution time: >> - Same as Karen?s CONSTANT_Class, field and method resolution rules >> --------------------------- >> The benefit of this approach is that as soon as anyone believes a class is a VT, >> it must be loaded as a VT or it fails. As a result, there is no inconsistency >> of loaded VTs. This proposal doesn't guard against cases where a class was not >> expecting a method return/arg type to be a VT but then later on turned out to >> be a VT when it was resolved. However, I think don?t think Karen?s proposal >> offered these guarantees either. >> > Some aspects of the implementation complexity that we have identified so far: >> > a) At method resolution time, if there is a mismatch in value type consistency >> > between the declaring class and the actual type in the signature, then there >> > is also a mismatch in all classes that have overridden the current method. >> > This is particularly painful with default methods in interfaces. >> With this proposal the only possible inconsistency here is: >> Method has a return/arg type that is believed to not be a VT but turns out to be >> a VT. In this case any compiled code is doing pass by reference calling >> convention which works for both VT and non-VT types. >> > b) We need to ensure that we catch all method resolution, through all of the >> > alternate accessor paths, including MethodHandles, VarHandles, Reflection, JNI, >> > so that we catch both the specification and implementation changes. >> All these cases are covered with the class loading consistency checks (EVTR). >> > 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. >> same as above >> > 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. >> This wouldn?t be required in this proposal >> > 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. >> Typically, a method is run a few times before it is compiled (perhaps I?m making >> implementation assumptions?). At this stage, the return/arg types are either >> loaded or they are always null. This seems to suggest that >> deoptimization/recompilation scenario would not be a common occurrence. >> --Tobi >>> From: Karen Kinnear < [ mailto:karen.kinnear at oracle.com | >> > karen.kinnear at oracle.com ] > >>> To: valhalla-spec-experts < [ mailto:valhalla-spec-experts at openjdk.java.net | >> > valhalla-spec-experts at openjdk.java.net ] > >> > Date: 2018/06/26 10:32 AM >> > Subject: EG help please with getting to LW1 re: Value Types >> > Consistency Checking >> > Sent by: "valhalla-spec-experts" > > [ mailto:bounces at openjdk.java.net | bounces at openjdk.java.net ] > >> > Summary: Could we please allow eager loading for value types in the >> > locally declared method signatures >> > prior to preparation for LW1? >> > Without that we seriously risk being able to offer an LW1 early >> > access binary for the JVMLS. >> > We believe it is more important to get this into people?s hands for >> > experimentation and feedback than >> > to delay the eager loading at this time. >> > Details: >> > At our EG discussion on June 20, 2018, we discussed the proposal for >> > Value Types Consistency checking >>> at [ http://cr.openjdk.java.net/~acorn/value-types-consistency- | >> > http://cr.openjdk.java.net/~acorn/value-types-consistency- ] >> > checking-details.pdf >> > Part of the proposal for checking value type consistency relative to >> > the actual type >> > was for locally declared methods. The proposal was to check the >> > value types in arguments/return type >> > before preparation of the declaring class. >> > During the meeting, there was a request to explore whether we could either: >> > 1) delay checking the value type consistency until an attempt to >> > resolve the method for invocation, or >> > 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. >> > My understanding is that the goals of this are two-fold: >> > 1) if the method is never called, the rest of the code will continue to run >> > 2) reduce eager loading >> > We have started this investigation, and there is non-trivial >> > complexity in implementing either of these approaches, >> > and we would like more time to explore how to make this possible, >> > after making LW1 available. >> > Some aspects of the implementation complexity that we have identified so far: >> > a) At method resolution time, if there is a mismatch in value type >> > consistency between the declaring class and the actual >> > type in the signature, then there is also a mismatch in all classes >> > that have overridden the current method. This is particularly >> > painful with default methods in interfaces. >> > b) We need to ensure that we catch all method resolution, through >> > all of the alternate accessor paths, including MethodHandles, VarHandles, >> > Reflection, JNI, so that we catch both the specification and >> > implementation changes. >> > 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. >> > 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. >> > 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. >> > thanks, >> > Karen From forax at univ-mlv.fr Wed Jul 11 15:57:52 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 11 Jul 2018 17:57:52 +0200 (CEST) Subject: Anonymous value class ? Message-ID: <1539680827.223724.1531324672538.JavaMail.zimbra@u-pem.fr> While testing how value types can be used, i had to find workarounds around the fact that there is no way to create an anonymous value class using the compiler. If we follow the idea of having a classical constructor being transformed to a factory method, i think we should also allow anonymous value class. new __ByValue Object() { ... }; a synthetic factory $make$ being generated instead of a synthetic constructor. R?mi From brian.goetz at oracle.com Wed Jul 11 17:37:52 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 11 Jul 2018 13:37:52 -0400 Subject: Anonymous value class ? In-Reply-To: <1539680827.223724.1531324672538.JavaMail.zimbra@u-pem.fr> References: <1539680827.223724.1531324672538.JavaMail.zimbra@u-pem.fr> Message-ID: Seems a possibility. Let?s put this on the list, but right now we?re focusing on getting to a usable minimal implementation so we can gather usability and performance feedback. Language work to follow! > On Jul 11, 2018, at 11:57 AM, Remi Forax wrote: > > While testing how value types can be used, i had to find workarounds around the fact that there is no way to create an anonymous value class using the compiler. > > If we follow the idea of having a classical constructor being transformed to a factory method, i think we should also allow anonymous value class. > new __ByValue Object() { > ... > }; > a synthetic factory $make$ being generated instead of a synthetic constructor. > > R?mi From Tobi_Ajila at ca.ibm.com Thu Jul 12 18:41:08 2018 From: Tobi_Ajila at ca.ibm.com (Tobi Ajila) Date: Thu, 12 Jul 2018 14:41:08 -0400 Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> Message-ID: > I'm looking for reasons that > this is a *bad* idea, so we can say in the end, "here's exactly why we had to make > the loading logic for VTs so tricky"?if we must. Karen's initial post mentions our two biggest concerns. If there is no guarantee that the VTs in the method descriptors will be used, loading them is an overhead. We would like to minimize the cost to startup as much as possible. The other reason is eager loading may trigger failures that would otherwise never occur if the method wasn't run, which is change from how the JVM normally behaves. --Tobi > From: Remi Forax > To: John Rose > Cc: Tobi Ajila , valhalla-spec-experts > > Date: 2018/07/10 05:44 AM > Subject: Re: EG help please with getting to LW1 re: Value Types > Consistency Checking > > Hi all, > > De: "John Rose" > ?: "Tobi Ajila" > Cc: "valhalla-spec-experts" > Envoy?: Samedi 7 Juillet 2018 23:08:27 > Objet: Re: EG help please with getting to LW1 re: Value Types > Consistency Checking > Hi Tobi. Thanks for the write-up. > > To be brief, your proposed technique will seems to require lazier > selection of calling > sequences than what Karen proposed. Argument and return registers > cannot be assigned > to values if their size is unknown, which is the case before they > are loaded. The JVM > must wait as late as the first actual call (with non-null > parameters) to determine calling > sequences. > > Karen's proposal allows calling sequences to be determined at > preparation (v-table pack) > time, while yours requires them to be chosen much later, by the time > of the first invocation > of a given v-table slot. (For JVMs without vtables, a "v-table > slot" really means an > equivalence class \u0015of CONSTANT_[I*]Methodrefs equated by the > transitive closure of > override relations.) The bytecode instruction just before that > invocation might have been > a defaultvalue instruction on a previously unloaded class. This > means the JVM needs > to install traps in unused v-table slots, so it can decide calling sequences. > > Karen's proposal, therefore, has the advantage of allowing the JVM > more lead time > freedom to set up v-table calling sequences, at preparation time. > Yours requires > just-in-time assignment of calling sequences, which seems more difficult. > > This leads to the question, what advantage did you find, with Packed > Objects, from > making calling sequence setup lazier? (I'm assuming that system > scalarized arguments > into multiple registers.) In other words, why is your phasing of > the checks better than > Karen's? > > ? John > > P.S. Background: > > So we are extending object references (Ljava/lang/Object;) to cover > references to values > also, at least in L-world. This gives a simple story for the > interpreter and a fallback for > less-optimized JIT-compiled code, but isn't enough to compete with > statically-compiled > languages. > > So the new requirement here is to make it possible for compiled > calling sequences > to use specialized representations for value parameters and returns. > In particular, we > often wish to use one or more machine registers to hold scalarized > fields, and we wish > to exclude null values (which require an extra encoding and impede > some optimizations). > > A secondary requirement is that we wish to pick the compiled calling > sequence once > and not have to revise it. This implies picking the calling > sequence no later than the first > execution (compiled or interpreted) of any particular method, and > getting it right the first > time. > > Deoptimization of calling sequences?across override-trees of > methods?is a trick we are > holding in reserve, but it seems a risky research project rather > than an understood technique. > I think deoptimization at this scale hasn't been proven efficient > yet, although it may be. > > It seems that in order to flatten, we are obligated to load value > types more eagerly > than object types. Value types can't "hide behind" a polymorphic > reference; any > user of a value type in its native form (not boxed) needs to "see" > its complete field > list, which requires loading the classfile. This is certainly true > for object layout, > where an object that contains a value-typed field must load that > value type to see > how much space it must reserve for it, in that object's flattened > and packed layout. > > Given that we are going to routinely pre-load value type classfiles, > it is reasonable > to apply this technique in other places besides the layout of > instances and fields. > In particular, the layout of calling sequences is in many ways > closely analogous > to the layout of instances. (There is a deep symmetry between calls > and objects, > arising perhaps from the fact that function applications are > isomorphic to curried > functions or tuples. In any case, it seems to me that some such > symmetry crops > up between the O-O notions of field extension and virtual method > extension, and > so in JVM's treatment of object layout vs. its treatment of virtual > dispatch, both of > which are examined carefully at loading and preparation time, before > execution.) > > The symmetry is only true for immutable class. The main difference > is that curried functions usually doesn't expose the value of the > bounded parameters while tuples let you access to those values. > > Anyway, if we are going to preload field classes, it is no great > additional burden to > preload argument classes too, if an appropriate signal can be > defined (the VT list). > It might even be reasonable to preload *all* VTs mentioned in the > list, just to make > the preloading process simpler and more predictable. I'm looking > for reasons that > this is a *bad* idea, so we can say in the end, "here's exactly why > we had to make > the loading logic for VTs so tricky"?if we must. > > I think the answer to the question of lazy loading of method > parameter types is rooted to the question of what is a value type > exactly for Java. > Is it an optimization, a first class concept i.e one that should > work as if it was integrated in the language from the beginning ? > The other problem is the more we diverge from the class behavior, > the harder it will be to allow a class to become a value type. > > I firmly believe that value type should be first class because they > are useless in a lot of scenario if they are not. The main > limitation of a value type is its immutable characteristic, what > save them from uselessness is that their creation cost should be > zero or very close to zero alleviating the burden of think in term > of object creation and making us, developers, free to use functional idioms. > With that in mind, i believe a value type should not be "boxed" > because it's not loaded yet (it can still be boxed due to separate > compilation but that's another story) so value type present in > method descriptor should be loaded eagerly. > > About loading all value type of the attribute ValueTypes, from one > side Java has a strong tradition to not pay for the code you do not > use. This power today's applications, an average application has an > hundred jars as dependencies, if all value types are preloaded it's > at waste of memory and cpu cycles. BTW, it's also what's make jaotc > useless in its current incarnation because it AOTs things your > application don't care. > > R?mi > > On Jul 6, 2018, at 8:38 AM, Tobi Ajila wrote: > > I would like to propose an alternative strategy, one that would > effectively provide the same consistency checks outlined in http:// > cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf > without requiring eager loading of value types (VT) in the return/ > args of methods during the preparation phase. This is born out of > our experience with PackedObjects which took a very similar approach > to the ValueTypes attribute. > > This proposal makes use of the existing ValueTypes attribute. In > addition, it requires that each classloader keeps a registry of > ?expected? VTs. > > Proposal > -------------------------- > The following steps occur in the loading phase: > > 1. Prior to loading the current class each type in the ValueTypes > attribute is checked see if it is loaded. If it is, the type must be > a VT or ICCE is thrown. Otherwise, the type is registered with the > initiating classloaders expected VT registry (EVTR). > > 2. Pre-loading of ACC_FLATTENABLE instance fields follow the same > rules as the ones specified in Karen's proposal. > > 3. Prior to loading the current class, if the current class is a VT > it must be in the classloader's EVTR or ICCE is thrown. If the > current class is not a VT and does appear in the EVTR, ICCE is thrown. > > In link phase prior to preparation: > - Same as Karen's static field rules, "static fields declared with > the ACC_FLATTENABLE flag set have their type pre-loaded..." > > In preparation phase: > - Same as Karen's method overriding rules, "any method overriding > needs to perform value type consistency checking between declarer of > the overridden method ..." > > At resolution time: > - Same as Karen?s CONSTANT_Class, field and method resolution rules > --------------------------- > > The benefit of this approach is that as soon as anyone believes a > class is a VT, it must be loaded as a VT or it fails. As a result, > there is no inconsistency of loaded VTs. This proposal doesn't guard > against cases where a class was not expecting a method return/arg > type to be a VT but then later on turned out to be a VT when it was > resolved. However, I think don?t think Karen?s proposal offered > these guarantees either. > > > Some aspects of the implementation complexity that we have > identified so far: > > a) At method resolution time, if there is a mismatch in value type > consistency > > between the declaring class and the actual type in the signature, > then there > > is also a mismatch in all classes that have overridden the current method. > > This is particularly painful with default methods in interfaces. > > With this proposal the only possible inconsistency here is: > Method has a return/arg type that is believed to not be a VT but > turns out to be a VT. In this case any compiled code is doing pass > by reference calling convention which works for both VT and non-VT types. > > > b) We need to ensure that we catch all method resolution, through > all of the > > alternate accessor paths, including MethodHandles, VarHandles, > Reflection, JNI, > > so that we catch both the specification and implementation changes. > > All these cases are covered with the class loading consistency checks (EVTR). > > > 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. > > same as above > > > 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. > > This wouldn?t be required in this proposal > > > 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. > > Typically, a method is run a few times before it is compiled > (perhaps I?m making implementation assumptions?). At this stage, the > return/arg types are either loaded or they are always null. This > seems to suggest that deoptimization/recompilation scenario would > not be a common occurrence. > > > --Tobi > > > From: Karen Kinnear > > To: valhalla-spec-experts > > Date: 2018/06/26 10:32 AM > > Subject: EG help please with getting to LW1 re: Value Types > > Consistency Checking > > Sent by: "valhalla-spec-experts" > bounces at openjdk.java.net> > > > > Summary: Could we please allow eager loading for value types in the > > locally declared method signatures > > prior to preparation for LW1? > > > > Without that we seriously risk being able to offer an LW1 early > > access binary for the JVMLS. > > We believe it is more important to get this into people?s hands for > > experimentation and feedback than > > to delay the eager loading at this time. > > > > Details: > > At our EG discussion on June 20, 2018, we discussed the proposal for > > Value Types Consistency checking > > at http://cr.openjdk.java.net/~acorn/value-types-consistency- > > checking-details.pdf > > > > Part of the proposal for checking value type consistency relative to > > the actual type > > was for locally declared methods. The proposal was to check the > > value types in arguments/return type > > before preparation of the declaring class. > > > > During the meeting, there was a request to explore whether we could either: > > 1) delay checking the value type consistency until an attempt to > > resolve the method for invocation, or > > 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. > > > > My understanding is that the goals of this are two-fold: > > 1) if the method is never called, the rest of the code will continue to run > > 2) reduce eager loading > > > > We have started this investigation, and there is non-trivial > > complexity in implementing either of these approaches, > > and we would like more time to explore how to make this possible, > > after making LW1 available. > > > > Some aspects of the implementation complexity that we have > identified so far: > > a) At method resolution time, if there is a mismatch in value type > > consistency between the declaring class and the actual > > type in the signature, then there is also a mismatch in all classes > > that have overridden the current method. This is particularly > > painful with default methods in interfaces. > > b) We need to ensure that we catch all method resolution, through > > all of the alternate accessor paths, including MethodHandles, VarHandles, > > Reflection, JNI, so that we catch both the specification and > > implementation changes. > > 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. > > 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. > > 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. > > > > thanks, > > Karen > From john.r.rose at oracle.com Thu Jul 12 19:02:02 2018 From: john.r.rose at oracle.com (John Rose) Date: Thu, 12 Jul 2018 12:02:02 -0700 Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> Message-ID: <017CF66A-7029-4364-8025-47FE5861BA67@oracle.com> Thanks, Tobi and Remi, for the helpful observations. On Jul 10, 2018, at 2:43 AM, Remi Forax wrote: > > I think the answer to the question of lazy loading of method parameter types is rooted to the question of what is a value type exactly for Java. > Is it an optimization, a first class concept i.e one that should work as if it was integrated in the language from the beginning ? > The other problem is the more we diverge from the class behavior, the harder it will be to allow a class to become a value type. > > I firmly believe that value type should be first class because they are useless in a lot of scenario if they are not. The main limitation of a value type is its immutable characteristic, what save them from uselessness is that their creation cost should be zero or very close to zero alleviating the burden of think in term of object creation and making us, developers, free to use functional idioms. > With that in mind, i believe a value type should not be "boxed" because it's not loaded yet (it can still be boxed due to separate compilation but that's another story) so value type present in method descriptor should be loaded eagerly. So value types should diverge from object types enough to allow accurate unboxing in hot paths. But they should not diverge more than necessary. That means no eager loading that's not needed. > About loading all value type of the attribute ValueTypes, from one side Java has a strong tradition to not pay for the code you do not use. This power today's applications, an average application has an hundred jars as dependencies, if all value types are preloaded it's at waste of memory and cpu cycles. BTW, it's also what's make jaotc useless in its current incarnation because it AOTs things your application don't care. This is a very specific set of reasons why eager loading is a bad idea: Against Java tradition, harmful to startup, and liable to tickle bugs that otherwise would sleep quietly. On Jul 12, 2018, at 11:41 AM, Tobi Ajila wrote: > > I'm looking for reasons that > > this is a *bad* idea, so we can say in the end, "here's exactly why we had to make > > the loading logic for VTs so tricky"?if we must. > > Karen's initial post mentions our two biggest concerns. If there is no guarantee that the VTs in the method descriptors will be used, loading them is an overhead. We would like to minimize the cost to startup as much as possible. The other reason is eager loading may trigger failures that would otherwise never occur if the method wasn't run, which is change from how the JVM normally behaves. OK, those points align with the discussion above. IMO there's still a possibility that we will want to eagerly load signature types declared as value types, at preparation time. This could happen if two bad things happen first: (a) We can't figure out how to assign calling sequences properly to virtual methods (including those connected by v-table/override relations) without preparation time loadings, and (b) we regretfully realize that we would rather get the calling sequences right than follow the Java traditions noted above. (For the moment, let's define the term "method family" to mean any group of methods which is connected by override/v-table relations in such a way that the methods are all constrained to have a common calling sequence. I can't think offhand of a standard term for this, but we need a term.) To solve (a) we need a story, for any given method family F, how the common calling sequence (including unboxed values) is assigned during startup, even if dynamically loaded class hierarchies are being loaded in a data-dependent fashion, concurrently with executions of members of F. I don't think appealing to speculation and deoptimization is a good answer for (a), because it slows startup unpredictably. If that's the answer, I'd rather just take the predictable startup hit of loading signature value types. That is, given an inaccurate solution for (a), I think we'd decide in the end, regarding point (b), to regretfully break tradition. So, is there a reasonably simple way to get good enough calling sequences non-speculatively? The answer might be yes, along the lines you mentioned Tobi, but I don't see it yet. I think maybe the whole family F needs a linkage barrier, which involves delayed loading of signature value types used in F. Although preparation of F's various classes would have assigned v-table slots (or whatever preconstructed dictionary V8 might use instead of v-tables), the calling sequences of those v-table slots would remain mysterious until the first execution of a method in F. Can we do that? It sort of feels like a mini-preparation pass just for F. ? John From karen.kinnear at oracle.com Thu Jul 12 20:51:35 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 12 Jul 2018 16:51:35 -0400 Subject: Valhalla EG Notes June 20, 2018 In-Reply-To: <564B3354-3733-4775-8D56-11B23D2B9998@oracle.com> References: <4521AAF1-AA57-425E-8A0E-24080E107441@oracle.com> <564B3354-3733-4775-8D56-11B23D2B9998@oracle.com> Message-ID: <10EC0C76-37A6-485E-88C3-D52732CF0A8B@oracle.com> Dan, tracking via https://bugs.openjdk.java.net/browse/JDK-8205061 thanks, Karen > On Jul 9, 2018, at 2:50 PM, Karen Kinnear wrote: > > > Many thanks for checking Dan and agreeing that this needs a spec fix. Working on moving that forward. > > thanks, > Karen > >> On Jul 6, 2018, at 11:26 AM, Daniel Heidinga > wrote: >> >> > AI: Karen - double check potential JVMTI bug >> >> I checked our code base for this and we have the same behaviour. Would be good to get this fixed at the spec level. >> >> --Dan >> >> ----- Original message ----- >> From: Karen Kinnear > >> Sent by: "valhalla-spec-experts" > >> To: valhalla-spec-experts > >> Cc: >> Subject: Valhalla EG Notes June 20, 2018 >> Date: Fri, Jun 29, 2018 6:36 PM >> >> NO meeting July 4th, 2018 - US Independence day holiday. Next Meeting July 18th. >> Karen will be on vacation week of July 18th - looking for a volunteer to run the meeting please. >> >> AIs: >> All: review Nestmates GetNestHost minor rewording of javadoc >> All: review Value Type Consistency Checking proposal: >> http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf >> All: see follow-up request - please approve LW1 temporary static method consistency checking before preparation, to be revisited: >> http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2018-June/000717.html >> >> Karen: update Value Types Consistency Checking proposal with BootStrapMethod info >> >> attendees: John, Dan S, Tobias, Dan H, Frederic, Remi, Karen >> >> I. Nestmates: >> Please review GetNestHost minor javadoc request >> >> II. Condy >> Remi: when will javac use condy for constant lambdas? >> Dan S: some experiments have been done, would like to do this, no timeframe yet >> Condy next step: not require Looking and Name&Type argument >> Remi: ElasticSearch guy: indy metafactory not do all the needed casting - works for java but not for scala and other languages - will dig and find >> >> III. Value Types >> >> 1. Equals/Hashcode/toString >> Remi - saw initial prototype implementation >> - two different approaches - Records in Amber vs. Valhalla >> Remi has a version he could clean up and offer for all us to use - weave custom MethodHandles for each type >> John: using loop combinators? >> Remi - try not to >> John: good - love to see it >> >> ** follow-on email >> (many thanks Remi!) >> >> 2. Value Types Consistency Checking proposal >> Karen walked through overview >> >> Summary: >> Two types of checks >> 1. Value Types attribute vs. reality >> 2. Value Types attribute of two different classes - e.g. caller-callee >> >> Users of Value Types attribute: >> 1. verifier (with no loading) - catching mismatched bytecode usage >> 2. optimizations >> >> Goal: avoid eager loading >> >> Terminology: >> pre-load: load before completing load of containing class >> - analogous to supertype handling >> - only proposed for flattenable instance fields, information needed for layout >> - risk of circularity >> eager loading: loading at other times - e.g. linking, preparation, etc. >> >> Proposed checking against reality: >> >> 1. instance fields (all flattenable in LW1) - pre-loaded: test vs. real >> 2. flattenable static fields - link phase, prior to preparation (post-LW1): test vs. real >> 3. local methods: prior to preparation check all (in ValueTypes attribute or not) parameters/return vs. real >> 4. CONSTANT_Class resolution: for all classes (in ValueTypes attribute or not)test vs. real >> >> Proposed checking inter-class consistency >> 5. Preparation (selection cache creation): method declarer vs. method overrider consistency >> 6. Field or Method Resolution: For all types in signatures, check caller-callee consistency >> Note: these checks should essentially match where loader constraint checks are performed today. >> Note: all the inter-class consistency checks check all the signature types, whether or not they are in the Value Types attribute >> >> Remi: if a method is never called, why load parameters? >> Tobi: why not load one first invocation? >> John: if load before call - add a new barrier. >> - challenge with overriding hierarchy - deopt - sudden unpredictable performance drop >> - preparation is better than 1st call >> Karen: note: if there is a null on the stack, they might not have loaded a parameter at first call >> Frederic: Overriding example >> A.m, B.m, C.m >> if A is correct, B is incorrect, C is maybe wrong >> - body of the local method may be incorrect >> Remi: if the super type is correct but the subtype is not >> Karen: preparation checks are NOT vs. the real type - they just check overrider/overridden - they could both be wrong and pass that check >> Frederic: This is more complex with interfaces >> Dan H: if never call method, want to continue to run, throw an exception when realize inconsistency >> Dan S: alternative - hotspot implementation could perform the check early and cache and throw the exception at first invocation >> >> AI: Karen - investigate possibilities including either delaying checking or offering the option to check earlier but delay throwing any exceptions >> ed. note - sent follow-up email: started the exploration - too complex for LW1 timeframe - asked for approval to keep proposal >> for now and revisit after we get early access binaries into people?s hands >> >> John: Constant_Class resolution - need to also check BootStrapMethod evaluation for indy and condy - spec says ?as if by ldc?. >> >> Karen: Issue 1: Note that it is possible for class A to declare a field of V, not know it is a value type, and class C to also not know >> and to store null in the field, because field resolution only checks between the caller-callee, not reality. >> Folks were ok with letting this work. >> >> III. Static fields - flattenability >> >> Karen summarized some of the issues and options outlined in the Value Types Consistency Checking: >> >> - risk of circularity errors if we pre-load static fields that are (flattenable) value types. Since there is a requirement to allow >> a static field to contain an instance of the container type, we obviously can not pre-load. >> >> - Preparation time issues: >> - Preparation is prior to class initialization >> - challenge in creating a default value instance of a class which has not yet been initialized >> - theory is that you can?t actually get to the static without initializing the class >> >> choices: >> 1. trigger class initialization early >> 2. prevent a leak >> >> John: bytecodes and MH-like bytecodes know how to make a default instance before class initialization >> >> Note: there is a risk of the default value instance escaping prior to initialization >> ? e.g. JVMTI - maybe spec bug - getFieldIDs/getMethodIDs - require a class to be prepared - should require a class to be initialized >> (since the jfieldIDs/jmethodIDs will be used by JNI which requires the class to be initialized, and the getField/getStatic etc. JNI >> methods do NOT ensure this for performance). This is a bug. >> >> ? JLS is explicit about hole during that allows the initializer to create an instance of itself and publish it for external view >> - this is an actual problem >> >> - Note that once the instance escapes - there are no class initialization barriers on bytecodes for instances - it is assumed that these >> are caught at ?new? or ?defaultvalue? >> >> Remi: agree with John - go ahead and initialize during preparation to a default value and do not trigger class initialization >> >> Dan S: prefer get static trigger class initialization rather than preparation >> >> John: concern about circularities for class initialization >> Karen: circularities - only for class loading, not for initialization - logic explicitly allows same thread to ?successfully? initialize if already >> in initialization >> >> Karen: class initialization of a container should trigger class initialization of all flattenable fields >> >> John: any additional class initialization barriers for hiding default - e.g. anewarray >> Preparation essentially creates storage, >> >> AI: Karen - double check potential JVMTI bug >> >> Corrections welcome, >> thanks, >> Karen >> >> >> >> >> >> >> >> >> >> > From forax at univ-mlv.fr Fri Jul 13 10:55:50 2018 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Fri, 13 Jul 2018 12:55:50 +0200 (CEST) Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: <017CF66A-7029-4364-8025-47FE5861BA67@oracle.com> References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> <017CF66A-7029-4364-8025-47FE5861BA67@oracle.com> Message-ID: <2030218895.799221.1531479350492.JavaMail.zimbra@u-pem.fr> Let's try ... First, what we want is to have an algorithm that find the calling layout of a method, unlike with references were there is only one possible calling layout, because value types can be flattened, there are several possible calling layouts when value types are involved. We want: - to defer the loading of a value type class until we need to actually call a method that contains that value type in its descriptor - a familly of methods (the tree of overridden methods) to have the same calling layout so VMs can use vtables if they want The ideas: - decouple the construction of the vtable from finding the calling layout of a method, so instead of having one pass that constructs the vtable, creates the slots etc and determines the calling layout, we now separate in two phases. Building the vtable only find the slots but not the calling layout of the methods, we need a supplementary phase to determine the calling layout of a method - the calling layout of a method is determined by the information (the value types declared in the ValueTypes attribute) of the class that creates the vtable slot for that method So vtables are created as usual, and when the interpreter does a method call, after having found the vtable slot, it will try to resolve the calling layout using the ValueTypes attribute of the class that have created that slot. So value type of that ValueTypes attribute that are part of the method descriptor will be loaded at that point. For default methods (which are injected in the vtable hierarchy), if we follow this algorithm, the calling layout of a default method should be deteermined using the information of the class that receives the default methods (the one that creates the vtable slot) and not from the ValueTypes attribute of the interface making the attribute ValueTypes in an interface useless. I don't know if it's a good idea or not ? R?mi ----- Mail original ----- > De: "John Rose" > ?: "Remi Forax" , "Tobi Ajila" > Cc: "valhalla-spec-experts" > Envoy?: Jeudi 12 Juillet 2018 21:02:02 > Objet: Re: EG help please with getting to LW1 re: Value Types Consistency Checking > Thanks, Tobi and Remi, for the helpful observations. > > On Jul 10, 2018, at 2:43 AM, Remi Forax wrote: >> >> I think the answer to the question of lazy loading of method parameter types is >> rooted to the question of what is a value type exactly for Java. >> Is it an optimization, a first class concept i.e one that should work as if it >> was integrated in the language from the beginning ? >> The other problem is the more we diverge from the class behavior, the harder it >> will be to allow a class to become a value type. >> >> I firmly believe that value type should be first class because they are useless >> in a lot of scenario if they are not. The main limitation of a value type is >> its immutable characteristic, what save them from uselessness is that their >> creation cost should be zero or very close to zero alleviating the burden of >> think in term of object creation and making us, developers, free to use >> functional idioms. >> With that in mind, i believe a value type should not be "boxed" because it's not >> loaded yet (it can still be boxed due to separate compilation but that's >> another story) so value type present in method descriptor should be loaded >> eagerly. > > So value types should diverge from object types enough to allow accurate > unboxing in hot paths. > But they should not diverge more than necessary. That means no eager loading > that's not needed. > >> About loading all value type of the attribute ValueTypes, from one side Java has >> a strong tradition to not pay for the code you do not use. This power today's >> applications, an average application has an hundred jars as dependencies, if >> all value types are preloaded it's at waste of memory and cpu cycles. BTW, it's >> also what's make jaotc useless in its current incarnation because it AOTs >> things your application don't care. > > This is a very specific set of reasons why eager loading is a bad idea: Against > Java tradition, > harmful to startup, and liable to tickle bugs that otherwise would sleep > quietly. > > On Jul 12, 2018, at 11:41 AM, Tobi Ajila wrote: > >> > I'm looking for reasons that >> > this is a *bad* idea, so we can say in the end, "here's exactly why we had to >> > make >> > the loading logic for VTs so tricky"?if we must. >> >> Karen's initial post mentions our two biggest concerns. If there is no guarantee >> that the VTs in the method descriptors will be used, loading them is an >> overhead. We would like to minimize the cost to startup as much as possible. >> The other reason is eager loading may trigger failures that would otherwise >> never occur if the method wasn't run, which is change from how the JVM normally >> behaves. > > OK, those points align with the discussion above. > > IMO there's still a possibility that we will want to eagerly load signature > types > declared as value types, at preparation time. This could happen if two bad > things happen first: (a) We can't figure out how to assign calling sequences > properly to virtual methods (including those connected by v-table/override > relations) without preparation time loadings, and (b) we regretfully realize > that we would rather get the calling sequences right than follow the Java > traditions noted above. > > (For the moment, let's define the term "method family" to mean any group > of methods which is connected by override/v-table relations in such a way > that the methods are all constrained to have a common calling sequence. > I can't think offhand of a standard term for this, but we need a term.) > > To solve (a) we need a story, for any given method family F, how the > common calling sequence (including unboxed values) is assigned during > startup, even if dynamically loaded class hierarchies are being loaded > in a data-dependent fashion, concurrently with executions of members > of F. > > I don't think appealing to speculation and deoptimization is a good answer > for (a), because it slows startup unpredictably. If that's the answer, I'd > rather just take the predictable startup hit of loading signature value types. > That is, given an inaccurate solution for (a), I think we'd decide in the end, > regarding point (b), to regretfully break tradition. > > So, is there a reasonably simple way to get good enough calling sequences > non-speculatively? > > The answer might be yes, along the lines you mentioned Tobi, but I don't > see it yet. I think maybe the whole family F needs a linkage barrier, > which involves delayed loading of signature value types used in F. > Although preparation of F's various classes would have assigned > v-table slots (or whatever preconstructed dictionary V8 might use > instead of v-tables), the calling sequences of those v-table slots would > remain mysterious until the first execution of a method in F. > > Can we do that? It sort of feels like a mini-preparation pass just for F. > > ? John From karen.kinnear at oracle.com Fri Jul 13 20:00:17 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Fri, 13 Jul 2018 16:00:17 -0400 Subject: Valhalla EG Notes June 20, 2018 In-Reply-To: <4521AAF1-AA57-425E-8A0E-24080E107441@oracle.com> References: <4521AAF1-AA57-425E-8A0E-24080E107441@oracle.com> Message-ID: <030E477B-F353-454B-9901-841649D3166C@oracle.com> Hearing no volunteers for running July 18th meeting - I am cancelling it. Hope to see some of you at the JVMLS. Tobi - I owe you a response to your proposal - we are prototyping the proposal I sent out and learning a lot which may help inform where we end up. thanks, Karen > On Jun 29, 2018, at 6:36 PM, Karen Kinnear wrote: > > NO meeting July 4th, 2018 - US Independence day holiday. Next Meeting July 18th. > Karen will be on vacation week of July 18th - looking for a volunteer to run the meeting please. > > AIs: > All: review Nestmates GetNestHost minor rewording of javadoc > All: review Value Type Consistency Checking proposal: > http://cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf > All: see follow-up request - please approve LW1 temporary static method consistency checking before preparation, to be revisited: > http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2018-June/000717.html > > Karen: update Value Types Consistency Checking proposal with BootStrapMethod info > > attendees: John, Dan S, Tobias, Dan H, Frederic, Remi, Karen > > I. Nestmates: > Please review GetNestHost minor javadoc request > > II. Condy > Remi: when will javac use condy for constant lambdas? > Dan S: some experiments have been done, would like to do this, no timeframe yet > Condy next step: not require Looking and Name&Type argument > Remi: ElasticSearch guy: indy metafactory not do all the needed casting - works for java but not for scala and other languages - will dig and find > > III. Value Types > > 1. Equals/Hashcode/toString > Remi - saw initial prototype implementation > - two different approaches - Records in Amber vs. Valhalla > Remi has a version he could clean up and offer for all us to use - weave custom MethodHandles for each type > John: using loop combinators? > Remi - try not to > John: good - love to see it > > ** follow-on email > (many thanks Remi!) > > 2. Value Types Consistency Checking proposal > Karen walked through overview > > Summary: > Two types of checks > 1. Value Types attribute vs. reality > 2. Value Types attribute of two different classes - e.g. caller-callee > > Users of Value Types attribute: > 1. verifier (with no loading) - catching mismatched bytecode usage > 2. optimizations > > Goal: avoid eager loading > > Terminology: > pre-load: load before completing load of containing class > - analogous to supertype handling > - only proposed for flattenable instance fields, information needed for layout > - risk of circularity > eager loading: loading at other times - e.g. linking, preparation, etc. > > Proposed checking against reality: > > 1. instance fields (all flattenable in LW1) - pre-loaded: test vs. real > 2. flattenable static fields - link phase, prior to preparation (post-LW1): test vs. real > 3. local methods: prior to preparation check all (in ValueTypes attribute or not) parameters/return vs. real > 4. CONSTANT_Class resolution: for all classes (in ValueTypes attribute or not)test vs. real > > Proposed checking inter-class consistency > 5. Preparation (selection cache creation): method declarer vs. method overrider consistency > 6. Field or Method Resolution: For all types in signatures, check caller-callee consistency > Note: these checks should essentially match where loader constraint checks are performed today. > Note: all the inter-class consistency checks check all the signature types, whether or not they are in the Value Types attribute > > Remi: if a method is never called, why load parameters? > Tobi: why not load one first invocation? > John: if load before call - add a new barrier. > - challenge with overriding hierarchy - deopt - sudden unpredictable performance drop > - preparation is better than 1st call > Karen: note: if there is a null on the stack, they might not have loaded a parameter at first call > Frederic: Overriding example > A.m, B.m, C.m > if A is correct, B is incorrect, C is maybe wrong > - body of the local method may be incorrect > Remi: if the super type is correct but the subtype is not > Karen: preparation checks are NOT vs. the real type - they just check overrider/overridden - they could both be wrong and pass that check > Frederic: This is more complex with interfaces > Dan H: if never call method, want to continue to run, throw an exception when realize inconsistency > Dan S: alternative - hotspot implementation could perform the check early and cache and throw the exception at first invocation > > AI: Karen - investigate possibilities including either delaying checking or offering the option to check earlier but delay throwing any exceptions > ed. note - sent follow-up email: started the exploration - too complex for LW1 timeframe - asked for approval to keep proposal > for now and revisit after we get early access binaries into people?s hands > > John: Constant_Class resolution - need to also check BootStrapMethod evaluation for indy and condy - spec says ?as if by ldc?. > > Karen: Issue 1: Note that it is possible for class A to declare a field of V, not know it is a value type, and class C to also not know > and to store null in the field, because field resolution only checks between the caller-callee, not reality. > Folks were ok with letting this work. > > III. Static fields - flattenability > > Karen summarized some of the issues and options outlined in the Value Types Consistency Checking: > > - risk of circularity errors if we pre-load static fields that are (flattenable) value types. Since there is a requirement to allow > a static field to contain an instance of the container type, we obviously can not pre-load. > > - Preparation time issues: > - Preparation is prior to class initialization > - challenge in creating a default value instance of a class which has not yet been initialized > - theory is that you can?t actually get to the static without initializing the class > > choices: > 1. trigger class initialization early > 2. prevent a leak > > John: bytecodes and MH-like bytecodes know how to make a default instance before class initialization > > Note: there is a risk of the default value instance escaping prior to initialization > ? e.g. JVMTI - maybe spec bug - getFieldIDs/getMethodIDs - require a class to be prepared - should require a class to be initialized > (since the jfieldIDs/jmethodIDs will be used by JNI which requires the class to be initialized, and the getField/getStatic etc. JNI > methods do NOT ensure this for performance). This is a bug. > > ? JLS is explicit about hole during that allows the initializer to create an instance of itself and publish it for external view > - this is an actual problem > > - Note that once the instance escapes - there are no class initialization barriers on bytecodes for instances - it is assumed that these > are caught at ?new? or ?defaultvalue? > > Remi: agree with John - go ahead and initialize during preparation to a default value and do not trigger class initialization > > Dan S: prefer get static trigger class initialization rather than preparation > > John: concern about circularities for class initialization > Karen: circularities - only for class loading, not for initialization - logic explicitly allows same thread to ?successfully? initialize if already > in initialization > > Karen: class initialization of a container should trigger class initialization of all flattenable fields > > John: any additional class initialization barriers for hiding default - e.g. anewarray > Preparation essentially creates storage, > > AI: Karen - double check potential JVMTI bug > > Corrections welcome, > thanks, > Karen > > > > > > > From john.r.rose at oracle.com Fri Jul 13 20:24:52 2018 From: john.r.rose at oracle.com (John Rose) Date: Fri, 13 Jul 2018 13:24:52 -0700 Subject: Valhalla EG Notes June 20, 2018 In-Reply-To: <030E477B-F353-454B-9901-841649D3166C@oracle.com> References: <4521AAF1-AA57-425E-8A0E-24080E107441@oracle.com> <030E477B-F353-454B-9901-841649D3166C@oracle.com> Message-ID: On Jul 13, 2018, at 1:00 PM, Karen Kinnear wrote: > > Tobi - I owe you a response to your proposal - we are prototyping the proposal I sent out and learning a lot > which may help inform where we end up. I think we all agree that pre-loading VT classfiles is necessary to drive at least some of the critical optimizations that justify VTs. The main optimization that require pre-loading is certainly flattened fields. Another one is (almost certainly) scalarized parameters and returns (for out-of-line calls). ("Pre-loading" simply means loading the VT classfile before the other JVMS rules would force loading. Those rules pertain to instantiation, static member resolution, etc.) The ValueTypes attribute is the (current) starting point for deciding which classes are *candidates* for pre-loading. We could load *all* of them as early as possible, but that is thought to require too much class loading activity at start-up time. I'm not fully convinced this would be so bad, but let's try to do better. Doing better means (a) loading fewer of the VT types, and/or (b) loading them later. The latest possible point is, as noted above, when at VT class is actually used in some way that triggers loading and . The best possible win would be deferring *all* VT loading to that required point, but we know that's impossible. So LW1 will eagerly load VT classfiles in some ad hoc fashion driven by optimization needs. Karen is writing up the rules for this, even as they seem to change under her feet. (Thanks Karen!) If the LW1 prototype loads VT classes too eagerly, we will try to dial it back, perhaps along the lines Tobi proposes. The LW1 prototype is intended in part to give us experience with performance models, so we may load VT classes eagerly if we think it helps with specific optimizations. We'll collect the performance win, and then go back and see if the loading can be made less eager, to collect a startup win also. The startup wins might well wait until post-LW1, depending on how much tricky experimentation and redesign is required. ? John P.S. The above discussion mentions field flattening and out-of-line parameter scalarization as the key optimizations that require pre-loading. These may, in the end, be the only such optimizations, not just the key ones. But we should be ready for a third shoe to drop. :-) From john.r.rose at oracle.com Fri Jul 13 21:50:00 2018 From: john.r.rose at oracle.com (John Rose) Date: Fri, 13 Jul 2018 14:50:00 -0700 Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: <2030218895.799221.1531479350492.JavaMail.zimbra@u-pem.fr> References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> <017CF66A-7029-4364-8025-47FE5861BA67@oracle.com> <2030218895.799221.1531479350492.JavaMail.zimbra@u-pem.fr> Message-ID: <8E0FD960-5057-43BE-80B6-8DA810C23178@oracle.com> On Jul 13, 2018, at 3:55 AM, forax at univ-mlv.fr wrote: > > Let's try ? OK! (Caveat: I am certain this is post-LW1.) > First, what we want is to have an algorithm that find the calling layout of a method, unlike with references were there is only one possible calling layout, because value types can be flattened, there are several possible calling layouts when value types are involved. > > We want: > - to defer the loading of a value type class until we need to actually call a method that contains that value type in its descriptor > - a familly of methods (the tree of overridden methods) to have the same calling layout so VMs can use vtables if they want > > The ideas: > - decouple the construction of the vtable from finding the calling layout of a method, so instead of having one pass that constructs the vtable, creates the slots etc and determines the calling layout, we now separate in two phases. Building the vtable only find the slots but not the calling layout of the methods, we need a supplementary phase to determine the calling layout of a method > - the calling layout of a method is determined by the information (the value types declared in the ValueTypes attribute) of the class that creates the vtable slot for that method > > So vtables are created as usual, and when the interpreter does a method call, after having found the vtable slot, it will try to resolve the calling layout using the ValueTypes attribute of the class that have created that slot. So value type of that ValueTypes attribute that are part of the method descriptor will be loaded at that point. Yes. What we are talking about here is a new resolution step for method descriptors. The v-table setup (and/or override tree detection) looks only at the strings, but before the first call the strings (parts of them) need resolution. It looks like we are inventing a new JVM phase here: value type resolution. Or (calling Dan!) maybe we just add a bit of language to the JVMS that says that resolving a method call entails resolving its value types. No, it's not just a little bit of language, because the resolution needs to walk up and down the class/interface hierarchy that defines the method's override family. These are the same paths as are walked by class loader constraint checking, which is one of the more complex parts of the JVMS. Basically, method overriding needs to re-run class loader constraint checking, just for one override family, but with newly-loaded knowledge about value types. That raises a possible counter-argument to the point that eager resolution of VTs is "not JVM-like". Yes, eager loading is not JVM-like, but if the alternative is a new JVM phase, which is *even less* JVM-like, then maybe we just do the early load and call it good. It's a judgement call: Is the complexity of the new phase warranted? > For default methods (which are injected in the vtable hierarchy), if we follow this algorithm, the calling layout of a default method should be deteermined using the information of the class that receives the default methods (the one that creates the vtable slot) and not from the ValueTypes attribute of the interface making the attribute ValueTypes in an interface useless. I don't know if it's a good idea or not ? I think in practice it will be necessary, especially given the delay in reporting errors. A program will be too busy doing work to tolerate ICCE's on random method calls due to non-local effects (somebody else got to the interface method first, with a different opinion). This means interface default methods (at least) need suites of varying adapters. For me this re-raises the question of what happens if a *class* in an override tree tries to inject a bad opinion. That mustn't be allowed to spoil scalarization but OTOH two bad classes might want to exchange nulls through their own part of the override tree. (Dirty habit!) A full story needs to say how those guys can continue with their nulls, without hurting optimization for the new code, in the same override tree. Or else we need grounds for telling the null-users to go elsewhere, with with prejudice (ICCE) or permission (separate calling sequence, separate v-table slot). Yuck. From forax at univ-mlv.fr Mon Jul 23 20:32:12 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 23 Jul 2018 22:32:12 +0200 (CEST) Subject: How to represent value based classes ? Message-ID: <1161645752.207250.1532377932517.JavaMail.zimbra@u-pem.fr> Hi all, i've plyed for some quite times now to specify in my mind what a value based class can be and i think it's time write that down. First, why we need value based class ? We want to offer a path to refactor a class to a value type but given that class instances are nullable and value type values are not, the proposed solution is to introduce a kind of 'compatible with null' value type i.e. a value based class. Java in its API already specifies that some classess (Optional, LocalDateTime) are value based classes saying that they have no identity. What is the best outcome ? The best case is like checked exceptions, i.e. the VM doesn't know what a value based class is and only javac knows what a value based class is and add some magics, do null tranlation back and forth. But i doubt it's possible because with the ValueTypes attribute, a class can not be a reference class and as a value type inside the same method, so the VM has to do the conversion in adapters. Proposed wrapping/unwrapping: A value based class is a value type with one discriminator field. A discriminator field is a field that is annotated with the flag ACC_DISCRIMINATOR (only one by value based class). Technically from the VM implementation point of view, a discriminator is a field_offset + a type. class -> value type if (null) -> vdefault value type -> class if (vt[discriminator_offset] == 0) -> null The Value Type attributes also need to be modified to include a boolean that says if it's a plain value type or a value based class. By example, for java.util.Optional, the field that contains the reference is also the discriminator field, which means that the difference Optional as value type and Optional as value based class is that the interpreter and the JIT may have to execute more tests to do null wrapping/unwrapping. For java.util.OptionalLong, here we need a supplementary field, a boolean (a byte), is enough. In that case, the value based class may take more space + more tests. For the class of java.time, Stephen can choose on per class basis, how to null as to be encoded. To summarize: A value based class can be either a class with some JIT optimizations but the layout of a class or a value type with a way to encode null, i think the former solution is sad. Obviously, i'm not a specialist of the assembly languages so there is maybe another encoding scheme. I think that letting the user to specify the discriminator field solve the issue to have to come with a general scheme that works for all value based classes, because you offload the verification that the discriminator can not be zero in the normal case to the user. R?mi From john.r.rose at oracle.com Mon Jul 23 20:46:14 2018 From: john.r.rose at oracle.com (John Rose) Date: Mon, 23 Jul 2018 13:46:14 -0700 Subject: How to represent value based classes ? In-Reply-To: <1161645752.207250.1532377932517.JavaMail.zimbra@u-pem.fr> References: <1161645752.207250.1532377932517.JavaMail.zimbra@u-pem.fr> Message-ID: <77BB5096-37CB-4738-8452-A90B96612DB4@oracle.com> Interesting exercise. You don?t need the extra bit in the attributes it you can defer null processing decisions until the VT/VBC is actually loaded. I think that?s possible. > On Jul 23, 2018, at 1:32 PM, Remi Forax wrote: > > Hi all, > i've plyed for some quite times now to specify in my mind what a value based class can be and i think it's time write that down. > > First, why we need value based class ? > We want to offer a path to refactor a class to a value type but given that class instances are nullable and value type values are not, the proposed solution is to introduce a kind of 'compatible with null' value type i.e. a value based class. Java in its API already specifies that some classess (Optional, LocalDateTime) are value based classes saying that they have no identity. > > What is the best outcome ? > The best case is like checked exceptions, i.e. the VM doesn't know what a value based class is and only javac knows what a value based class is and add some magics, do null tranlation back and forth. But i doubt it's possible because with the ValueTypes attribute, a class can not be a reference class and as a value type inside the same method, so the VM has to do the conversion in adapters. > > Proposed wrapping/unwrapping: > A value based class is a value type with one discriminator field. A discriminator field is a field that is annotated with the flag ACC_DISCRIMINATOR (only one by value based class). Technically from the VM implementation point of view, a discriminator is a field_offset + a type. > > class -> value type > if (null) -> vdefault > > value type -> class > if (vt[discriminator_offset] == 0) -> null > > > The Value Type attributes also need to be modified to include a boolean that says if it's a plain value type or a value based class. > > By example, for java.util.Optional, the field that contains the reference is also the discriminator field, which means that the difference Optional as value type and Optional as value based class is that the interpreter and the JIT may have to execute more tests to do null wrapping/unwrapping. > > For java.util.OptionalLong, here we need a supplementary field, a boolean (a byte), is enough. In that case, the value based class may take more space + more tests. > > For the class of java.time, Stephen can choose on per class basis, how to null as to be encoded. > > > To summarize: > A value based class can be either a class with some JIT optimizations but the layout of a class or a value type with a way to encode null, i think the former solution is sad. > Obviously, i'm not a specialist of the assembly languages so there is maybe another encoding scheme. > I think that letting the user to specify the discriminator field solve the issue to have to come with a general scheme that works for all value based classes, because you offload the verification that the discriminator can not be zero in the normal case to the user. > > R?mi From forax at univ-mlv.fr Mon Jul 23 20:51:24 2018 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Mon, 23 Jul 2018 22:51:24 +0200 (CEST) Subject: How to represent value based classes ? In-Reply-To: <77BB5096-37CB-4738-8452-A90B96612DB4@oracle.com> References: <1161645752.207250.1532377932517.JavaMail.zimbra@u-pem.fr> <77BB5096-37CB-4738-8452-A90B96612DB4@oracle.com> Message-ID: <940247316.208351.1532379084701.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "John Rose" > ?: "Remi Forax" > Cc: "valhalla-spec-experts" > Envoy?: Lundi 23 Juillet 2018 22:46:14 > Objet: Re: How to represent value based classes ? > Interesting exercise. You don?t need the extra bit in the attributes it you can > defer null processing decisions until the VT/VBC is actually loaded. I think > that?s possible. yes, it's a sub-item item of the issue "when VT/VBC should be loaded" ? R?mi > >> On Jul 23, 2018, at 1:32 PM, Remi Forax wrote: >> >> Hi all, >> i've plyed for some quite times now to specify in my mind what a value based >> class can be and i think it's time write that down. >> >> First, why we need value based class ? >> We want to offer a path to refactor a class to a value type but given that class >> instances are nullable and value type values are not, the proposed solution is >> to introduce a kind of 'compatible with null' value type i.e. a value based >> class. Java in its API already specifies that some classess (Optional, >> LocalDateTime) are value based classes saying that they have no identity. >> >> What is the best outcome ? >> The best case is like checked exceptions, i.e. the VM doesn't know what a value >> based class is and only javac knows what a value based class is and add some >> magics, do null tranlation back and forth. But i doubt it's possible because >> with the ValueTypes attribute, a class can not be a reference class and as a >> value type inside the same method, so the VM has to do the conversion in >> adapters. >> >> Proposed wrapping/unwrapping: >> A value based class is a value type with one discriminator field. A >> discriminator field is a field that is annotated with the flag >> ACC_DISCRIMINATOR (only one by value based class). Technically from the VM >> implementation point of view, a discriminator is a field_offset + a type. >> >> class -> value type >> if (null) -> vdefault >> >> value type -> class >> if (vt[discriminator_offset] == 0) -> null >> >> >> The Value Type attributes also need to be modified to include a boolean that >> says if it's a plain value type or a value based class. >> >> By example, for java.util.Optional, the field that contains the reference is >> also the discriminator field, which means that the difference Optional as value >> type and Optional as value based class is that the interpreter and the JIT may >> have to execute more tests to do null wrapping/unwrapping. >> >> For java.util.OptionalLong, here we need a supplementary field, a boolean (a >> byte), is enough. In that case, the value based class may take more space + >> more tests. >> >> For the class of java.time, Stephen can choose on per class basis, how to null >> as to be encoded. >> >> >> To summarize: >> A value based class can be either a class with some JIT optimizations but the >> layout of a class or a value type with a way to encode null, i think the former >> solution is sad. >> Obviously, i'm not a specialist of the assembly languages so there is maybe >> another encoding scheme. >> I think that letting the user to specify the discriminator field solve the issue >> to have to come with a general scheme that works for all value based classes, >> because you offload the verification that the discriminator can not be zero in >> the normal case to the user. >> > > R?mi From john.r.rose at oracle.com Mon Jul 23 21:03:48 2018 From: john.r.rose at oracle.com (John Rose) Date: Mon, 23 Jul 2018 14:03:48 -0700 Subject: How to represent value based classes ? In-Reply-To: <940247316.208351.1532379084701.JavaMail.zimbra@u-pem.fr> References: <1161645752.207250.1532377932517.JavaMail.zimbra@u-pem.fr> <77BB5096-37CB-4738-8452-A90B96612DB4@oracle.com> <940247316.208351.1532379084701.JavaMail.zimbra@u-pem.fr> Message-ID: On Jul 23, 2018, at 1:51 PM, forax at univ-mlv.fr wrote: > > it's a sub-item item of the issue "when VT/VBC should be loaded" ? Right. And I don?t see any case where we would care about null handling where we would not *also* care about the layout. In the case of the verifier, a checkcast instruction will convert from a null reference to a VT or VBC without caring which case it is. After linking, the checkcast could either NPE or substitute the default value. From john.r.rose at oracle.com Mon Jul 23 21:07:42 2018 From: john.r.rose at oracle.com (John Rose) Date: Mon, 23 Jul 2018 14:07:42 -0700 Subject: How to represent value based classes ? In-Reply-To: References: <1161645752.207250.1532377932517.JavaMail.zimbra@u-pem.fr> <77BB5096-37CB-4738-8452-A90B96612DB4@oracle.com> <940247316.208351.1532379084701.JavaMail.zimbra@u-pem.fr> Message-ID: On Jul 23, 2018, at 2:03 PM, John Rose wrote: > > Right. And I don?t see any case where we would care about null handling where we would not *also* care about the layout. In the case of the verifier, a checkcast instruction will convert from a null reference to a VT or VBC without caring which case it is. After linking, the checkcast could either NPE or substitute the default value. There are other times like this when we need nullability info, but I think the verifier is the extreme case, and if we can solve that one (as above) then others can be handled by similar tricks, which make an early decision (allow the checkcast) and refine it later (after linking decide the precise behavior). From frederic.parain at oracle.com Tue Jul 24 13:10:03 2018 From: frederic.parain at oracle.com (Frederic Parain) Date: Tue, 24 Jul 2018 09:10:03 -0400 Subject: EG help please with getting to LW1 re: Value Types Consistency Checking In-Reply-To: References: <58F4AAFF-77D4-4CB4-A296-6620BDE75CA7@oracle.com> <1314941128.627986.1531215838105.JavaMail.zimbra@u-pem.fr> Message-ID: <53005e6b-702a-5383-b4a2-d9684ece160f@oracle.com> On 07/12/2018 02:41 PM, Tobi Ajila wrote: > > I'm looking for reasons that > > this is a *bad* idea, so we can say in the end, "here's exactly why > we had to make > > the loading logic for VTs so tricky"?if we must. > > Karen's initial post mentions our two biggest concerns. If there is no > guarantee that the VTs in the method descriptors will be used, loading > them is an overhead. We would like to minimize the cost to startup as > much as possible. The other reason is eager loading may trigger failures > that would otherwise never occur if the method wasn't run, which is > change from how the JVM normally behaves. This is already the case for flattened value fields: even if the application never use them, they can cause failures if their pre-loading fails. Fred > > --Tobi > > > From: Remi Forax > > To: John Rose > > Cc: Tobi Ajila , valhalla-spec-experts > > > > Date: 2018/07/10 05:44 AM > > Subject: Re: EG help please with getting to LW1 re: Value Types > > Consistency Checking > > > > Hi all, > > > > De: "John Rose" > > ?: "Tobi Ajila" > > Cc: "valhalla-spec-experts" > > Envoy?: Samedi 7 Juillet 2018 23:08:27 > > Objet: Re: EG help please with getting to LW1 re: Value Types > > Consistency Checking > > Hi Tobi. ?Thanks for the write-up. > > > > To be brief, your proposed technique will seems to require lazier > > selection of calling > > sequences than what Karen proposed. ?Argument and return registers > > cannot be assigned > > to values if their size is unknown, which is the case before they > > are loaded. ?The JVM > > must wait as late as the first actual call (with non-null > > parameters) to determine calling > > sequences. > > > > Karen's proposal allows calling sequences to be determined at > > preparation (v-table pack) > > time, while yours requires them to be chosen much later, by the time > > of the first invocation > > of a given v-table slot. ?(For JVMs without vtables, a "v-table > > slot" really means an > > equivalence class \u0015of CONSTANT_[I*]Methodrefs equated by the > > transitive closure of > > override relations.) ?The bytecode instruction just before that > > invocation might have been > > a defaultvalue instruction on a previously unloaded class. ?This > > means the JVM needs > > to install traps in unused v-table slots, so it can decide calling > sequences. > > > > Karen's proposal, therefore, has the advantage of allowing the JVM > > more lead time > > freedom to set up v-table calling sequences, at preparation time. > > Yours requires > > just-in-time assignment of calling sequences, which seems more difficult. > > > > This leads to the question, what advantage did you find, with Packed > > Objects, from > > making calling sequence setup lazier? ?(I'm assuming that system > > scalarized arguments > > into multiple registers.) ?In other words, why is your phasing of > > the checks better than > > Karen's? > > > > ? John > > > > P.S. Background: > > > > So we are extending object references (Ljava/lang/Object;) to cover > > references to values > > also, at least in L-world. ?This gives a simple story for the > > interpreter and a fallback for > > less-optimized JIT-compiled code, but isn't enough to compete with > > statically-compiled > > languages. > > > > So the new requirement here is to make it possible for compiled > > calling sequences > > to use specialized representations for value parameters and returns. > > In particular, we > > often wish to use one or more machine registers to hold scalarized > > fields, and we wish > > to exclude null values (which require an extra encoding and impede > > some optimizations). > > > > A secondary requirement is that we wish to pick the compiled calling > > sequence once > > and not have to revise it. ?This implies picking the calling > > sequence no later than the first > > execution (compiled or interpreted) of any particular method, and > > getting it right the first > > time. > > > > Deoptimization of calling sequences?across override-trees of > > methods?is a trick we are > > holding in reserve, but it seems a risky research project rather > > than an understood technique. > > I think deoptimization at this scale hasn't been proven efficient > > yet, although it may be. > > > > It seems that in order to flatten, we are obligated to load value > > types more eagerly > > than object types. ?Value types can't "hide behind" a polymorphic > > reference; any > > user of a value type in its native form (not boxed) needs to "see" > > its complete field > > list, which requires loading the classfile. ?This is certainly true > > for object layout, > > where an object that contains a value-typed field must load that > > value type to see > > how much space it must reserve for it, in that object's flattened > > and packed layout. > > > > Given that we are going to routinely pre-load value type classfiles, > > it is reasonable > > to apply this technique in other places besides the layout of > > instances and fields. > > In particular, the layout of calling sequences is in many ways > > closely analogous > > to the layout of instances. ?(There is a deep symmetry between calls > > and objects, > > arising perhaps from the fact that function applications are > > isomorphic to curried > > functions or tuples. ?In any case, it seems to me that some such > > symmetry crops > > up between the O-O notions of field extension and virtual method > > extension, and > > so in JVM's treatment of object layout vs. its treatment of virtual > > dispatch, both of > > which are examined carefully at loading and preparation time, before > > execution.) > > > > The symmetry is only true for immutable class. The main difference > > is that curried functions usually doesn't expose the value of the > > bounded parameters while tuples let you access to those values. > > > > Anyway, if we are going to preload field classes, it is no great > > additional burden to > > preload argument classes too, if an appropriate signal can be > > defined (the VT list). > > It might even be reasonable to preload *all* VTs mentioned in the > > list, just to make > > the preloading process simpler and more predictable. ?I'm looking > > for reasons that > > this is a *bad* idea, so we can say in the end, "here's exactly why > > we had to make > > the loading logic for VTs so tricky"?if we must. > > > > I think the answer to the question of lazy loading of method > > parameter types is rooted to the question of what is a value type > > exactly for Java. > > Is it an optimization, a first class concept i.e one that should > > work as if it was integrated in the language from the beginning ? > > The other problem is the more we diverge from the class behavior, > > the harder it will be to allow a class to become a value type. > > > > I firmly believe that value type should be first class because they > > are useless in a lot of scenario if they are not. The main > > limitation of a value type is its immutable characteristic, what > > save them from uselessness is that their creation cost should be > > zero or very close to zero alleviating the burden of think in term > > of object creation and making us, developers, free to use functional > idioms. > > With that in mind, i believe a value type should not be "boxed" > > because it's not loaded yet (it can still be boxed due to separate > > compilation but that's another story) so value type present in > > method descriptor should be loaded eagerly. > > > > About loading all value type of the attribute ValueTypes, from one > > side Java has a strong tradition to not pay for the code you do not > > use. This power today's applications, an average application has an > > hundred jars as dependencies, if all value types are preloaded it's > > at waste of memory and cpu cycles. BTW, it's also what's make jaotc > > useless in its current incarnation because it AOTs things your > > application don't care. > > > > R?mi > > > > On Jul 6, 2018, at 8:38 AM, Tobi Ajila wrote: > > > > I would like to propose an alternative strategy, one that would > > effectively provide the same consistency checks outlined in http:// > > cr.openjdk.java.net/~acorn/value-types-consistency-checking-details.pdf > > without requiring eager loading of value types (VT) in the return/ > > args of methods during the preparation phase. This is born out of > > our experience with PackedObjects which took a very similar approach > > to the ValueTypes attribute. > > > > This proposal makes use of the existing ValueTypes attribute. In > > addition, it requires that each classloader keeps a registry of > > ?expected? VTs. > > > > Proposal > > -------------------------- > > The following steps occur in the loading phase: > > > > 1. Prior to loading the current class each type in the ValueTypes > > attribute is checked see if it is loaded. If it is, the type must be > > a VT or ICCE is thrown. Otherwise, the type is registered with the > > initiating classloaders expected VT registry (EVTR). > > > > 2. Pre-loading of ACC_FLATTENABLE instance fields follow the same > > rules as the ones specified in Karen's proposal. > > > > 3. Prior to loading the current class, if the current class is a VT > > it must be in the classloader's EVTR or ICCE is thrown. If the > > current class is not a VT and does appear in the EVTR, ICCE is thrown. > > > > In link phase prior to preparation: > > - Same as Karen's static field rules, "static fields declared with > > the ACC_FLATTENABLE flag set have their type pre-loaded..." > > > > In preparation phase: > > - Same as Karen's method overriding rules, "any method overriding > > needs to perform value type consistency checking between declarer of > > the overridden method ..." > > > > At resolution time: > > - Same as Karen?s CONSTANT_Class, field and method resolution rules > > --------------------------- > > > > The benefit of this approach is that as soon as anyone believes a > > class is a VT, it must be loaded as a VT or it fails. As a result, > > there is no inconsistency of loaded VTs. This proposal doesn't guard > > against cases where a class was not expecting a method return/arg > > type to be a VT but then later on turned out to be a VT when it was > > resolved. However, I think don?t think Karen?s proposal offered > > these guarantees either. > > > > > Some aspects of the implementation complexity that we have > > identified so far: > > > a) At method resolution time, if there is a mismatch in value type > > consistency > > > between the declaring class and the actual type in the signature, > > then there > > > is also a mismatch in all classes that have overridden the current > method. > > > This is particularly painful with default methods in interfaces. > > > > With this proposal the only possible inconsistency here is: > > Method has a return/arg type that is believed to not be a VT but > > turns out to be a VT. In this case any compiled code is doing pass > > by reference calling convention which works for both VT and non-VT > types. > > > > > b) We need to ensure that we catch all method resolution, through > > all of the > > > alternate accessor paths, including MethodHandles, VarHandles, > > Reflection, JNI, > > > so that we catch both the specification and implementation changes. > > > > All these cases are covered with the class loading consistency checks > (EVTR). > > > > > 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. > > > > same as above > > > > > 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. > > > > This wouldn?t be required in this proposal > > > > > 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. > > > > Typically, a method is run a few times before it is compiled > > (perhaps I?m making implementation assumptions?). At this stage, the > > return/arg types are either loaded or they are always null. This > > seems to suggest that deoptimization/recompilation scenario would > > not be a common occurrence. > > > > > > --Tobi > > > > > From: Karen Kinnear > > > To: valhalla-spec-experts > > > Date: 2018/06/26 10:32 AM > > > Subject: EG help please with getting to LW1 re: Value Types > > > Consistency Checking > > > Sent by: "valhalla-spec-experts" > > bounces at openjdk.java.net> > > > > > > Summary: Could we please allow eager loading for value types in the > > > locally declared method signatures > > > prior to preparation ?for LW1? > > > > > > Without that we seriously risk being able to offer an LW1 early > > > access binary for the JVMLS. > > > We believe it is more important to get this into people?s hands for > > > experimentation and feedback than > > > to delay the eager loading at this time. > > > > > > Details: > > > At our EG discussion on June 20, 2018, we discussed the proposal for > > > Value Types Consistency checking > > > at http://cr.openjdk.java.net/~acorn/value-types-consistency- > > > > checking-details.pdf > > > > > > Part of the proposal for checking value type consistency relative to > > > the actual type > > > was for locally declared methods. The proposal was to check the > > > value types in arguments/return type > > > before preparation of the declaring class. > > > > > > During the meeting, there was a request to explore whether we could > either: > > > 1) ?delay checking the value type consistency until an attempt to > > > resolve the method for invocation, or > > > 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. > > > > > > My understanding is that the goals of this are two-fold: > > > 1) if the method is never called, the rest of the code will > continue to run > > > 2) reduce eager loading > > > > > > We have started this investigation, and there is non-trivial > > > complexity in implementing either of these approaches, > > > and we would like more time to explore how to make this possible, > > > after making LW1 available. > > > > > > Some aspects of the implementation complexity that we have > > identified so far: > > > a) At method resolution time, if there is a mismatch in value type > > > consistency between the declaring class and the actual > > > type in the signature, then there is also a mismatch in all classes > > > that have overridden the current method. This is particularly > > > painful with default methods in interfaces. > > > b) We need to ensure that we catch all method resolution, through > > > all of the alternate accessor paths, including MethodHandles, > VarHandles, > > > Reflection, JNI, so that we catch both the specification and > > > implementation changes. > > > 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. > > > 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. > > > 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. > > > > > > thanks, > > > Karen > > >