From srikanth.adayapalam at oracle.com Mon Apr 2 12:21:08 2018 From: srikanth.adayapalam at oracle.com (srikanth.adayapalam at oracle.com) Date: Mon, 02 Apr 2018 12:21:08 +0000 Subject: hg: valhalla/valhalla: [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable Message-ID: <201804021221.w32CL8iq009586@aojmv0008.oracle.com> Changeset: 32ff82e6b770 Author: sadayapalam Date: 2018-04-02 17:50 +0530 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/32ff82e6b770 [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable + src/java.base/share/classes/java/lang/ValueBased.java ! src/java.compiler/share/classes/javax/lang/model/element/Modifier.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java + test/langtools/tools/javac/diags/examples/BadValueBasedAnno.java + test/langtools/tools/javac/diags/examples/SuspiciousNullMix.java + test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.java + test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.out ! test/langtools/tools/javac/valhalla/lworld-values/CastNullCheckTest.java + test/langtools/tools/javac/valhalla/lworld-values/CheckDefaultFlattenable.java ! test/langtools/tools/javac/valhalla/lworld-values/CheckNullCastable.out + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.java + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.out + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest10.out ! test/langtools/tools/javac/valhalla/lworld-values/FlattenableFlagTest.java ! test/langtools/tools/javac/valhalla/lworld-values/Point.java + test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.java + test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.out From srikanth.adayapalam at oracle.com Mon Apr 2 12:49:17 2018 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Mon, 2 Apr 2018 18:19:17 +0530 Subject: hg: valhalla/valhalla: [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable In-Reply-To: <201804021221.w32CL8iq009586@aojmv0008.oracle.com> References: <201804021221.w32CL8iq009586@aojmv0008.oracle.com> Message-ID: <7cf7a10a-192b-9bdb-768b-a9fa89370736@oracle.com> On Monday 02 April 2018 05:51 PM, srikanth.adayapalam at oracle.com wrote: > Changeset: 32ff82e6b770 > Author: sadayapalam > Date: 2018-04-02 17:50 +0530 > URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/32ff82e6b770 > > [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable Notes: ??? - Introduces a new annotation java.lang.ValueBased with which a __ByValue class may be decorated to indicate that it is a value based class evolving to become a value type. ??? - A __ByValue class without this annotation is considered a "pure" value type. ??? - ACC_FLATTENABLE defaults are flipped. A field whose type is a pure value type will automatically be flagged ACC_FLATTENABLE in its containing instance. ??? - For value based classes evolving to value types, the default flattenable status is NOT flattenable. Request flattening with the field modifier __Flattenable. ??? - A field whose type is a pure value type can opt out of flattening by using the new field modifier __NotFlattened ??? - Javac will redundantly accept __Flattenable with pure value typed fields and __NotFlattened with VBC typed fields. ??? - @ValueBased instances can be assigned null; null can be cast to them - this would result in a warning at compile time and not an error. (the unrealistic code pattern "null instanceof VBC" would also trigger a warning instead of error) ??? - Javac continues to implement a strict mode for pure value types (also see below) ??? - The lenient mode for @ValueBased classes is only for null assignment and (the unrealistic) casting of nulls to @ValueBased types. All identity related violations still result in an error. So does comparison of @ValueBased type instances. (Rationale: Karen originally asked for null related violations to be tolerated on the grounds that the documentation for value based classes does not expressly forbid these. However since == and != are expressly called out as inadvisable operations on value based classes, I have continued to treat them as errors - but I can be convinced to relax this) ???? - This change set does not identify and annotate the classes in JDK that are value based with @ValueBased. Only introduces the annotation and the new semantics for it. ??? - When an Object instance or a interface instance is cast to a value type, javac will insert a null check IFF the target of the cast is NOT @ValueBased. ??? - When compiling at a source level that is NOT __ByValue aware, if javac encounters a class file that has the ACC_VALUE bit set, the class will be demoted to @ValueBased even though it may not have been annotated with @ValueBased. This will result in null violation warnings to be emitted as appropriate. ???? - As of this change set the @ValueBased annotation is supposed to always be paired with __ByValue modifier (not checked). A new lint mode in consideration for JDK11 will implement sanity checks for @ValueBased classes that are candidates for evolution at a future date and so are not yet ready to be modified with __ByValue. ??? - Javac does not inject null checks with any opcode other than checkcast - see earlier mail raising some questions about the necessity of this with other opcodes. ??? - Expect some surprises in tests due to the flipping of defaults for flattening. Karen, please let me know if this adequately covers your proposal. Thanks! Srikanth > > + src/java.base/share/classes/java/lang/ValueBased.java > ! src/java.compiler/share/classes/javax/lang/model/element/Modifier.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java > ! src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties > ! src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java > + test/langtools/tools/javac/diags/examples/BadValueBasedAnno.java > + test/langtools/tools/javac/diags/examples/SuspiciousNullMix.java > + test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.java > + test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.out > ! test/langtools/tools/javac/valhalla/lworld-values/CastNullCheckTest.java > + test/langtools/tools/javac/valhalla/lworld-values/CheckDefaultFlattenable.java > ! test/langtools/tools/javac/valhalla/lworld-values/CheckNullCastable.out > + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.java > + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.out > + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest10.out > ! test/langtools/tools/javac/valhalla/lworld-values/FlattenableFlagTest.java > ! test/langtools/tools/javac/valhalla/lworld-values/Point.java > + test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.java > + test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.out > From david.simms at oracle.com Tue Apr 3 10:43:44 2018 From: david.simms at oracle.com (david.simms at oracle.com) Date: Tue, 03 Apr 2018 10:43:44 +0000 Subject: hg: valhalla/valhalla: Use __NotFlattened field modifier, remove tabs Message-ID: <201804031043.w33Ahj66008834@aojmv0008.oracle.com> Changeset: 7bb765d53478 Author: dsimms Date: 2018-04-03 12:43 +0200 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/7bb765d53478 Use __NotFlattened field modifier, remove tabs ! test/hotspot/jtreg/runtime/valhalla/valuetypes/FlattenableSemanticTest.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue1.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue2.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue3.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue4.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/UninitializedValueFieldsTest.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeCreation.java From karen.kinnear at oracle.com Tue Apr 3 21:10:42 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Tue, 3 Apr 2018 17:10:42 -0400 Subject: hg: valhalla/valhalla: [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable In-Reply-To: <7cf7a10a-192b-9bdb-768b-a9fa89370736@oracle.com> References: <201804021221.w32CL8iq009586@aojmv0008.oracle.com> <7cf7a10a-192b-9bdb-768b-a9fa89370736@oracle.com> Message-ID: <9B584D58-38E1-473F-A107-475D68A4464B@oracle.com> Srikanth, I very much appreciate your introducing this experimental annotation. I do appreciate that you believe this is not how we will want to handle this in the long-term, and that we want to use javac as an early warning system to prevent in the field surprise behavior. I believe we need some experimentation with migration and nullability, to find out if there are benefits to incremental opt-in vs. immediate behavior changes. So this allows us to do those experiments using java and javac. If we never had separate compilation, I wouldn?t expect to need this. We will all learn more by trying concrete examples. > On Apr 2, 2018, at 8:49 AM, Srikanth wrote: > > > > On Monday 02 April 2018 05:51 PM, srikanth.adayapalam at oracle.com wrote: >> Changeset: 32ff82e6b770 >> Author: sadayapalam >> Date: 2018-04-02 17:50 +0530 >> URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/32ff82e6b770 >> >> [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable > > Notes: > > - Introduces a new annotation java.lang.ValueBased with which a __ByValue class may be decorated to indicate that it is a value based class evolving to become a value type. > - A __ByValue class without this annotation is considered a "pure" value type. > - ACC_FLATTENABLE defaults are flipped. A field whose type is a pure value type will automatically be flagged ACC_FLATTENABLE in its containing instance. > - For value based classes evolving to value types, the default flattenable status is NOT flattenable. Request flattening with the field modifier __Flattenable. Yes - the key point here is that we can experiment with a two-step migration for value-based class. Step 1, migrate value-based class to be a value type, and default continues to be not flattenable and to be nullable. Step 2, field container author can opt-in via __Flattenable. > - A field whose type is a pure value type can opt out of flattening by using the new field modifier __NotFlattened Did you mean __NotFlattenable, i.e. nullable? My expectation was that at the classfile level, this would not generate ACC_FLATTENABLE. > - Javac will redundantly accept __Flattenable with pure value typed fields and __NotFlattened with VBC typed fields. > - @ValueBased instances can be assigned null; null can be cast to them - this would result in a warning at compile time and not an error. > (the unrealistic code pattern "null instanceof VBC" would also trigger a warning instead of error) Thank you for making those warnings. > - Javac continues to implement a strict mode for pure value types (also see below) > - The lenient mode for @ValueBased classes is only for null assignment and (the unrealistic) casting of nulls to @ValueBased types. All identity related violations still result in an error. So does comparison of @ValueBased type instances. (Rationale: Karen originally asked for null related violations to be tolerated on the grounds that the documentation for value based classes does not expressly forbid these. However since == and != are expressly called out as inadvisable operations on value based classes, I have continued to treat them as errors - but I can be convinced to relax this) My understanding of the model that John worked out was that == followed by null check and .equals pattern would work. If I understand what you are saying - that reflects what we may see at the bytecode level for backward compatibility. What you are describing is that javac will not allow identity checks for pure value types or ValueBased classes - because today that should already be disallowed. We are only testing out leniency for the nullability issues. So - given the distinction between source and existing bytecode handling - I agree with what you are proposing. > - This change set does not identify and annotate the classes in JDK that are value based with @ValueBased. Only introduces the annotation and the new semantics for it. Thank you. That allows all of us to experiment incrementally. > - When an Object instance or a interface instance is cast to a value type, javac will insert a null check IFF the target of the cast is NOT @ValueBased. > - When compiling at a source level that is NOT __ByValue aware, if javac encounters a class file that has the ACC_VALUE bit set, the class will be demoted to @ValueBased even though it may not have been annotated with @ValueBased. This will result in null violation warnings to be emitted as appropriate. Thank you for giving us another way to experiment. > - As of this change set the @ValueBased annotation is supposed to always be paired with __ByValue modifier (not checked). A new lint mode in consideration for JDK11 will implement sanity checks for @ValueBased classes that are candidates for evolution at a future date and so are not yet ready to be modified with __ByValue. Thank you for proposing the JDK11 lint mode. We are proposing JVM flags for JKDK11 as well - to check identity and nullability assumptions optionally. I think both of these will help migration. > - Javac does not inject null checks with any opcode other than checkcast - see earlier mail raising some questions about the necessity of this with other opcodes. > - Expect some surprises in tests due to the flipping of defaults for flattening. Thank you for the head?s up. > > Karen, please let me know if this adequately covers your proposal. many thanks, Karen > > Thanks! > Srikanth > > > > >> >> + src/java.base/share/classes/java/lang/ValueBased.java >> ! src/java.compiler/share/classes/javax/lang/model/element/Modifier.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java >> ! src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties >> ! src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java >> + test/langtools/tools/javac/diags/examples/BadValueBasedAnno.java >> + test/langtools/tools/javac/diags/examples/SuspiciousNullMix.java >> + test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.java >> + test/langtools/tools/javac/valhalla/lworld-values/BadValueBased.out >> ! test/langtools/tools/javac/valhalla/lworld-values/CastNullCheckTest.java >> + test/langtools/tools/javac/valhalla/lworld-values/CheckDefaultFlattenable.java >> ! test/langtools/tools/javac/valhalla/lworld-values/CheckNullCastable.out >> + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.java >> + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest.out >> + test/langtools/tools/javac/valhalla/lworld-values/DemoteToValueBasedTest10.out >> ! test/langtools/tools/javac/valhalla/lworld-values/FlattenableFlagTest.java >> ! test/langtools/tools/javac/valhalla/lworld-values/Point.java >> + test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.java >> + test/langtools/tools/javac/valhalla/lworld-values/ValueBasedWarningsTest.out >> > From srikanth.adayapalam at oracle.com Wed Apr 4 00:42:44 2018 From: srikanth.adayapalam at oracle.com (Srikanth) Date: Wed, 4 Apr 2018 06:12:44 +0530 Subject: hg: valhalla/valhalla: [lworld] Introduce a new annotation java.lang.ValueBased to distinguish migrating value based classes from pure value types and implement leniet semantics for them; Also flip the default for ACC_Flattenable In-Reply-To: <9B584D58-38E1-473F-A107-475D68A4464B@oracle.com> References: <201804021221.w32CL8iq009586@aojmv0008.oracle.com> <7cf7a10a-192b-9bdb-768b-a9fa89370736@oracle.com> <9B584D58-38E1-473F-A107-475D68A4464B@oracle.com> Message-ID: <8d54a026-eb6e-d376-cab3-b3f07a955707@oracle.com> On Wednesday 04 April 2018 02:40 AM, Karen Kinnear wrote: > Srikanth, > > I very much appreciate your introducing this experimental annotation. I do appreciate that you believe this > is not how we will want to handle this in the long-term, and that we want to use javac as an early warning > system to prevent in the field surprise behavior. > > I believe we need some experimentation with migration and nullability, to find out if there are benefits > to incremental opt-in vs. immediate behavior changes. So this allows us to do those experiments using > java and javac. If we never had separate compilation, I wouldn?t expect to need this. We will all learn more > by trying concrete examples. Sounds good, I can see a lenient mode that only warns on null mix also as a long term option for @ValueBased classes. >> - A field whose type is a pure value type can opt out of flattening by using the new field modifier __NotFlattened > Did you mean __NotFlattenable, i.e. nullable? > My expectation was that at the classfile level, this would not generate ACC_FLATTENABLE. I went with John's strawman for the experimental keyword i.e __NotFlattened. Yes, at the class file level this means not a new flag, but the absence of ACC_FLATTENABLE. > >> - Javac continues to implement a strict mode for pure value types (also see below) >> - The lenient mode for @ValueBased classes is only for null assignment and (the unrealistic) casting of nulls to @ValueBased types. All identity related violations still result in an error. So does comparison of @ValueBased type instances. (Rationale: Karen originally asked for null related violations to be tolerated on the grounds that the documentation for value based classes does not expressly forbid these. However since == and != are expressly called out as inadvisable operations on value based classes, I have continued to treat them as errors - but I can be convinced to relax this) > My understanding of the model that John worked out was that == followed by null check and .equals pattern would work. > If I understand what you are saying - that reflects what we may see at the bytecode level for backward compatibility. Not yet, I think the .equals call is not settled on yet, that is one of the proposals to attach a meaning to == and != and not the only one. As and when this gets finalized, I will follow up. Srikanth From tobias.hartmann at oracle.com Wed Apr 4 13:04:38 2018 From: tobias.hartmann at oracle.com (Tobias Hartmann) Date: Wed, 4 Apr 2018 15:04:38 +0200 Subject: [lworld] Initial C2 support for LWorld value types Message-ID: Hi, I implemented basic C2 support for LWorld value types. All compiler and runtime tests (with -Xcomp) now pass, except for ValueTypeArray.java because LWorld arrays are not yet supported and TestIntrinsics.java because some C2 intrinsics still need to be fixed. For now, C2 code deoptimizes if a value type argument or field is NULL (also, if we try to cast NULL to a value type). http://cr.openjdk.java.net/~thartmann/valhalla/lworld/webrev.00/ Gory details: - Added uncommon traps at method entry, field loading and checkcast if value type is null (for now, explicit null checks are used but this can be easily changed to use implicit ones) - Modified C2's type system to make value types a subtype of java.lang.Object (similar to how we handle arrays) and handle "mixtures" - Fixed merging of value types and (Object) oops by allocating value type in the source block - Fixed missing support for adding a new merge path during parsing - Added support for non-flattenable value type fields (loads should not return the default value) - Added TestLWorld.java which tests LWorld value types with C2 (more work needed to inc. coverage) - Fixed lots of whitespace/tabs/indentation errors in the runtime tests and re-enabled -Xcomp Although this work is far from being done, I think it's stable enough to be pushed so Roland can continue while I'm on vacation until April 24. Thanks, Tobias From tobias.hartmann at oracle.com Thu Apr 5 09:49:41 2018 From: tobias.hartmann at oracle.com (tobias.hartmann at oracle.com) Date: Thu, 05 Apr 2018 09:49:41 +0000 Subject: hg: valhalla/valhalla: [lworld] Initial C2 support for LWorld value types Message-ID: <201804050949.w359ngFA004499@aojmv0008.oracle.com> Changeset: 2c44fb9e8e97 Author: thartmann Date: 2018-04-05 11:49 +0200 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/2c44fb9e8e97 [lworld] Initial C2 support for LWorld value types ! src/hotspot/share/ci/ciField.cpp ! src/hotspot/share/ci/ciField.hpp ! src/hotspot/share/opto/compile.cpp ! src/hotspot/share/opto/graphKit.cpp ! src/hotspot/share/opto/memnode.cpp ! src/hotspot/share/opto/parse1.cpp ! src/hotspot/share/opto/parse2.cpp ! src/hotspot/share/opto/parse3.cpp ! src/hotspot/share/opto/type.cpp ! src/hotspot/share/opto/type.hpp ! src/hotspot/share/opto/valuetypenode.cpp ! src/hotspot/share/opto/valuetypenode.hpp + test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Empty.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/FlattenableSemanticTest.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/IntValue.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/JumboValue.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Long8Value.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Person.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Point.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Test8186715.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestInheritedValueTypeFields.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue1.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue2.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue3.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue4.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/UninitializedValueFieldsTest.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/VDefaultTest.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/VWithFieldTest.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeCreation.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeDensity.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeGenerator.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeGetField.java ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypesTest.java From david.simms at oracle.com Thu Apr 5 10:12:11 2018 From: david.simms at oracle.com (David Simms) Date: Thu, 5 Apr 2018 12:12:11 +0200 Subject: hg: valhalla/valhalla: [lworld] Initial C2 support for LWorld value types In-Reply-To: <201804050949.w359ngFA004499@aojmv0008.oracle.com> References: <201804050949.w359ngFA004499@aojmv0008.oracle.com> Message-ID: <72a60a50-67f5-aad7-3a02-1863e5399c04@oracle.com> Thanks Tobias ! On 05/04/18 11:49, tobias.hartmann at oracle.com wrote: > Changeset: 2c44fb9e8e97 > Author: thartmann > Date: 2018-04-05 11:49 +0200 > URL:http://hg.openjdk.java.net/valhalla/valhalla/rev/2c44fb9e8e97 > > [lworld] Initial C2 support for LWorld value types > > ! src/hotspot/share/ci/ciField.cpp > ! src/hotspot/share/ci/ciField.hpp > ! src/hotspot/share/opto/compile.cpp > ! src/hotspot/share/opto/graphKit.cpp > ! src/hotspot/share/opto/memnode.cpp > ! src/hotspot/share/opto/parse1.cpp > ! src/hotspot/share/opto/parse2.cpp > ! src/hotspot/share/opto/parse3.cpp > ! src/hotspot/share/opto/type.cpp > ! src/hotspot/share/opto/type.hpp > ! src/hotspot/share/opto/valuetypenode.cpp > ! src/hotspot/share/opto/valuetypenode.hpp > + test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Empty.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/FlattenableSemanticTest.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/IntValue.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/JumboValue.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Long8Value.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Person.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Point.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/Test8186715.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestInheritedValueTypeFields.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue1.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue2.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue3.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/TestValue4.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/UninitializedValueFieldsTest.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/VDefaultTest.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/VWithFieldTest.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeCreation.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeDensity.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeGenerator.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeGetField.java > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypesTest.java > From rwestrel at redhat.com Thu Apr 5 15:53:16 2018 From: rwestrel at redhat.com (Roland Westrelin) Date: Thu, 05 Apr 2018 17:53:16 +0200 Subject: Lworld and calling convention Message-ID: I started to work on bringing the calling convention from MVT to the Lworld. The first problem I hit is that when adapters are generated, classes of the method's signature may not have been loaded yet so it's impossible to tell which argument is a value and which is not. I then looked at what it would take to make adapter generation lazy. I have a prototype that seems to allow for lazy generation but then the question is what are the events that should trigger adapter generation? Going from interpreter to compiled code (where the i2c is needed) is fairly simple. We don't need the i2c until compiled code exists. We already load the classes of the signature before we trigger the compilation of the method so generating the adapters at that point would be fine. Going from compiled code to the interpreter seems much trickier. Let's say we compile m(). The compiler will trim some untaken paths and inline some methods so it's only possible to tell what call sites will be in the compiled m() as it's being compiled or once it's compiled. There's no guarantee that the classes of the signatures of these call sites are loaded when the call sites are compiled because, in legacy code, null may be passed for a value argument. We can't load classes as we compile the method because the compiler threads don't perform class loading. If compiled method m() has a call site: m2(v1, v2) and v1 and v2 are values (from 2 different classes), that call site may be compiled as: m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) (passing fields) if when the call site was compiled, classes for v1 & v2 are loaded. or: m2(v1, v2.f1, v2.f2, ..) (passing a reference to v1) if the class for v1 was not loaded when the call site was compiled or: m2(v1.f1, v1.f2, .., v2) if the class for v2 was not loaded when the call site was compiled or: m2(v1, v2) if both classes were not loaded when the call site was compiled. So for a single call site with 2 value arguments, there are 4 ways of compiling the call site. We could generate the adapters the first time the call in compiled method m() is executed (at call resolution time) but then we need to generate an adapter that matches how the call site was compiled. How do we know which of the 4 ways of performing the call it is? As code executes and classes get loaded, we might need several adapters generated. Maybe some m2() call site was compiled as: m2(v1, v2) but then one class got loaded so another one got compiled as: m2(v1, v2.f1, v2.f2, ..) and then another one as: m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) and we need 3 different c2i adapters. Add to this, that we can't deoptimize at call resolution time because compiled code only has debug info to resume execution after the call. I see 2 ways forward with this. Either we eagerly load classes of signatures so we can generate the adapters eagerly as is done currently. Or we refuse to compile a call site for which the classes of the signature are not loaded (replace the call with an uncommon trap and trigger class loading?). In that case, we would sometime drop perfectly good code. Comments? Roland. From frederic.parain at oracle.com Fri Apr 6 17:21:51 2018 From: frederic.parain at oracle.com (frederic.parain at oracle.com) Date: Fri, 06 Apr 2018 17:21:51 +0000 Subject: hg: valhalla/valhalla: Enabling quickening for getfield and putfield Message-ID: <201804061721.w36HLpOM001390@aojmv0008.oracle.com> Changeset: 7e2ff89e3bc3 Author: fparain Date: 2018-04-06 13:13 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/7e2ff89e3bc3 Enabling quickening for getfield and putfield ! src/hotspot/cpu/x86/frame_x86.cpp ! src/hotspot/cpu/x86/macroAssembler_x86.cpp ! src/hotspot/cpu/x86/templateTable_x86.cpp ! src/hotspot/share/interpreter/bytecodes.cpp ! src/hotspot/share/interpreter/interpreterRuntime.cpp ! src/hotspot/share/interpreter/interpreterRuntime.hpp ! src/hotspot/share/interpreter/templateTable.cpp ! src/hotspot/share/oops/cpCache.cpp ! src/hotspot/share/runtime/frame.cpp ! src/hotspot/share/runtime/globals.hpp ! test/hotspot/jtreg/runtime/valhalla/valuetypes/JumboValue.java + test/hotspot/jtreg/runtime/valhalla/valuetypes/QuickeningTest.java From frederic.parain at oracle.com Fri Apr 6 17:24:37 2018 From: frederic.parain at oracle.com (Frederic Parain) Date: Fri, 6 Apr 2018 13:24:37 -0400 Subject: hg: valhalla/valhalla: Enabling quickening for getfield and putfield In-Reply-To: <201804061721.w36HLpOM001390@aojmv0008.oracle.com> References: <201804061721.w36HLpOM001390@aojmv0008.oracle.com> Message-ID: <3694A9BF-359A-451F-A839-2E8AAF203349@oracle.com> This changeset enables bytecode quickening for both putfield and getfield. It also simplifies the support in the interpreter runtime for these bytecodes, The changeset also includes some clean up and it disables the thread local value buffering by default, as discussed during our last meeting. Testing have been done on both MacOSX and Linux. Fred > On Apr 6, 2018, at 13:21, frederic.parain at oracle.com wrote: > > Changeset: 7e2ff89e3bc3 > Author: fparain > Date: 2018-04-06 13:13 -0400 > URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/7e2ff89e3bc3 > > Enabling quickening for getfield and putfield > > ! src/hotspot/cpu/x86/frame_x86.cpp > ! src/hotspot/cpu/x86/macroAssembler_x86.cpp > ! src/hotspot/cpu/x86/templateTable_x86.cpp > ! src/hotspot/share/interpreter/bytecodes.cpp > ! src/hotspot/share/interpreter/interpreterRuntime.cpp > ! src/hotspot/share/interpreter/interpreterRuntime.hpp > ! src/hotspot/share/interpreter/templateTable.cpp > ! src/hotspot/share/oops/cpCache.cpp > ! src/hotspot/share/runtime/frame.cpp > ! src/hotspot/share/runtime/globals.hpp > ! test/hotspot/jtreg/runtime/valhalla/valuetypes/JumboValue.java > + test/hotspot/jtreg/runtime/valhalla/valuetypes/QuickeningTest.java > From frederic.parain at oracle.com Fri Apr 6 17:25:08 2018 From: frederic.parain at oracle.com (Frederic Parain) Date: Fri, 6 Apr 2018 13:25:08 -0400 Subject: hg: valhalla/valhalla: Enabling quickening for getfield and putfield In-Reply-To: <3694A9BF-359A-451F-A839-2E8AAF203349@oracle.com> References: <201804061721.w36HLpOM001390@aojmv0008.oracle.com> <3694A9BF-359A-451F-A839-2E8AAF203349@oracle.com> Message-ID: Webrev: http://cr.openjdk.java.net/~fparain/fixes2/webrev.00/ > On Apr 6, 2018, at 13:24, Frederic Parain wrote: > > This changeset enables bytecode quickening for both putfield and getfield. > It also simplifies the support in the interpreter runtime for these bytecodes, > The changeset also includes some clean up and it disables the thread local > value buffering by default, as discussed during our last meeting. > > Testing have been done on both MacOSX and Linux. > > Fred > > >> On Apr 6, 2018, at 13:21, frederic.parain at oracle.com wrote: >> >> Changeset: 7e2ff89e3bc3 >> Author: fparain >> Date: 2018-04-06 13:13 -0400 >> URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/7e2ff89e3bc3 >> >> Enabling quickening for getfield and putfield >> >> ! src/hotspot/cpu/x86/frame_x86.cpp >> ! src/hotspot/cpu/x86/macroAssembler_x86.cpp >> ! src/hotspot/cpu/x86/templateTable_x86.cpp >> ! src/hotspot/share/interpreter/bytecodes.cpp >> ! src/hotspot/share/interpreter/interpreterRuntime.cpp >> ! src/hotspot/share/interpreter/interpreterRuntime.hpp >> ! src/hotspot/share/interpreter/templateTable.cpp >> ! src/hotspot/share/oops/cpCache.cpp >> ! src/hotspot/share/runtime/frame.cpp >> ! src/hotspot/share/runtime/globals.hpp >> ! test/hotspot/jtreg/runtime/valhalla/valuetypes/JumboValue.java >> + test/hotspot/jtreg/runtime/valhalla/valuetypes/QuickeningTest.java >> > From david.simms at oracle.com Tue Apr 10 14:49:06 2018 From: david.simms at oracle.com (David Simms) Date: Tue, 10 Apr 2018 16:49:06 +0200 Subject: Value type hash code Message-ID: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> After prototyping "hashCode()" for value types, here's a few observations and thoughts... * "The general contract of hashCode" [1] is unchanged. * The default implementation, if no user implementation is provided, is assumed to be completely based upon the entire contents of the value (there's nothing else to go on). o The current "Object" implementation, both its generation and object header hash caching are completely inappropriate for value types. o The VM cannot pretend to know one field is more significant than another. o Large values will benefit from user implementation to provide efficiency. o Whilst the VM may provide a default implementation for safety, a "javac" generated method would be optimal (can be optimized by the JIT, includes inlining). * Values containing references whose contents are mutable pose a problem, their hash code is only as stable as the contents of the whole object graph. o Objects may suffer similar problems, difficult to say this is any more important for values. Except to say values are supposed to be "immutable" but references may break this quality, perhaps "javac" could warn when value fields are mutable objects (not always possible, e.g. field reference to an interface). I assume a the default implementation should look something like this (only with concrete fields, not reflection): ??????? int hc = 0; ??????? for (Field field : val.getClass().getDeclaredFields()) { ??????????? if (Modifier.isStatic(field.getModifiers())) continue; ??????????? // Using the generic JDK hash for all types ??????????? hc = (31 * hc) + Objects.hashCode(field.get(val)); ??????? } ??????? return hc; This algorithm assumes the VM implements calls to reference field's hashCode(), and encodes primitives the same as their boxed JDK counter-parts (e.g. "Long.hashCode(long l)" does not generically hash two int size chunks, rather it xors hi and lo, Boolean is another interesting example 1231 || 1237). Unclear if this is actually important...however, this example: ??? final __ByValue class MyInt implements Comparable { ??? ??? final int value; ??? ??? //.... ??? } The user is free to explicitly delegate to "Integer.hashCode(int val)", but is it just more natural that the default works this way ? Alternative VM implementations might hash over value data payload including field padding. With h/w support (suitable checksum instruction) there might be some performance gain for large values, but then if you introduce object references, said h/w support would get broken. Said implementation would be dependent on field layout, and not give the same result on different platforms. Whilst the Javadoc states hashing "need not remain consistent from one execution of an application to another execution of the same application." [1], I'm wondering how many folks rely on consistent hashing, more than nobody I would fear. Lastly hashing large amounts of data per value seems an unlikely general use-case. Cheers /David Simms [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() From forax at univ-mlv.fr Tue Apr 10 15:05:05 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 10 Apr 2018 17:05:05 +0200 (CEST) Subject: Value type hash code In-Reply-To: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: <69605145.844843.1523372705213.JavaMail.zimbra@u-pem.fr> In my opinion, the VM should reject the value type that doesn't defines equals, hashCode and toString because a value type doesn't inherits from Object, so there is no default implementations provided. R?mi ----- Mail original ----- > De: "David Simms" > ?: "valhalla-dev" > Envoy?: Mardi 10 Avril 2018 16:49:06 > Objet: Value type hash code > After prototyping "hashCode()" for value types, here's a few > observations and thoughts... > > * "The general contract of hashCode" [1] is unchanged. > * The default implementation, if no user implementation is provided, > is assumed to be completely based upon the entire contents of the > value (there's nothing else to go on). > o The current "Object" implementation, both its generation and > object header hash caching are completely inappropriate for > value types. > o The VM cannot pretend to know one field is more significant than > another. > o Large values will benefit from user implementation to provide > efficiency. > o Whilst the VM may provide a default implementation for safety, a > "javac" generated method would be optimal (can be optimized by > the JIT, includes inlining). > * Values containing references whose contents are mutable pose a > problem, their hash code is only as stable as the contents of the > whole object graph. > o Objects may suffer similar problems, difficult to say this is > any more important for values. Except to say values are supposed > to be "immutable" but references may break this quality, perhaps > "javac" could warn when value fields are mutable objects (not > always possible, e.g. field reference to an interface). > > I assume a the default implementation should look something like this > (only with concrete fields, not reflection): > > ??????? int hc = 0; > ??????? for (Field field : val.getClass().getDeclaredFields()) { > ??????????? if (Modifier.isStatic(field.getModifiers())) continue; > > ??????????? // Using the generic JDK hash for all types > ??????????? hc = (31 * hc) + Objects.hashCode(field.get(val)); > ??????? } > ??????? return hc; > > This algorithm assumes the VM implements calls to reference field's > hashCode(), and encodes primitives the same as their boxed JDK > counter-parts (e.g. "Long.hashCode(long l)" does not generically hash > two int size chunks, rather it xors hi and lo, Boolean is another > interesting example 1231 || 1237). Unclear if this is actually > important...however, this example: > > ??? final __ByValue class MyInt implements Comparable { > ??? ??? final int value; > ??? ??? //.... > ??? } > > The user is free to explicitly delegate to "Integer.hashCode(int val)", > but is it just more natural that the default works this way ? > Alternative VM implementations might hash over value data payload > including field padding. With h/w support (suitable checksum > instruction) there might be some performance gain for large values, but > then if you introduce object references, said h/w support would get > broken. Said implementation would be dependent on field layout, and not > give the same result on different platforms. Whilst the Javadoc states > hashing "need not remain consistent from one execution of an application > to another execution of the same application." [1], I'm wondering how > many folks rely on consistent hashing, more than nobody I would fear. > Lastly hashing large amounts of data per value seems an unlikely general > use-case. > > > Cheers > /David Simms > > [1] > https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() From gil at azul.com Tue Apr 10 16:14:13 2018 From: gil at azul.com (Gil Tene) Date: Tue, 10 Apr 2018 16:14:13 +0000 Subject: Value type hash code In-Reply-To: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: Need to watch out for recursion: A value type instance x may include a reference to a mutable object o that may contain a value type field o.v, and may have provided a hashCode() implementation that depends on the value of o.v.hasCode(). If o.v = x, both x.hashCode() and o.hashCode() will infinitely recurse. One may argue that a hashCode() override can cause this sort of recursion in other ways, e.g. a class C that overrides hashCode() and contains a reference r of type C can similarly infinitely recurse if o.r = o; However, such infinite recursion can (currently) occur only if all hashCode() methods in the recursion chain have been overridden (which lets us claim user error). The problem with the default implementation suggested below is that infinite recursion can now occur with an override in one place in the chain? A way around this, which will also provide the benefit of making the default hashcode of value types stable in all cases, would be for the default value type hashCode() implementation to use the identity hashcode of each object referred from a reference field, rather than the hasCode() implementation of the referred object. So I'd propose a change to: int hc = 0; for (Field field : val.getClass().getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; // Use Objects.hasCode for primitives and value classes; use identify hashcode for objects: int fieldHashCode = (field.getType().isPrimitive() || field.getType().isValue()) ? Objects.hashCode(field.get(val)) : System.identityHashCode(field.get(val)); // Using the generic JDK hash for all types hc = (31 * hc) + fieldHashCode; } return hc; ? Gil. > On Apr 10, 2018, at 7:49 AM, David Simms wrote: > > > After prototyping "hashCode()" for value types, here's a few observations and thoughts... > > * "The general contract of hashCode" [1] is unchanged. > * The default implementation, if no user implementation is provided, > is assumed to be completely based upon the entire contents of the > value (there's nothing else to go on). > o The current "Object" implementation, both its generation and > object header hash caching are completely inappropriate for > value types. > o The VM cannot pretend to know one field is more significant than > another. > o Large values will benefit from user implementation to provide > efficiency. > o Whilst the VM may provide a default implementation for safety, a > "javac" generated method would be optimal (can be optimized by > the JIT, includes inlining). > * Values containing references whose contents are mutable pose a > problem, their hash code is only as stable as the contents of the > whole object graph. > o Objects may suffer similar problems, difficult to say this is > any more important for values. Except to say values are supposed > to be "immutable" but references may break this quality, perhaps > "javac" could warn when value fields are mutable objects (not > always possible, e.g. field reference to an interface). > > I assume a the default implementation should look something like this (only with concrete fields, not reflection): > > int hc = 0; > for (Field field : val.getClass().getDeclaredFields()) { > if (Modifier.isStatic(field.getModifiers())) continue; > > // Using the generic JDK hash for all types > hc = (31 * hc) + Objects.hashCode(field.get(val)); > } > return hc; > > This algorithm assumes the VM implements calls to reference field's hashCode(), and encodes primitives the same as their boxed JDK counter-parts (e.g. "Long.hashCode(long l)" does not generically hash two int size chunks, rather it xors hi and lo, Boolean is another interesting example 1231 || 1237). Unclear if this is actually important...however, this example: > > final __ByValue class MyInt implements Comparable { > final int value; > //.... > } > > The user is free to explicitly delegate to "Integer.hashCode(int val)", but is it just more natural that the default works this way ? Alternative VM implementations might hash over value data payload including field padding. With h/w support (suitable checksum instruction) there might be some performance gain for large values, but then if you introduce object references, said h/w support would get broken. Said implementation would be dependent on field layout, and not give the same result on different platforms. Whilst the Javadoc states hashing "need not remain consistent from one execution of an application to another execution of the same application." [1], I'm wondering how many folks rely on consistent hashing, more than nobody I would fear. Lastly hashing large amounts of data per value seems an unlikely general use-case. > > > Cheers > /David Simms > > [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() > From me at yawk.at Wed Apr 11 06:19:16 2018 From: me at yawk.at (Jonas Konrad) Date: Wed, 11 Apr 2018 08:19:16 +0200 Subject: Value type hash code In-Reply-To: References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: <99c45b00-a2b8-d0ef-86b6-cbe04b72285e@yawk.at> But this is already a problem in other contexts, such as lomboks @EqualsAndHashCode, auto-value, or IDE-generated eq/hc. I think defaulting to identity hash for references would make default hc/eq basically useless in cases where you have references in the value and would be unexpected to a user. If you have circular object graphs you need to worry about this anyway (also for toString for example), and that can be done best inside the mutable object. - Jonas On 2018-04-10 18:14, Gil Tene wrote: > Need to watch out for recursion: > > A value type instance x may include a reference to a mutable object o that may contain a value type field o.v, and may have provided a hashCode() implementation that depends on the value of o.v.hasCode(). If o.v = x, both x.hashCode() and o.hashCode() will infinitely recurse. > > One may argue that a hashCode() override can cause this sort of recursion in other ways, e.g. a class C that overrides hashCode() and contains a reference r of type C can similarly infinitely recurse if o.r = o; However, such infinite recursion can (currently) occur only if all hashCode() methods in the recursion chain have been overridden (which lets us claim user error). > > The problem with the default implementation suggested below is that infinite recursion can now occur with an override in one place in the chain? > > A way around this, which will also provide the benefit of making the default hashcode of value types stable in all cases, would be for the default value type hashCode() implementation to use the identity hashcode of each object referred from a reference field, rather than the hasCode() implementation of the referred object. > > So I'd propose a change to: > > int hc = 0; > for (Field field : val.getClass().getDeclaredFields()) { > if (Modifier.isStatic(field.getModifiers())) continue; > > // Use Objects.hasCode for primitives and value classes; use identify hashcode for objects: > int fieldHashCode = (field.getType().isPrimitive() || field.getType().isValue()) ? > Objects.hashCode(field.get(val)) : System.identityHashCode(field.get(val)); > > // Using the generic JDK hash for all types > hc = (31 * hc) + fieldHashCode; > } > return hc; > > > ? Gil. > >> On Apr 10, 2018, at 7:49 AM, David Simms wrote: >> >> >> After prototyping "hashCode()" for value types, here's a few observations and thoughts... >> >> * "The general contract of hashCode" [1] is unchanged. >> * The default implementation, if no user implementation is provided, >> is assumed to be completely based upon the entire contents of the >> value (there's nothing else to go on). >> o The current "Object" implementation, both its generation and >> object header hash caching are completely inappropriate for >> value types. >> o The VM cannot pretend to know one field is more significant than >> another. >> o Large values will benefit from user implementation to provide >> efficiency. >> o Whilst the VM may provide a default implementation for safety, a >> "javac" generated method would be optimal (can be optimized by >> the JIT, includes inlining). >> * Values containing references whose contents are mutable pose a >> problem, their hash code is only as stable as the contents of the >> whole object graph. >> o Objects may suffer similar problems, difficult to say this is >> any more important for values. Except to say values are supposed >> to be "immutable" but references may break this quality, perhaps >> "javac" could warn when value fields are mutable objects (not >> always possible, e.g. field reference to an interface). >> >> I assume a the default implementation should look something like this (only with concrete fields, not reflection): >> >> int hc = 0; >> for (Field field : val.getClass().getDeclaredFields()) { >> if (Modifier.isStatic(field.getModifiers())) continue; >> >> // Using the generic JDK hash for all types >> hc = (31 * hc) + Objects.hashCode(field.get(val)); >> } >> return hc; >> >> This algorithm assumes the VM implements calls to reference field's hashCode(), and encodes primitives the same as their boxed JDK counter-parts (e.g. "Long.hashCode(long l)" does not generically hash two int size chunks, rather it xors hi and lo, Boolean is another interesting example 1231 || 1237). Unclear if this is actually important...however, this example: >> >> final __ByValue class MyInt implements Comparable { >> final int value; >> //.... >> } >> >> The user is free to explicitly delegate to "Integer.hashCode(int val)", but is it just more natural that the default works this way ? Alternative VM implementations might hash over value data payload including field padding. With h/w support (suitable checksum instruction) there might be some performance gain for large values, but then if you introduce object references, said h/w support would get broken. Said implementation would be dependent on field layout, and not give the same result on different platforms. Whilst the Javadoc states hashing "need not remain consistent from one execution of an application to another execution of the same application." [1], I'm wondering how many folks rely on consistent hashing, more than nobody I would fear. Lastly hashing large amounts of data per value seems an unlikely general use-case. >> >> >> Cheers >> /David Simms >> >> [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() >> > From daniel.smith at oracle.com Wed Apr 11 14:13:51 2018 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 11 Apr 2018 08:13:51 -0600 Subject: Value type hash code In-Reply-To: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> > On Apr 10, 2018, at 8:49 AM, David Simms wrote: > > * Values containing references whose contents are mutable pose a > problem, their hash code is only as stable as the contents of the > whole object graph. There's some flexibility in how we name operations, but let's observe that there are two pairs of operations to consider: substitutable/substitutableHash: recur on value fields, use acmp on reference fields deepEquals/deepHash: recur on value fields, use 'equals' on reference fields I think my expectation has been that substitutable/substitutableHash would be the default behavior of equals/hashCode, with the capability for users to override this if they're confident it's safe. (And with the ability to fall back to the default behavior with System.identityHashCode or something similar.) ?Dan From gil at azul.com Wed Apr 11 14:20:07 2018 From: gil at azul.com (Gil Tene) Date: Wed, 11 Apr 2018 14:20:07 +0000 Subject: Value type hash code In-Reply-To: <99c45b00-a2b8-d0ef-86b6-cbe04b72285e@yawk.at> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> , <99c45b00-a2b8-d0ef-86b6-cbe04b72285e@yawk.at> Message-ID: <5D8BDF50-9108-4F44-820A-3ADCA5AD57D8@azul.com> Sent from my iPad On Apr 10, 2018, at 11:19 PM, Jonas Konrad > wrote: But this is already a problem in other contexts, such as lomboks @EqualsAndHashCode, auto-value, or IDE-generated eq/hc. Those are user-code things, that need to take responsibility for their actions. It is quite different if the spec?ed behavior of the JDK makes recursive loops happen without user code (which both Lombok and IDEs are) overriding all hashCode() implementations in the recursion loop. Arrays.hashcode() (e.g. https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) ) had to deal with the same issue, and similarly chose to use the identity hashcode of any contained arrays rather than their contents. I think that is the right, robust choice fir a default behavior. I think defaulting to identity hash for references would make default hc/eq basically useless in cases where you have references in the value and would be unexpected to a user. It is less unexpected than the hashcode of an immutable value being mutable by default (if it contains references to objects). And less unexpected than being able to create a recursion loop with a single override in a chain of defaults. If you have circular object graphs you need to worry about this anyway (also for toString for example), and that can be done best inside the mutable object. - Jonas On 2018-04-10 18:14, Gil Tene wrote: Need to watch out for recursion: A value type instance x may include a reference to a mutable object o that may contain a value type field o.v, and may have provided a hashCode() implementation that depends on the value of o.v.hasCode(). If o.v = x, both x.hashCode() and o.hashCode() will infinitely recurse. One may argue that a hashCode() override can cause this sort of recursion in other ways, e.g. a class C that overrides hashCode() and contains a reference r of type C can similarly infinitely recurse if o.r = o; However, such infinite recursion can (currently) occur only if all hashCode() methods in the recursion chain have been overridden (which lets us claim user error). The problem with the default implementation suggested below is that infinite recursion can now occur with an override in one place in the chain? A way around this, which will also provide the benefit of making the default hashcode of value types stable in all cases, would be for the default value type hashCode() implementation to use the identity hashcode of each object referred from a reference field, rather than the hasCode() implementation of the referred object. So I'd propose a change to: int hc = 0; for (Field field : val.getClass().getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; // Use Objects.hasCode for primitives and value classes; use identify hashcode for objects: int fieldHashCode = (field.getType().isPrimitive() || field.getType().isValue()) ? Objects.hashCode(field.get(val)) : System.identityHashCode(field.get(val)); // Using the generic JDK hash for all types hc = (31 * hc) + fieldHashCode; } return hc; ? Gil. On Apr 10, 2018, at 7:49 AM, David Simms > wrote: After prototyping "hashCode()" for value types, here's a few observations and thoughts... * "The general contract of hashCode" [1] is unchanged. * The default implementation, if no user implementation is provided, is assumed to be completely based upon the entire contents of the value (there's nothing else to go on). o The current "Object" implementation, both its generation and object header hash caching are completely inappropriate for value types. o The VM cannot pretend to know one field is more significant than another. o Large values will benefit from user implementation to provide efficiency. o Whilst the VM may provide a default implementation for safety, a "javac" generated method would be optimal (can be optimized by the JIT, includes inlining). * Values containing references whose contents are mutable pose a problem, their hash code is only as stable as the contents of the whole object graph. o Objects may suffer similar problems, difficult to say this is any more important for values. Except to say values are supposed to be "immutable" but references may break this quality, perhaps "javac" could warn when value fields are mutable objects (not always possible, e.g. field reference to an interface). I assume a the default implementation should look something like this (only with concrete fields, not reflection): int hc = 0; for (Field field : val.getClass().getDeclaredFields()) { if (Modifier.isStatic(field.getModifiers())) continue; // Using the generic JDK hash for all types hc = (31 * hc) + Objects.hashCode(field.get(val)); } return hc; This algorithm assumes the VM implements calls to reference field's hashCode(), and encodes primitives the same as their boxed JDK counter-parts (e.g. "Long.hashCode(long l)" does not generically hash two int size chunks, rather it xors hi and lo, Boolean is another interesting example 1231 || 1237). Unclear if this is actually important...however, this example: final __ByValue class MyInt implements Comparable { final int value; //.... } The user is free to explicitly delegate to "Integer.hashCode(int val)", but is it just more natural that the default works this way ? Alternative VM implementations might hash over value data payload including field padding. With h/w support (suitable checksum instruction) there might be some performance gain for large values, but then if you introduce object references, said h/w support would get broken. Said implementation would be dependent on field layout, and not give the same result on different platforms. Whilst the Javadoc states hashing "need not remain consistent from one execution of an application to another execution of the same application." [1], I'm wondering how many folks rely on consistent hashing, more than nobody I would fear. Lastly hashing large amounts of data per value seems an unlikely general use-case. Cheers /David Simms [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() From brian.goetz at oracle.com Wed Apr 11 15:38:48 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 11 Apr 2018 11:38:48 -0400 Subject: Value type hash code In-Reply-To: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: <0c1912e6-758e-3b27-f571-25b79d5b6f6c@oracle.com> On the topic of mechanics, there's some overlap between what we do for values and what we do for records (and of course their intersection, value records.)? We've got an indy bootstrap that you load up with a sequence of field-getter method handles, and it produces an MH that does short-circuit lazy map-reduce over the values for both equals and hashCode.? Eventually we'll make these codebases line up. On 4/10/2018 10:49 AM, David Simms wrote: > > After prototyping "hashCode()" for value types, here's a few > observations and thoughts... > > ?* "The general contract of hashCode" [1] is unchanged. > ?* The default implementation, if no user implementation is provided, > ?? is assumed to be completely based upon the entire contents of the > ?? value (there's nothing else to go on). > ???? o The current "Object" implementation, both its generation and > ?????? object header hash caching are completely inappropriate for > ?????? value types. > ???? o The VM cannot pretend to know one field is more significant than > ?????? another. > ???? o Large values will benefit from user implementation to provide > ?????? efficiency. > ???? o Whilst the VM may provide a default implementation for safety, a > ?????? "javac" generated method would be optimal (can be optimized by > ?????? the JIT, includes inlining). > ?* Values containing references whose contents are mutable pose a > ?? problem, their hash code is only as stable as the contents of the > ?? whole object graph. > ???? o Objects may suffer similar problems, difficult to say this is > ?????? any more important for values. Except to say values are supposed > ?????? to be "immutable" but references may break this quality, perhaps > ?????? "javac" could warn when value fields are mutable objects (not > ?????? always possible, e.g. field reference to an interface). > > I assume a the default implementation should look something like this > (only with concrete fields, not reflection): > > ??????? int hc = 0; > ??????? for (Field field : val.getClass().getDeclaredFields()) { > ??????????? if (Modifier.isStatic(field.getModifiers())) continue; > > ??????????? // Using the generic JDK hash for all types > ??????????? hc = (31 * hc) + Objects.hashCode(field.get(val)); > ??????? } > ??????? return hc; > > This algorithm assumes the VM implements calls to reference field's > hashCode(), and encodes primitives the same as their boxed JDK > counter-parts (e.g. "Long.hashCode(long l)" does not generically hash > two int size chunks, rather it xors hi and lo, Boolean is another > interesting example 1231 || 1237). Unclear if this is actually > important...however, this example: > > ??? final __ByValue class MyInt implements Comparable { > ??? ??? final int value; > ??? ??? //.... > ??? } > > The user is free to explicitly delegate to "Integer.hashCode(int > val)", but is it just more natural that the default works this way ? > Alternative VM implementations might hash over value data payload > including field padding. With h/w support (suitable checksum > instruction) there might be some performance gain for large values, > but then if you introduce object references, said h/w support would > get broken. Said implementation would be dependent on field layout, > and not give the same result on different platforms. Whilst the > Javadoc states hashing "need not remain consistent from one execution > of an application to another execution of the same application." [1], > I'm wondering how many folks rely on consistent hashing, more than > nobody I would fear. Lastly hashing large amounts of data per value > seems an unlikely general use-case. > > > Cheers > /David Simms > > [1] > https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() > > From brian.goetz at oracle.com Wed Apr 11 15:42:37 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 11 Apr 2018 11:42:37 -0400 Subject: Value type hash code In-Reply-To: <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> Message-ID: One of the operations we can name is ==.? I think the substitution check is the most reasonable interpretation of ==, but I don't really see how we can avoid recurring on .equals() for the equals() implementation.? Otherwise, this will violate basic user expectations, such as: ??? value record StringBox(String s); I think values would be near-useless under such an interpretation of equals(). On 4/11/2018 10:13 AM, Dan Smith wrote: >> On Apr 10, 2018, at 8:49 AM, David Simms wrote: >> >> * Values containing references whose contents are mutable pose a >> problem, their hash code is only as stable as the contents of the >> whole object graph. > There's some flexibility in how we name operations, but let's observe that there are two pairs of operations to consider: > > substitutable/substitutableHash: recur on value fields, use acmp on reference fields > deepEquals/deepHash: recur on value fields, use 'equals' on reference fields > > I think my expectation has been that substitutable/substitutableHash would be the default behavior of equals/hashCode, with the capability for users to override this if they're confident it's safe. (And with the ability to fall back to the default behavior with System.identityHashCode or something similar.) > > ?Dan From me at yawk.at Wed Apr 11 15:43:44 2018 From: me at yawk.at (Jonas Konrad) Date: Wed, 11 Apr 2018 17:43:44 +0200 Subject: Value type hash code In-Reply-To: <5D8BDF50-9108-4F44-820A-3ADCA5AD57D8@azul.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <99c45b00-a2b8-d0ef-86b6-cbe04b72285e@yawk.at> <5D8BDF50-9108-4F44-820A-3ADCA5AD57D8@azul.com> Message-ID: > Arrays.hashcode() (e.g. > https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) ) > had to deal with the same issue, and similarly chose to use the identity > hashcode of any contained arrays rather than their contents. I think > that is the right, robust choice fir a default behavior. I do not agree that that is the same. Yes, Arrays.equals and .hashCode are shallow, but that is just an artefact of array equality being defined as it is (as identity). I don't think it's anyone's goal to repeat the same mistakes as the array api and need Values.deepHashCode later :) Had arrays had a proper eq/hc instead of simple identity from the start, they would've been implemented with possible infinite recursion as well. Since basically nobody uses array eq/hc I don't think the current behaviour is very useful - we can't change it for arrays now, but we don't have to do the same for values. The 'new' API which does this 'right' is List, and List uses member eq/hc. I don't think it really matters if I introduce a circular dependency through a value type and get infinite recursion or I introduce a circular dependency through a List and get infinite recursion. Other examples are 'value-based' classes in the JDK right now, such as Optional - in fact it has the same issues you are talking about - but it does not use identity either. The reason I bring up lombok/auto-value/IDEs is because this is how it is implemented most commonly (by far) in the real world. If you want the default eq/hc to be actually useful to end users, that's how to do it. This also adds another unintuitive difference between value and non-value types (unless you override eq/hc yourself) which seems pretty arbitrary to me. - Jonas On 04/11/2018 04:20 PM, Gil Tene wrote: > > > Sent from my iPad > > On Apr 10, 2018, at 11:19 PM, Jonas Konrad > wrote: > >> But this is already a problem in other contexts, such as lomboks >> @EqualsAndHashCode, auto-value, or IDE-generated eq/hc. > > Those are user-code things, that need to take responsibility for their > actions. It is quite different if the spec?ed behavior of the JDK makes > recursive loops happen without user code (which both Lombok and IDEs > are) overriding all hashCode() implementations in the recursion loop. > > Arrays.hashcode() (e.g. > https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D)?) > had to deal with the same issue, and similarly chose to use the identity > hashcode of any contained arrays rather than their contents. I think > that is the right, robust choice fir a default behavior. > >> >> I think defaulting to identity hash for references would make default >> hc/eq basically useless in cases where you have references in the >> value and would be unexpected to a user. > > It is less unexpected than the hashcode of an immutable value being > mutable by default (if it contains references to objects). And less > unexpected than being able to create a recursion loop with a single > override in a chain of defaults. > >> If you have circular object graphs you need to worry about this anyway >> (also for toString for example), and that can be done best inside the >> mutable object. >> >> - Jonas >> >> On 2018-04-10 18:14, Gil Tene wrote: >>> Need to watch out for recursion: >>> A value type instance x may include a reference to a mutable object o >>> that may contain a value type field o.v, and may have provided a >>> hashCode() implementation that depends on the value of o.v.hasCode(). >>> If o.v = x, both x.hashCode() and o.hashCode() will infinitely recurse. >>> One may argue that a hashCode() override can cause this sort of >>> recursion in other ways, e.g. a class C that overrides hashCode() and >>> contains a reference r of type C can similarly infinitely recurse if >>> o.r = o; ?However, such infinite recursion can (currently) occur only >>> if all hashCode() methods in the recursion chain have been overridden >>> (which lets us claim user error). >>> The problem with the default implementation suggested below is that >>> infinite recursion can now occur with an override in one place in the >>> chain? >>> A way around this, which will also provide the benefit of making the >>> default hashcode of value types stable in all cases, would be for the >>> default value type hashCode() implementation to use the identity >>> hashcode of each object referred from a reference field, rather than >>> the hasCode() implementation of the referred object. >>> So I'd propose a change to: >>> ????????int hc = 0; >>> ????????for (Field field : val.getClass().getDeclaredFields()) { >>> ????????????if (Modifier.isStatic(field.getModifiers())) continue; >>> ? ? ???// Use Objects.hasCode for primitives and value classes; use >>> identify hashcode for objects: >>> ????????????int fieldHashCode = (field.getType().isPrimitive() || >>> field.getType().isValue()) ? >>> ????????????????Objects.hashCode(field.get(val)) : >>> System.identityHashCode(field.get(val)); >>> ????????????// Using the generic JDK hash for all types >>> ????????????hc = (31 * hc) + fieldHashCode; >>> ????????} >>> ????????return hc; >>> ? Gil. >>>> On Apr 10, 2018, at 7:49 AM, David Simms >>> > wrote: >>>> >>>> >>>> After prototyping "hashCode()" for value types, here's a few >>>> observations and thoughts... >>>> >>>> * "The general contract of hashCode" [1] is unchanged. >>>> * The default implementation, if no user implementation is provided, >>>> ??is assumed to be completely based upon the entire contents of the >>>> ??value (there's nothing else to go on). >>>> ????o The current "Object" implementation, both its generation and >>>> ??????object header hash caching are completely inappropriate for >>>> ??????value types. >>>> ????o The VM cannot pretend to know one field is more significant than >>>> ??????another. >>>> ????o Large values will benefit from user implementation to provide >>>> ??????efficiency. >>>> ????o Whilst the VM may provide a default implementation for safety, a >>>> ??????"javac" generated method would be optimal (can be optimized by >>>> ??????the JIT, includes inlining). >>>> * Values containing references whose contents are mutable pose a >>>> ??problem, their hash code is only as stable as the contents of the >>>> ??whole object graph. >>>> ????o Objects may suffer similar problems, difficult to say this is >>>> ??????any more important for values. Except to say values are supposed >>>> ??????to be "immutable" but references may break this quality, perhaps >>>> ??????"javac" could warn when value fields are mutable objects (not >>>> ??????always possible, e.g. field reference to an interface). >>>> >>>> I assume a the default implementation should look something like >>>> this (only with concrete fields, not reflection): >>>> >>>> ????????int hc = 0; >>>> ????????for (Field field : val.getClass().getDeclaredFields()) { >>>> ????????????if (Modifier.isStatic(field.getModifiers())) continue; >>>> >>>> ????????????// Using the generic JDK hash for all types >>>> ????????????hc = (31 * hc) + Objects.hashCode(field.get(val)); >>>> ????????} >>>> ????????return hc; >>>> >>>> This algorithm assumes the VM implements calls to reference field's >>>> hashCode(), and encodes primitives the same as their boxed JDK >>>> counter-parts (e.g. "Long.hashCode(long l)" does not generically >>>> hash two int size chunks, rather it xors hi and lo, Boolean is >>>> another interesting example 1231 || 1237). Unclear if this is >>>> actually important...however, this example: >>>> >>>> ????final __ByValue class MyInt implements Comparable { >>>> ????????final int value; >>>> ????????//.... >>>> ????} >>>> >>>> The user is free to explicitly delegate to "Integer.hashCode(int >>>> val)", but is it just more natural that the default works this way ? >>>> Alternative VM implementations might hash over value data payload >>>> including field padding. With h/w support (suitable checksum >>>> instruction) there might be some performance gain for large values, >>>> but then if you introduce object references, said h/w support would >>>> get broken. Said implementation would be dependent on field layout, >>>> and not give the same result on different platforms. Whilst the >>>> Javadoc states hashing "need not remain consistent from one >>>> execution of an application to another execution of the same >>>> application." [1], I'm wondering how many folks rely on consistent >>>> hashing, more than nobody I would fear. Lastly hashing large amounts >>>> of data per value seems an unlikely general use-case. >>>> >>>> >>>> Cheers >>>> /David Simms >>>> >>>> [1] >>>> https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() >>>> From daniel.smith at oracle.com Wed Apr 11 16:40:25 2018 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 11 Apr 2018 10:40:25 -0600 Subject: Value type hash code In-Reply-To: References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> Message-ID: <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> > On Apr 11, 2018, at 9:42 AM, Brian Goetz wrote: > > One of the operations we can name is ==. I think the substitution check is the most reasonable interpretation of ==, but I don't really see how we can avoid recurring on .equals() for the equals() implementation. Otherwise, this will violate basic user expectations, such as: > > value record StringBox(String s); > > I think values would be near-useless under such an interpretation of equals(). This is a reasonable language design, but I don't think the JVM should hard-wire that behavior. The compiler can generate the equals/hashCode methods it wants, and my thinking is that when the compiler fails to do so, the JVM's default (that is, the behavior of Object.equals and Object.hashCode if not overridden) should be conservative. ?Dan From forax at univ-mlv.fr Wed Apr 11 18:27:22 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 11 Apr 2018 20:27:22 +0200 (CEST) Subject: Value type hash code In-Reply-To: References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> Message-ID: <519529674.1581428.1523471242032.JavaMail.zimbra@u-pem.fr> Hi Brian, in the l-world, you can have a reference or a value type in 'a' local, so acmp is defined as an identity check (if there is a value type on the left or on the right operand the result is false) not a substitution check. R?mi ----- Mail original ----- > De: "Brian Goetz" > ?: "daniel smith" , "David Simms" > Cc: "valhalla-dev" > Envoy?: Mercredi 11 Avril 2018 17:42:37 > Objet: Re: Value type hash code > One of the operations we can name is ==.? I think the substitution check > is the most reasonable interpretation of ==, but I don't really see how > we can avoid recurring on .equals() for the equals() implementation. > Otherwise, this will violate basic user expectations, such as: > > ??? value record StringBox(String s); > > I think values would be near-useless under such an interpretation of > equals(). > > On 4/11/2018 10:13 AM, Dan Smith wrote: >>> On Apr 10, 2018, at 8:49 AM, David Simms wrote: >>> >>> * Values containing references whose contents are mutable pose a >>> problem, their hash code is only as stable as the contents of the >>> whole object graph. >> There's some flexibility in how we name operations, but let's observe that there >> are two pairs of operations to consider: >> >> substitutable/substitutableHash: recur on value fields, use acmp on reference >> fields >> deepEquals/deepHash: recur on value fields, use 'equals' on reference fields >> >> I think my expectation has been that substitutable/substitutableHash would be >> the default behavior of equals/hashCode, with the capability for users to >> override this if they're confident it's safe. (And with the ability to fall >> back to the default behavior with System.identityHashCode or something >> similar.) >> > > ?Dan From forax at univ-mlv.fr Wed Apr 11 18:32:29 2018 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 11 Apr 2018 20:32:29 +0200 (CEST) Subject: Value type hash code In-Reply-To: <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> Message-ID: <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "daniel smith" > ?: "Brian Goetz" > Cc: "valhalla-dev" > Envoy?: Mercredi 11 Avril 2018 18:40:25 > Objet: Re: Value type hash code >> On Apr 11, 2018, at 9:42 AM, Brian Goetz wrote: >> >> One of the operations we can name is ==. I think the substitution check is the >> most reasonable interpretation of ==, but I don't really see how we can avoid >> recurring on .equals() for the equals() implementation. Otherwise, this will >> violate basic user expectations, such as: >> >> value record StringBox(String s); >> >> I think values would be near-useless under such an interpretation of equals(). > > This is a reasonable language design, but I don't think the JVM should hard-wire > that behavior. The compiler can generate the equals/hashCode methods it wants, > and my thinking is that when the compiler fails to do so, the JVM's default > (that is, the behavior of Object.equals and Object.hashCode if not overridden) > should be conservative. I think we can go a step further and do not provide any defaults. The default implementation of equals and hashCode in java/lang/Object make only sense for reference, for value types, it depends on the value type, i.e, it's far easier for the compiler to provide an equals/hashCode than for the VM, hence my proposition that the VM should not provide any default and let the compiler of the different languages decide what defaults are. > > ?Dan R?mi From daniel.smith at oracle.com Wed Apr 11 18:41:06 2018 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 11 Apr 2018 12:41:06 -0600 Subject: Value type hash code In-Reply-To: <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> Message-ID: <1B556C11-F63F-4418-A8DF-2172CD59E065@oracle.com> > On Apr 11, 2018, at 12:32 PM, Remi Forax wrote: > >> This is a reasonable language design, but I don't think the JVM should hard-wire >> that behavior. The compiler can generate the equals/hashCode methods it wants, >> and my thinking is that when the compiler fails to do so, the JVM's default >> (that is, the behavior of Object.equals and Object.hashCode if not overridden) >> should be conservative. > > I think we can go a step further and do not provide any defaults. > > The default implementation of equals and hashCode in java/lang/Object make only sense for reference, > for value types, it depends on the value type, i.e, it's far easier for the compiler to provide an equals/hashCode than for the VM, > hence my proposition that the VM should not provide any default and let the compiler of the different languages decide what defaults are. It must do *something*, but throwing an exception (with 'equals' either throwing or returning 'false') is a viable 3rd alternative. From stuart.marks at oracle.com Wed Apr 11 18:42:53 2018 From: stuart.marks at oracle.com (Stuart Marks) Date: Wed, 11 Apr 2018 11:42:53 -0700 Subject: Value type hash code In-Reply-To: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: <263e6021-9f98-6867-faa8-3026f28a1518@oracle.com> Interesting stuff. Several observations: * Clearly there ought to be a default implementation. One question I have is whether the default implementation ought to be *specified*. If it's not specified -- really, it's specified only to conform to the general contract, but the details aren't specified -- then we'll have more freedom to change it in the future. Indeed, it'd be nice if it changed from time to time, or even frequently; it would help avoid code making inadvertent dependencies on the hash values. * I think a primary use case for value types will be as HashMap keys. If so, I don't see any reasonable alternative than to delegate to the hashCode() of ordinary objects referenced from a value type, even if they're mutable. Lists of any implementation are defined to be equal and to have the same hashcode if their elements are equal. Two value types containing distinct List instances, containing equal elements should be equal and have equal hash codes. Yes, this implies that a value type's hashCode() and equals() can change if it contains a reference to a mutable object. Sure, someone (javac?) can try to warn about this, but then we get into the business of tagging some objects as immutable. I'm not sure I want to go there. To a certain extent, people are used to this; they use mutable objects as HashMap keys all the time. They just "know" that they mustn't mutate the object while it's in use. Occasionally, though, somebody will pop up in a huff complaining that HashMap is broken, and it's because they mutated a key... and then they'll complain that this isn't properly documented. Overall though, I don't think this is a serious problem. * I'm sort-of ok with arrays using identity hash code, since that's what you get when you call hashCode() on them. The user can override this by calling Arrays.hashCode() or deepHashCode() if desired. But I can't help but think this is perpetuating a mistake.... * I'm wondering if it makes sense to mix the field types into the hashCode, at least for primitives. The hashcodes for the integral primitives are all equal to the value, for small values. That is, the hashes of (byte)123, (short)123, (char)123, 123, and 123L are all 123. That bugs me. I'm not sure how much practical impact it would have, though. * Somebody (maybe me) should do some research into better hash algorithms. The base-31 polynomial was probably quite reasonable 20 years ago, but better things might have been discovered since then. Intuitively, I'd say that the starting value should be something other than zero, preferably a large prime number. Since the hash code of 0 is 0, and the hash code of "" is 0, it's quite likely for a value containing zeros and empty strings to be zero! (Unless we mix in the field types, as above.) s'marks On 4/10/18 7:49 AM, David Simms wrote: > > After prototyping "hashCode()" for value types, here's a few observations and > thoughts... > > ?* "The general contract of hashCode" [1] is unchanged. > ?* The default implementation, if no user implementation is provided, > ?? is assumed to be completely based upon the entire contents of the > ?? value (there's nothing else to go on). > ???? o The current "Object" implementation, both its generation and > ?????? object header hash caching are completely inappropriate for > ?????? value types. > ???? o The VM cannot pretend to know one field is more significant than > ?????? another. > ???? o Large values will benefit from user implementation to provide > ?????? efficiency. > ???? o Whilst the VM may provide a default implementation for safety, a > ?????? "javac" generated method would be optimal (can be optimized by > ?????? the JIT, includes inlining). > ?* Values containing references whose contents are mutable pose a > ?? problem, their hash code is only as stable as the contents of the > ?? whole object graph. > ???? o Objects may suffer similar problems, difficult to say this is > ?????? any more important for values. Except to say values are supposed > ?????? to be "immutable" but references may break this quality, perhaps > ?????? "javac" could warn when value fields are mutable objects (not > ?????? always possible, e.g. field reference to an interface). > > I assume a the default implementation should look something like this (only with > concrete fields, not reflection): > > ??????? int hc = 0; > ??????? for (Field field : val.getClass().getDeclaredFields()) { > ??????????? if (Modifier.isStatic(field.getModifiers())) continue; > > ??????????? // Using the generic JDK hash for all types > ??????????? hc = (31 * hc) + Objects.hashCode(field.get(val)); > ??????? } > ??????? return hc; > > This algorithm assumes the VM implements calls to reference field's hashCode(), > and encodes primitives the same as their boxed JDK counter-parts (e.g. > "Long.hashCode(long l)" does not generically hash two int size chunks, rather it > xors hi and lo, Boolean is another interesting example 1231 || 1237). Unclear if > this is actually important...however, this example: > > ??? final __ByValue class MyInt implements Comparable { > ??? ??? final int value; > ??? ??? //.... > ??? } > > The user is free to explicitly delegate to "Integer.hashCode(int val)", but is > it just more natural that the default works this way ? Alternative VM > implementations might hash over value data payload including field padding. With > h/w support (suitable checksum instruction) there might be some performance gain > for large values, but then if you introduce object references, said h/w support > would get broken. Said implementation would be dependent on field layout, and > not give the same result on different platforms. Whilst the Javadoc states > hashing "need not remain consistent from one execution of an application to > another execution of the same application." [1], I'm wondering how many folks > rely on consistent hashing, more than nobody I would fear. Lastly hashing large > amounts of data per value seems an unlikely general use-case. > > > Cheers > /David Simms > > [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() > > From john.r.rose at oracle.com Wed Apr 11 20:27:42 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 13:27:42 -0700 Subject: Value type hash code In-Reply-To: <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> Message-ID: <1A240EB3-F71A-48FF-9D3D-81F5F60D2676@oracle.com> On Apr 11, 2018, at 11:32 AM, Remi Forax wrote: > > The default implementation of equals and hashCode in java/lang/Object make only sense for reference, That's because currently Object is the supertype of references only. When Object becomes the supertype of values also, it's portfolio increases. This is a common logical error: Because X did Y historically, X must also do only Y in the future. We could make this our story for X=Object, Y=identityHashCode by fiat, but we are not forced to. In fact, since Object is the super of value types (by another fiat; yes, I know it doesn't fit perfectly), it it totally reasonable to enhance the Object.hashCode method to some logic like this: hashCode() { if (this.getClass is reference type) return System.identityHashCode(this) else return System.valueHashCode(this) } And in fact I'm convinced that is what we should do. That leads to the question, "what is the definition of System.valueHashCode" (name is unimportant)? > for value types, it depends on the value type, i.e, it's far easier for the compiler to provide an equals/hashCode than for the VM, There is a third and much better answer, which I'm surprised you don't mention; it is using a BSM. In other words, we are not stuck with the following unpleasant choice: - Put lots of complicated intrinsic behavior into the JVM proper. - Put lots of complicated generated bytecode into the classfiles, which is there forever. The third choice is: - Let the Java runtime manage complicated intrinsic behaviors using BSMs. This third choice makes classfiles smaller (which is important!) and allows the JVM and JDK to jointly choose the most efficient code shapes to implement the documented behavior. This worked really, really well for lambdas. (Somebody might still be thinking that only generated bytecodes in classfiles will get full performance. Actually, generated bytecodes in classfiles are the worst-performing option. BSMs can generate efficient code with "cheats" like Unsafe which bytecodes are forbidden to use. Even a non-BSM solution like System.valueHashCode can be faster than raw bytecodes, if the magic method is treated as an intrinsic by the JIT. The problem with raw bytecodes is that the JIT cannot trust them to correspond to an optimizable pattern; it must implement every corner of them and may not replace them with more efficient code, because they might have been written by the user. Also, loads of bytecodes in classfiles are slow to load and hard to verify and analyze. The anti-pattern to avoid is a one-line Java class compiling to kilobytes of classfile, and we can do this with BSMs.) The most I'd like to see in value type classfiles is a one line hashCode (and equals, toString): hashCode() { return indy[Bootstraps::valueHashCode](this) } And in fact, I would prefer to have this stereotyped code be inherited (by a new VM feature "mindy" = method instance dynamic.) ?That's me wanting to sand down all the corners. > hence my proposition that the VM should not provide any default and let the compiler of the different languages decide what defaults are. That's fine to let the compiler decide but putting lots of boilerplate bytecodes into classfiles is an anti-pattern; see above. Let the compiler choose a BSM and (maybe) a supertype to inherit mindy methods from. Now, back to the details of hashCode: At points like this we can go back and try to fix historical defects in hashCode. Fix more defects and get more expense and delay, or fix fewer and get the feature sooner. Someone noticed that there is a theoretical possibility of stack overflow in some cases. The most important fact to note here is working precedents for handling this issue, which work today. The most relevant working precedent is collection types, whose documented semantics support value-based types, a close cousing to value types. (The product of List.of is approximately value-based.) The code for AbstractList gives us the best precedent to work with, and it does not check for self-cycles. I don't think value types have any greater chance than lists of self-cycles; in fact they probably have less, since they will often be logical leaves in data structure. So it would be reasonable to adapt the standard definitions from AbstractList for the value types. To me that is the best first cut. (The self-check in toString, which is in AbstractCollection, short-circuits away in the case of value types.) Details of this first cut: Make a List (using List.of) of the fields in order of the value instance. Use source order of fields. Omit statics of course. For good measure fold in the type, say, inserting this.getClass() into the field list as a leading element. Defer equals/hashCode/toString to the List derived as specified. Certainly tweak the toString output so it doesn't look exactly like a List.toString output. hashCode() { // library optimizes this behavior via BSM: return List.of(this.getClass(), this.field1, this.field2, ?).hashCode(); } To be quite clear: Yes, if the value type has a reference field, that sub-object's hashCode method gets called, and that could do something crazy. If that's an issue, the author of the value type should specify more expensive and careful methods. Preferably using a different BSM, of course. (Alternative compliant behaviors would be to throw an exception or to skip the reference field, for hashCode. Using identityHashCode is also an option but only if the corresponding equals method uses acmp/op== not an equals call. But in that case having values use an identity-sensitive comparison for their sub-components seems even more surprising than throwing an exception. Of all the choices, following the precedent of List seems to me least surprising and most useful.) ? John P.S. Now to make it more complicated: My favorite grudge against hashCode is not that it is potentially self-recursive. My grudge is that hashCode produces at most 32 bits or in the case of identityHashCode only about 20 bits, and the standard mixing functions (xor, *31+) are known to be poor, in terms of creating funnels that confuse pairs of values, and failing to spread input bits to output bits. Should we consider making a longHashCode method for various types, including value types, and have it produce a full 64 bits of output, mixed in a more modern way? According to my experiments, two rounds of AES-step is better than any standard arithmetic operation of similar cycle-count on modern hardware, and light-years better (though another cycle or two) than h*31+x. This algorithm would be much better than the legacy h*31+x: uint128_t h = (SALT); for (uint64_t x1, x2 in pairs of inputs) { uint128_t x12 = x1; x12 <<= 64; x12 |= x2; h = aes_step(h ^ x2); // optional: h = aes_step(h ^ SALT2); } The second iteration of aes (a single AES encode or decode step, not a full block of 10 of them) seems to meet or beat anything else doable in the same number of cycles, since full-word multiplies are today about as expensive as AES steps, and AES steps handle two words at a time, while two rounds of AES is at least as good at mixing as full-word multiples. AES or not, the relevant methods, for value types, could use longHashCode as the defining block: hashCode() { // library optimizes this behavior via BSM: return (int)this.longHashCode(); } longHashCode() { // library optimizes this behavior via BSM: return List.of(this.getClass(), this.field1, this.field2, ?).longHashCode(); } Anyway, this elephant has many corners, and various of us are inspecting distinct corners. But poor hashing is the particular toenail I would like to trim. Of course it's elephants all the way down: Replacing h*31+x is, all by itself, its own multi-faceted conversation; I think I've got this one by the trunk but maybe there's something on a leg or tail that needs pointing out, such as the fact that AES isn't available on many 32-bit chips. One final point: We don't need to be stuck with 32-bit hashCode forever. Our eventual solution to reified generics, whatever it is, seems likely to allow the size of the hashCode to be a generic parameter. So it is reasonable to hope that many of our hashing data structures could be generified over the quality of the hash function. From john.r.rose at oracle.com Wed Apr 11 20:39:43 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 13:39:43 -0700 Subject: Value type hash code In-Reply-To: <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> Message-ID: <89A0305F-131E-46D2-B717-BB0DA963BE03@oracle.com> On Apr 11, 2018, at 7:13 AM, Dan Smith wrote: > >> On Apr 10, 2018, at 8:49 AM, David Simms wrote: >> >> * Values containing references whose contents are mutable pose a >> problem, their hash code is only as stable as the contents of the >> whole object graph. > > There's some flexibility in how we name operations, but let's observe that there are two pairs of operations to consider: > > substitutable/substitutableHash: recur on value fields, use acmp on reference fields Yes. (And that's a reasonable default.) > deepEquals/deepHash: recur on value fields, use 'equals' on reference fields Yes, that's the same as "as if by List.of" I mentioned. > I think my expectation has been that substitutable/substitutableHash would be the default behavior of equals/hashCode, with the capability for users to override this if they're confident it's safe. (And with the ability to fall back to the default behavior with System.identityHashCode or something similar.) One can be the default; both should be available as explicit opt-ins (via BSM). Despite what I said in my previous message, the substitutable one would be a more conservative choice of default; it corresponds closely to the define behavior for references. Reason: acmp/op== is the substitutability test for (possibly stateful) objects, and that (not deepEquals) is the default for references. Still, the deepEquals one is probably more useful, for both references and values, so IMO it should be easy to opt into it. Note the frequency, for reference classes, of people having to override Object.equals/hashCode, so their objects will play well with collection types. This suggests to me that setting the default to deepEquals (not substitutable) is a reasonable move to consider. In the case of "boilerplate friendly" classes like records, deepEquals should be the default, with an option to revert to the stricter substitutability test by some other means. And of course there's a range of possibilities: If a class has has two fields, perhaps one should be compared for substitutability and one for deep equality. Note that I didn't say whether the class or the fields were references or values: The same concerns apply to both. ? John From john.r.rose at oracle.com Wed Apr 11 20:59:00 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 13:59:00 -0700 Subject: Value type hash code In-Reply-To: <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> Message-ID: On Apr 11, 2018, at 9:40 AM, Dan Smith wrote: > > This is a reasonable language design, but I don't think the JVM should hard-wire that behavior. The compiler can generate the equals/hashCode methods it wants, and my thinking is that when the compiler fails to do so, the JVM's default (that is, the behavior of Object.equals and Object.hashCode if not overridden) should be conservative. (As usual we are confusing ourselves by having simultaneous but distinct discussions about what the JVM should do and what the language should do.) What Dan is saying here is what the JVM should do if presented with a naked value class, with no contents beyond what the verifier requires. Not even Java 1.0 had completely naked classes, since javac would often spin up synthetic methods like and . What others are saying is that the language should make the default be something such as deepEquals or maybe substitutable or even "user responsibility" (a la abstract inherited methods). And I'm also saying that BSMs allow the relevant choices to be flipped easily and declaratively, unlike in early versions of Java, which required javac to weave fancy (and opaque) bytecodes for fancy stuff like string append, class literals, or inner classes. But, to turn back to the JVM responsibility: It seems like the most conservative thing to do would implementing a value-oriented substitutability test, which appropriately mirrors (for values) the substitutability test of references, which is acmp/op==. Then, for better or worse, the contract of Object.equals (and thus Object.hashCode) would be always a substitutability check. Mostly worse, since we are more comfortable these days requiring well-dressed classes to have suitable equals/hashCode methods. Or we could choose to break symmetry between references and values in the case of Object.equals, at the JVM level. I think the cost of this would be low, though the esthetics would be very poor. Third option: Keep symmetry on Object.equals, and define a new supertype interface Equable (or some such) whose semantics would override the substitutability check of Object.equals, replacing them with deepEquals. Then declare that standard value types implement Equable as well as Object (but allow the JVM to accept naked value types without Equable). Extend the benefits of Equable to reference types also, of course. This third option would seem to require the ability for default methods in Equable to override Object methods, which would be a difficult new thing. IMO it would be a not-unreasonable cost to pay, to avoid having to hard-wire either kind of equality (substitutability or deep equality) into the JVM or require boilerplate everywhere the hard-wired option was wrong. But, probably, default methods aren't the right way to think about this. Which brings us back to the "mindy" idea: The things implemented by Equable (in the above scenario) wouldn't be today's default methods, but rather some sort of inheritable BSM declaration, which would be expanded separately in each concrete class that implements the interface. I know how this would work in the JVM but I have not the faintest idea what it would look like at the language level; maybe at first it would be a hardwired Magick in that particular type, Equable. Eventually along with template classes we might have template methods, and then the language-level design would become clearer. ? John From john.r.rose at oracle.com Wed Apr 11 21:01:18 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 14:01:18 -0700 Subject: Value type hash code In-Reply-To: <519529674.1581428.1523471242032.JavaMail.zimbra@u-pem.fr> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <519529674.1581428.1523471242032.JavaMail.zimbra@u-pem.fr> Message-ID: On Apr 11, 2018, at 11:27 AM, Remi Forax wrote: > > in the l-world, you can have a reference or a value type in 'a' local, > so acmp is defined as an identity check (if there is a value type on the left or on the right operand the result is false) not a substitution check. Not quite true: We are currently defining literal acmp on a value to return false always. That's to avoid having to buy the whole contract of detecting substitutability. The performance model requires a new user-visible operator to test for the "thicker" concept of value substitutability. Meanwhile, reference substitutability has always been just a "thin" pointer compare. From john.r.rose at oracle.com Wed Apr 11 21:10:21 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 14:10:21 -0700 Subject: Value type hash code In-Reply-To: <263e6021-9f98-6867-faa8-3026f28a1518@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <263e6021-9f98-6867-faa8-3026f28a1518@oracle.com> Message-ID: <0629D39E-8AC1-49C4-A03E-23EBB5738114@oracle.com> On Apr 11, 2018, at 11:42 AM, Stuart Marks wrote: > > Interesting stuff. Several observations: > > * Clearly there ought to be a default implementation. One question I have is whether the default implementation ought to be *specified*. If it's not specified -- really, it's specified only to conform to the general contract, but the details aren't specified -- then we'll have more freedom to change it in the future. Indeed, it'd be nice if it changed from time to time, or even frequently; it would help avoid code making inadvertent dependencies on the hash values. Maybe (but probably not) that's tenable at the language level. We JVM folks need certainty too, for naked classes as well as fully clothed ones. (We could have the JVM outlaw certain ill-clothed ones, of course, but that move doesn't seem to buy increased clarity at a the JVM level. The JVM still needs to define at least an analog of Object.equals for values, I suspect.) > * I think a primary use case for value types will be as HashMap keys. If so, I don't see any reasonable alternative than to delegate to the hashCode() of ordinary objects referenced from a value type, even if they're mutable. Lists of any implementation are defined to be equal and to have the same hashcode if their elements are equal. Two value types containing distinct List instances, containing equal elements should be equal and have equal hash codes. Yep. Which is why we are wondering whether to break symmetry on today's Object.equals and give it a more useful meaning for values even though it is pretty useless for today's references. > Yes, this implies that a value type's hashCode() and equals() can change if it contains a reference to a mutable object. Sure, someone (javac?) can try to warn about this, but then we get into the business of tagging some objects as immutable. I'm not sure I want to go there. > > To a certain extent, people are used to this; they use mutable objects as HashMap keys all the time. They just "know" that they mustn't mutate the object while it's in use. Occasionally, though, somebody will pop up in a huff complaining that HashMap is broken, and it's because they mutated a key... and then they'll complain that this isn't properly documented. Overall though, I don't think this is a serious problem. (To me that's like the self-loop/SOE problem: Very possible in theory, but our users somehow manage to avoid it.) > * I'm sort-of ok with arrays using identity hash code, since that's what you get when you call hashCode() on them. The user can override this by calling Arrays.hashCode() or deepHashCode() if desired. But I can't help but think this is perpetuating a mistake?. I agree strongly with this feeling, and would like to find a clever escape from the box we've put ourselves in. > * I'm wondering if it makes sense to mix the field types into the hashCode, at least for primitives. The hashcodes for the integral primitives are all equal to the value, for small values. That is, the hashes of (byte)123, (short)123, (char)123, 123, and 123L are all 123. That bugs me. I'm not sure how much practical impact it would have, though. I'd rather mix in the value class. That would handle all the field types in one fell swoop. > * Somebody (maybe me) should do some research into better hash algorithms. You too! You noticed that broken toenail! > The base-31 polynomial was probably quite reasonable 20 years ago, but better things might have been discovered since then. Intuitively, I'd say that the starting value should be something other than zero, preferably a large prime number. Since the hash code of 0 is 0, and the hash code of "" is 0, it's quite likely for a value containing zeros and empty strings to be zero! (Unless we mix in the field types, as above.) It was a New Jersey move even 20 years ago. IIRC we tested it on medium sized corpuses of URL strings and found it was "not too terrible". Now it's just plain terrible, given the available alternatives, and the continuing expansion of uses cases that Java serves. ? John From forax at univ-mlv.fr Wed Apr 11 21:35:27 2018 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Wed, 11 Apr 2018 23:35:27 +0200 (CEST) Subject: Value type hash code In-Reply-To: References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <519529674.1581428.1523471242032.JavaMail.zimbra@u-pem.fr> Message-ID: <2109246418.1607038.1523482527337.JavaMail.zimbra@u-pem.fr> > De: "John Rose" > ?: "Remi Forax" > Cc: "Brian Goetz" , "valhalla-dev" > > Envoy?: Mercredi 11 Avril 2018 23:01:18 > Objet: Re: Value type hash code > On Apr 11, 2018, at 11:27 AM, Remi Forax < [ mailto:forax at univ-mlv.fr | > forax at univ-mlv.fr ] > wrote: >> in the l-world, you can have a reference or a value type in 'a' local, >> so acmp is defined as an identity check (if there is a value type on the left or >> on the right operand the result is false) not a substitution check. > Not quite true: We are currently defining literal acmp on a value to return > false always. > That's to avoid having to buy the whole contract of detecting substitutability. so acmp != substitutability, no ? > The performance model requires a new user-visible operator to test for the > "thicker" concept of value substitutability. and value substitutability can not be used for implementing equals because equals takes an Object as parameter while the thicker value substitutability is only define for different values of the same value type. > Meanwhile, reference substitutability has always been just a "thin" pointer > compare. You can say we have generalized substitutability which return false for value type or is a pointer comparison when you have reference, or you can say, we have only identity check for reference, so it returns null for value. Apart the fact that the name is different, it's the same thing, and i prefer identity check because it avoid to use the term of "thicker" value substitutability. R?mi From john.r.rose at oracle.com Wed Apr 11 21:54:47 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 14:54:47 -0700 Subject: Value type hash code In-Reply-To: <2109246418.1607038.1523482527337.JavaMail.zimbra@u-pem.fr> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <519529674.1581428.1523471242032.JavaMail.zimbra@u-pem.fr> <2109246418.1607038.1523482527337.JavaMail.zimbra@u-pem.fr> Message-ID: <66C2603B-8056-4EC9-944B-0D104A23968C@oracle.com> On Apr 11, 2018, at 2:35 PM, forax at univ-mlv.fr wrote: > > > > De: "John Rose" > ?: "Remi Forax" > Cc: "Brian Goetz" , "valhalla-dev" > Envoy?: Mercredi 11 Avril 2018 23:01:18 > Objet: Re: Value type hash code > On Apr 11, 2018, at 11:27 AM, Remi Forax > wrote: > > in the l-world, you can have a reference or a value type in 'a' local, > so acmp is defined as an identity check (if there is a value type on the left or on the right operand the result is false) not a substitution check. > > Not quite true: We are currently defining literal acmp on a value to return false always. > That's to avoid having to buy the whole contract of detecting substitutability. > > so acmp != substitutability, no ? Correct. I'd rather keep the symmetry at that point between references and values, but It seems to a forced move because value substitutability check is not O(1). > > The performance model requires a new user-visible operator to test for the > "thicker" concept of value substitutability. > and value substitutability can not be used for implementing equals because equals takes an Object as parameter while the thicker value substitutability is only define for different values of the same value type. If I understand your point, I already covered it by pointing out that the contract of (invokespecial) Object.equals does not need to be identical with the contract of acmp/op==, because Object.equals can be defined by fiat to include a special path for values, to use something other than acmp/op==. Should it have this extra path? Probably. But you could imagine Object.equals returning false always for value types, just like acmp/op==. What it comes down to is we have at least three concepts to distribute among the legacy operations, whatever their names may be: - object identity check (O(1), legacy acmp/op==) - substitutability (same as identity check *but only for object references*) - deep equality (including ad hoc definitions specific to classes) Which bucket should (invokespecial) Object.equals go in, for values? I think the second, not the first, better matches up with the intended uses of Object.equals, even though it doesn't match with the *current implementation* of Object.equals which is acmp/op==. > Meanwhile, reference substitutability has always been just a "thin" pointer compare. > You can say we have generalized substitutability which return false for value type or is a pointer comparison when you have reference, Not so much generalized, as (say) "object substitutability", which returns false, etc. > or you can say, we have only identity check for reference, so it returns null for value. Yes. > Apart the fact that the name is different, it's the same thing, and i prefer identity check because it avoid to use the term of "thicker" value substitutability. Good, I adopted that term in my three-way list above. Do you still think Object.equals must do object identity checks, or can it do substitutability for values? Which aspect of the legacy pointer compare is more important, for Object.equals: The fact that it is O(1) or the fact that it detects substitutability? ? John From john.r.rose at oracle.com Wed Apr 11 21:57:13 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 14:57:13 -0700 Subject: Value type hash code In-Reply-To: <66C2603B-8056-4EC9-944B-0D104A23968C@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <519529674.1581428.1523471242032.JavaMail.zimbra@u-pem.fr> <2109246418.1607038.1523482527337.JavaMail.zimbra@u-pem.fr> <66C2603B-8056-4EC9-944B-0D104A23968C@oracle.com> Message-ID: On Apr 11, 2018, at 2:54 PM, John Rose wrote: > > value substitutability check is not O(1). P.S. It is O(N) where N is the size of the value. Yes, N is very small, almost 1, but it is still thought to be large compared to the very small cost of a pointer compare on today's machines. If we had one-cycle cache line compares maybe the trade-off would go elsewhere. From daniel.smith at oracle.com Wed Apr 11 22:21:51 2018 From: daniel.smith at oracle.com (Dan Smith) Date: Wed, 11 Apr 2018 16:21:51 -0600 Subject: Value type hash code In-Reply-To: References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> Message-ID: <6C2909B3-B2D0-49F0-BACA-19A27267C9E9@oracle.com> > On Apr 11, 2018, at 2:59 PM, John Rose wrote: > > On Apr 11, 2018, at 9:40 AM, Dan Smith wrote: >> >> This is a reasonable language design, but I don't think the JVM should hard-wire that behavior. The compiler can generate the equals/hashCode methods it wants, and my thinking is that when the compiler fails to do so, the JVM's default (that is, the behavior of Object.equals and Object.hashCode if not overridden) should be conservative. > > (As usual we are confusing ourselves by having simultaneous but distinct > discussions about what the JVM should do and what the language should do.) > > What Dan is saying here is what the JVM should do if presented with a naked > value class, with no contents beyond what the verifier requires. Not even Java > 1.0 had completely naked classes, since javac would often spin up synthetic > methods like and . > > What others are saying is that the language should make the default be > something such as deepEquals or maybe substitutable or even "user > responsibility" (a la abstract inherited methods). Yes, this is right. And to clarify my motivation: Object.equals/hashCode have some really nice properties that apply to all non-overriding objects (both class instances and arrays), including consistency over time, guaranteed successful completion, and guaranteed substitutability. These methods do this by being extremely conservative. (I think a lot of people would say these properties are not very important, but I think they would be missed if Java had gone a different way and given every object a deep equals by default.) Often, end users find this conservative behavior inconvenient, and would like to consider a wider range of instances equivalent. They are free to write some code that will have that effect, or use libraries that have written such code, and in so doing opt in to various risks if they're not careful about how they use their instances. I think it would be a mistake for the JVM to force these risks on all users. The JVM has no domain knowledge, no way to determine whether a value is intended to be a hash key, store a cyclical object graph, etc. It may make sense for the language to introduce these risks through certain implicit declarations, although I think we should think carefully about them. End users should understand the risks of using the implicit-generating constructs and have reasonable alternatives/opt-outs. It's even more permissible for libraries to introduce these risks, although again it should be done carefully, taking into account what the library knows about its clients, and clearly advertising the risks. (If I were designing a general-purpose mutable collection API, for example, I would not have followed the Collections path of defining an unstable equals/hashCode method. Maybe I'd prefer to introduce a "currently equal" operation under a different name.) And of course it's fine to allow end users to accept the risks explicitly in their own classes. From john.r.rose at oracle.com Wed Apr 11 22:23:59 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 15:23:59 -0700 Subject: Value type hash code In-Reply-To: <6C2909B3-B2D0-49F0-BACA-19A27267C9E9@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> <6C2909B3-B2D0-49F0-BACA-19A27267C9E9@oracle.com> Message-ID: Well said; thank you. > On Apr 11, 2018, at 3:21 PM, Dan Smith wrote: > >> On Apr 11, 2018, at 2:59 PM, John Rose wrote: >> >> On Apr 11, 2018, at 9:40 AM, Dan Smith wrote: >>> >>> This is a reasonable language design, but I don't think the JVM should hard-wire that behavior. The compiler can generate the equals/hashCode methods it wants, and my thinking is that when the compiler fails to do so, the JVM's default (that is, the behavior of Object.equals and Object.hashCode if not overridden) should be conservative. >> >> (As usual we are confusing ourselves by having simultaneous but distinct >> discussions about what the JVM should do and what the language should do.) >> >> What Dan is saying here is what the JVM should do if presented with a naked >> value class, with no contents beyond what the verifier requires. Not even Java >> 1.0 had completely naked classes, since javac would often spin up synthetic >> methods like and . >> >> What others are saying is that the language should make the default be >> something such as deepEquals or maybe substitutable or even "user >> responsibility" (a la abstract inherited methods). > > Yes, this is right. And to clarify my motivation: > > Object.equals/hashCode have some really nice properties that apply to all non-overriding objects (both class instances and arrays), including consistency over time, guaranteed successful completion, and guaranteed substitutability. These methods do this by being extremely conservative. > > (I think a lot of people would say these properties are not very important, but I think they would be missed if Java had gone a different way and given every object a deep equals by default.) > > Often, end users find this conservative behavior inconvenient, and would like to consider a wider range of instances equivalent. They are free to write some code that will have that effect, or use libraries that have written such code, and in so doing opt in to various risks if they're not careful about how they use their instances. > > I think it would be a mistake for the JVM to force these risks on all users. The JVM has no domain knowledge, no way to determine whether a value is intended to be a hash key, store a cyclical object graph, etc. > > It may make sense for the language to introduce these risks through certain implicit declarations, although I think we should think carefully about them. End users should understand the risks of using the implicit-generating constructs and have reasonable alternatives/opt-outs. > > It's even more permissible for libraries to introduce these risks, although again it should be done carefully, taking into account what the library knows about its clients, and clearly advertising the risks. (If I were designing a general-purpose mutable collection API, for example, I would not have followed the Collections path of defining an unstable equals/hashCode method. Maybe I'd prefer to introduce a "currently equal" operation under a different name.) > > And of course it's fine to allow end users to accept the risks explicitly in their own classes. > From paul.sandoz at oracle.com Thu Apr 12 01:02:55 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 11 Apr 2018 18:02:55 -0700 Subject: Value type hash code In-Reply-To: <1A240EB3-F71A-48FF-9D3D-81F5F60D2676@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> <1A240EB3-F71A-48FF-9D3D-81F5F60D2676@oracle.com> Message-ID: <6E0CF6E5-FF6C-40A1-A349-52E760B27A95@oracle.com> > On Apr 11, 2018, at 1:27 PM, John Rose wrote: > The most I'd like to see in value type classfiles is a one line hashCode (and equals, toString): > > hashCode() { > return indy[Bootstraps::valueHashCode](this) > } > > And in fact, I would prefer to have this stereotyped code be inherited (by a new VM feature > "mindy" = method instance dynamic.) ?That's me wanting to sand down all the corners. > I cannot resist? if all fields are are constant then cindy, mindy?s constant companion :-) Paul. From john.r.rose at oracle.com Thu Apr 12 01:25:40 2018 From: john.r.rose at oracle.com (John Rose) Date: Wed, 11 Apr 2018 18:25:40 -0700 Subject: Value type hash code In-Reply-To: <0629D39E-8AC1-49C4-A03E-23EBB5738114@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <263e6021-9f98-6867-faa8-3026f28a1518@oracle.com> <0629D39E-8AC1-49C4-A03E-23EBB5738114@oracle.com> Message-ID: On Apr 11, 2018, at 2:10 PM, John Rose wrote: > >> >> * Somebody (maybe me) should do some research into better hash algorithms. > > You too! You noticed that broken toenail! I put a brain dump here: https://bugs.openjdk.java.net/browse/JDK-8201462 Caveat: It's not serious yet, just a brain dump. From forax at univ-mlv.fr Thu Apr 12 07:41:32 2018 From: forax at univ-mlv.fr (forax at univ-mlv.fr) Date: Thu, 12 Apr 2018 09:41:32 +0200 (CEST) Subject: Value type hash code In-Reply-To: <6E0CF6E5-FF6C-40A1-A349-52E760B27A95@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <339F1539-CC32-4DD2-A352-213CBB5018C7@oracle.com> <7CD43EF9-D8BE-4CDA-98FB-87A6D8395821@oracle.com> <530626714.1582191.1523471549797.JavaMail.zimbra@u-pem.fr> <1A240EB3-F71A-48FF-9D3D-81F5F60D2676@oracle.com> <6E0CF6E5-FF6C-40A1-A349-52E760B27A95@oracle.com> Message-ID: <1696739584.1699868.1523518892932.JavaMail.zimbra@u-pem.fr> ----- Mail original ----- > De: "Paul Sandoz" > ?: "John Rose" > Cc: "Remi Forax" , "valhalla-dev" > Envoy?: Jeudi 12 Avril 2018 03:02:55 > Objet: Re: Value type hash code >> On Apr 11, 2018, at 1:27 PM, John Rose wrote: >> The most I'd like to see in value type classfiles is a one line hashCode (and >> equals, toString): >> >> hashCode() { >> return indy[Bootstraps::valueHashCode](this) >> } >> >> And in fact, I would prefer to have this stereotyped code be inherited (by a new >> VM feature >> "mindy" = method instance dynamic.) ?That's me wanting to sand down all the >> corners. >> > > I cannot resist? if all fields are are constant then cindy, mindy?s constant > companion :-) > > Paul. instead of method instance dynamic, i prefer class dynamic, or classy. R?mi From frederic.parain at oracle.com Thu Apr 12 13:27:50 2018 From: frederic.parain at oracle.com (frederic.parain at oracle.com) Date: Thu, 12 Apr 2018 13:27:50 +0000 Subject: hg: valhalla/valhalla: Fix flag definition conflict Message-ID: <201804121327.w3CDRoYE003041@aojmv0008.oracle.com> Changeset: 4d1e8489a000 Author: fparain Date: 2018-04-12 09:26 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/4d1e8489a000 Fix flag definition conflict ! src/hotspot/share/utilities/accessFlags.hpp From frederic.parain at oracle.com Thu Apr 12 13:29:27 2018 From: frederic.parain at oracle.com (Frederic Parain) Date: Thu, 12 Apr 2018 09:29:27 -0400 Subject: hg: valhalla/valhalla: Fix flag definition conflict In-Reply-To: <201804121327.w3CDRoYE003041@aojmv0008.oracle.com> References: <201804121327.w3CDRoYE003041@aojmv0008.oracle.com> Message-ID: <9537529e-9520-8df8-5246-c407539db194@oracle.com> Minor fix to resolve a flag definition conflict causing a regression in a JCK test. Thanks to Harold for reporting the issue and for his help during the investigation. Fred On 04/12/2018 09:27 AM, frederic.parain at oracle.com wrote: > Changeset: 4d1e8489a000 > Author: fparain > Date: 2018-04-12 09:26 -0400 > URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/4d1e8489a000 > > Fix flag definition conflict > > ! src/hotspot/share/utilities/accessFlags.hpp > From rwestrel at redhat.com Thu Apr 12 14:37:51 2018 From: rwestrel at redhat.com (Roland Westrelin) Date: Thu, 12 Apr 2018 16:37:51 +0200 Subject: MethodHandleBuilder bug? Message-ID: I noticed that this: private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), "mergeNull", MethodType.methodType(void.class, TestLWorld.class, boolean.class), CODE -> { CODE. iload_1(). iconst_0(). ifcmp(TypeTag.I, CondKind.EQ, "null"). aload_0(). getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). goto_("continue"). label("null"). aconst_null(). label("continue"). aload_0(). swap(). putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). return_(); } ); works fine but if I swap the code in the if branches: private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), "mergeNull", MethodType.methodType(void.class, TestLWorld.class, boolean.class), CODE -> { CODE. iload_1(). iconst_0(). ifcmp(TypeTag.I, CondKind.EQ, "null"). aconst_null(). goto_("continue"). label("null"). aload_0(). getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). label("continue"). aload_0(). swap(). putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). return_(); } ); then I get: java.lang.ExceptionInInitializerError at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:564) at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115) at java.base/java.lang.Thread.run(Thread.java:841) Caused by: java.lang.IllegalStateException: Bad type: at java.base/jdk.experimental.bytecode.BasicTypeHelper.tag(BasicTypeHelper.java:76) at java.base/jdk.experimental.value.MethodHandleBuilder$IsolatedMethodBuilder$IsolatedMethodTypeHelper.tag(MethodHandleBuilder.java:196) at java.base/jdk.experimental.value.MethodHandleBuilder$IsolatedMethodBuilder$IsolatedMethodTypeHelper.tag(MethodHandleBuilder.java:138) at java.base/jdk.experimental.bytecode.CodeBuilder.writeStackMapType(CodeBuilder.java:1257) at java.base/jdk.experimental.bytecode.CodeBuilder.sameLocals1StackItemFrame(CodeBuilder.java:1305) at java.base/jdk.experimental.bytecode.TypedCodeBuilder.writeStackMapFrame(TypedCodeBuilder.java:1231) at java.base/jdk.experimental.bytecode.TypedCodeBuilder.emitStackMap(TypedCodeBuilder.java:1196) at java.base/jdk.experimental.bytecode.TypedCodeBuilder.resolveJumps(TypedCodeBuilder.java:1189) at java.base/jdk.experimental.bytecode.MacroCodeBuilder.label(MacroCodeBuilder.java:437) at compiler.valhalla.valuetypes.TestLWorld.lambda$static$3(TestLWorld.java:505) at java.base/jdk.experimental.bytecode.MethodBuilder.withCode(MethodBuilder.java:50) at java.base/jdk.experimental.value.MethodHandleBuilder.lambda$loadCode$1(MethodHandleBuilder.java:101) at java.base/jdk.experimental.bytecode.ClassBuilder.withMethod(ClassBuilder.java:204) at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:99) at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:77) at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:72) at compiler.valhalla.valuetypes.TestLWorld.(TestLWorld.java:492) ... 6 more Roland. From paul.sandoz at oracle.com Thu Apr 12 20:23:56 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 12 Apr 2018 13:23:56 -0700 Subject: MethodHandleBuilder bug? In-Reply-To: References: Message-ID: Thanks, i think there is a bug processing the label when merging stack state from which to generate a stack map entry. Something to do with liveness? i might be able to work it out more fully... but i am not too familiar with stack map entries. Paul. > On Apr 12, 2018, at 7:37 AM, Roland Westrelin wrote: > > > I noticed that this: > > private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), > "mergeNull", > MethodType.methodType(void.class, TestLWorld.class, boolean.class), > CODE -> { > CODE. > iload_1(). > iconst_0(). > ifcmp(TypeTag.I, CondKind.EQ, "null"). > aload_0(). > getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). > goto_("continue"). > label("null"). > aconst_null(). > label("continue"). > aload_0(). > swap(). > putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). > return_(); > } > ); > > works fine but if I swap the code in the if branches: > > private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), > "mergeNull", > MethodType.methodType(void.class, TestLWorld.class, boolean.class), > CODE -> { > CODE. > iload_1(). > iconst_0(). > ifcmp(TypeTag.I, CondKind.EQ, "null"). > aconst_null(). > goto_("continue"). > label("null"). > aload_0(). > getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). > label("continue"). > aload_0(). > swap(). > putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). > return_(); > } > ); > > then I get: > > java.lang.ExceptionInInitializerError > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) > at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) > at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) > at java.base/java.lang.reflect.Method.invoke(Method.java:564) > at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115) > at java.base/java.lang.Thread.run(Thread.java:841) > Caused by: java.lang.IllegalStateException: Bad type: > at java.base/jdk.experimental.bytecode.BasicTypeHelper.tag(BasicTypeHelper.java:76) > at java.base/jdk.experimental.value.MethodHandleBuilder$IsolatedMethodBuilder$IsolatedMethodTypeHelper.tag(MethodHandleBuilder.java:196) > at java.base/jdk.experimental.value.MethodHandleBuilder$IsolatedMethodBuilder$IsolatedMethodTypeHelper.tag(MethodHandleBuilder.java:138) > at java.base/jdk.experimental.bytecode.CodeBuilder.writeStackMapType(CodeBuilder.java:1257) > at java.base/jdk.experimental.bytecode.CodeBuilder.sameLocals1StackItemFrame(CodeBuilder.java:1305) > at java.base/jdk.experimental.bytecode.TypedCodeBuilder.writeStackMapFrame(TypedCodeBuilder.java:1231) > at java.base/jdk.experimental.bytecode.TypedCodeBuilder.emitStackMap(TypedCodeBuilder.java:1196) > at java.base/jdk.experimental.bytecode.TypedCodeBuilder.resolveJumps(TypedCodeBuilder.java:1189) > at java.base/jdk.experimental.bytecode.MacroCodeBuilder.label(MacroCodeBuilder.java:437) > at compiler.valhalla.valuetypes.TestLWorld.lambda$static$3(TestLWorld.java:505) > at java.base/jdk.experimental.bytecode.MethodBuilder.withCode(MethodBuilder.java:50) > at java.base/jdk.experimental.value.MethodHandleBuilder.lambda$loadCode$1(MethodHandleBuilder.java:101) > at java.base/jdk.experimental.bytecode.ClassBuilder.withMethod(ClassBuilder.java:204) > at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:99) > at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:77) > at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:72) > at compiler.valhalla.valuetypes.TestLWorld.(TestLWorld.java:492) > ... 6 more > > Roland. From paul.sandoz at oracle.com Thu Apr 12 21:25:40 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 12 Apr 2018 14:25:40 -0700 Subject: MethodHandleBuilder bug? In-Reply-To: References: Message-ID: Try with the patch below. I ain?t tested this throughly. Paul. diff -r 4d1e8489a000 src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java --- a/src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java Thu Apr 12 09:26:53 2018 -0400 +++ b/src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java Thu Apr 12 14:22:51 2018 -0700 @@ -73,6 +73,9 @@ case 'V': return TypeTag.V; default: + if (s == nullType()) { + return TypeTag.A; + } throw new IllegalStateException("Bad type: " + s); } } diff -r 4d1e8489a000 src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java --- a/src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java Thu Apr 12 09:26:53 2018 -0400 +++ b/src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java Thu Apr 12 14:22:51 2018 -0700 @@ -238,6 +238,7 @@ State(ArrayList stack, Vector locals) { this.stack = stack; this.locals = locals; + this.alive = true; } State() { > On Apr 12, 2018, at 1:23 PM, Paul Sandoz wrote: > > Thanks, i think there is a bug processing the label when merging stack state from which to generate a stack map entry. Something to do with liveness? i might be able to work it out more fully... but i am not too familiar with stack map entries. > > Paul. > >> On Apr 12, 2018, at 7:37 AM, Roland Westrelin wrote: >> >> >> I noticed that this: >> >> private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), >> "mergeNull", >> MethodType.methodType(void.class, TestLWorld.class, boolean.class), >> CODE -> { >> CODE. >> iload_1(). >> iconst_0(). >> ifcmp(TypeTag.I, CondKind.EQ, "null"). >> aload_0(). >> getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). >> goto_("continue"). >> label("null"). >> aconst_null(). >> label("continue"). >> aload_0(). >> swap(). >> putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). >> return_(); >> } >> ); >> >> works fine but if I swap the code in the if branches: >> >> private static final MethodHandle mergeNull = MethodHandleBuilder.loadCode(MethodHandles.lookup(), >> "mergeNull", >> MethodType.methodType(void.class, TestLWorld.class, boolean.class), >> CODE -> { >> CODE. >> iload_1(). >> iconst_0(). >> ifcmp(TypeTag.I, CondKind.EQ, "null"). >> aconst_null(). >> goto_("continue"). >> label("null"). >> aload_0(). >> getfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). >> label("continue"). >> aload_0(). >> swap(). >> putfield(TestLWorld.class, "valueField1", "Lcompiler/valhalla/valuetypes/MyValue1;"). >> return_(); >> } >> ); >> >> then I get: >> >> java.lang.ExceptionInInitializerError >> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) >> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> at java.base/java.lang.reflect.Method.invoke(Method.java:564) >> at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:115) >> at java.base/java.lang.Thread.run(Thread.java:841) >> Caused by: java.lang.IllegalStateException: Bad type: >> at java.base/jdk.experimental.bytecode.BasicTypeHelper.tag(BasicTypeHelper.java:76) >> at java.base/jdk.experimental.value.MethodHandleBuilder$IsolatedMethodBuilder$IsolatedMethodTypeHelper.tag(MethodHandleBuilder.java:196) >> at java.base/jdk.experimental.value.MethodHandleBuilder$IsolatedMethodBuilder$IsolatedMethodTypeHelper.tag(MethodHandleBuilder.java:138) >> at java.base/jdk.experimental.bytecode.CodeBuilder.writeStackMapType(CodeBuilder.java:1257) >> at java.base/jdk.experimental.bytecode.CodeBuilder.sameLocals1StackItemFrame(CodeBuilder.java:1305) >> at java.base/jdk.experimental.bytecode.TypedCodeBuilder.writeStackMapFrame(TypedCodeBuilder.java:1231) >> at java.base/jdk.experimental.bytecode.TypedCodeBuilder.emitStackMap(TypedCodeBuilder.java:1196) >> at java.base/jdk.experimental.bytecode.TypedCodeBuilder.resolveJumps(TypedCodeBuilder.java:1189) >> at java.base/jdk.experimental.bytecode.MacroCodeBuilder.label(MacroCodeBuilder.java:437) >> at compiler.valhalla.valuetypes.TestLWorld.lambda$static$3(TestLWorld.java:505) >> at java.base/jdk.experimental.bytecode.MethodBuilder.withCode(MethodBuilder.java:50) >> at java.base/jdk.experimental.value.MethodHandleBuilder.lambda$loadCode$1(MethodHandleBuilder.java:101) >> at java.base/jdk.experimental.bytecode.ClassBuilder.withMethod(ClassBuilder.java:204) >> at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:99) >> at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:77) >> at java.base/jdk.experimental.value.MethodHandleBuilder.loadCode(MethodHandleBuilder.java:72) >> at compiler.valhalla.valuetypes.TestLWorld.(TestLWorld.java:492) >> ... 6 more >> >> Roland. > From rwestrel at redhat.com Fri Apr 13 15:26:35 2018 From: rwestrel at redhat.com (Roland Westrelin) Date: Fri, 13 Apr 2018 17:26:35 +0200 Subject: MethodHandleBuilder bug? In-Reply-To: References: Message-ID: > Try with the patch below. Thanks for the quick fix. I will give it a try. Roland. From nlisker at gmail.com Sat Apr 14 03:39:28 2018 From: nlisker at gmail.com (Nir Lisker) Date: Sat, 14 Apr 2018 06:39:28 +0300 Subject: Building and testing Message-ID: Hello, I'm interested in playing with generic specialization. I've a couple of points to ask about. 1. Building. Following the instructions on the wiki [1], after cloning, the file get_source.sh does not exist and the commands chmod u+x get_source.sh ./get_source.sh fail. I ignored this and continued with bash configure make images which complete successfully. Is this fine? 2. Testing. I'm thinking of targeting my attempts at the JavaFX beans. Observable [2] demonstrates the type verbosity - each primitive type dictates type hierarchies just so that it can take or return its primitive value. Would this area be considered a proper testing grounds for generic specialization? Can I expect to be able to replace all type hierarchies of primitives, such as the ones for ReadOnlyJavaBeanBooleanProperty [3] and ReadOnlyBooleanWrapper [4] with a single generic one, or is it too optimistic? [1] https://wiki.openjdk.java.net/display/valhalla/Main [2] https://download.java.net/java/early_access/jdk11/docs/api/javafx.base/javafx/beans/Observable.html [3] https://download.java.net/java/early_access/jdk11/docs/api/javafx.base/javafx/beans/property/adapter/ReadOnlyJavaBeanBooleanProperty.html [4] https://download.java.net/java/early_access/jdk11/docs/api/javafx.base/javafx/beans/property/ReadOnlyBooleanWrapper.html Thanks, Nir From david.holmes at oracle.com Sun Apr 15 07:53:32 2018 From: david.holmes at oracle.com (David Holmes) Date: Sun, 15 Apr 2018 17:53:32 +1000 Subject: Building and testing In-Reply-To: References: Message-ID: <1621e7cc-9193-f456-ef14-6432e3ee979d@oracle.com> Hi Nir, On 14/04/2018 1:39 PM, Nir Lisker wrote: > Hello, > > I'm interested in playing with generic specialization. I've a couple of I don't think generic specialization is there is to play with yet. > points to ask about. > > 1. Building. Following the instructions on the wiki [1], after cloning, the > file get_source.sh does not exist and the commands > chmod u+x get_source.sh > ./get_source.sh > fail. I ignored this and continued with > bash configure > make images > which complete successfully. Is this fine? Yes. There is only a single repo now so we don't need get_source.sh any more. The wiki needs updating. Cheers, David > 2. Testing. I'm thinking of targeting my attempts at the JavaFX beans. > Observable [2] demonstrates the type verbosity - each primitive type > dictates type hierarchies just so that it can take or return its primitive > value. > > Would this area be considered a proper testing grounds for generic > specialization? > Can I expect to be able to replace all type hierarchies of primitives, such > as the ones for ReadOnlyJavaBeanBooleanProperty [3] and > ReadOnlyBooleanWrapper [4] with a single generic one, or is it too > optimistic? > > [1] https://wiki.openjdk.java.net/display/valhalla/Main > > [2] > https://download.java.net/java/early_access/jdk11/docs/api/javafx.base/javafx/beans/Observable.html > > [3] > https://download.java.net/java/early_access/jdk11/docs/api/javafx.base/javafx/beans/property/adapter/ReadOnlyJavaBeanBooleanProperty.html > > [4] > https://download.java.net/java/early_access/jdk11/docs/api/javafx.base/javafx/beans/property/ReadOnlyBooleanWrapper.html > > Thanks, > Nir > From david.holmes at oracle.com Mon Apr 16 05:49:42 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 16 Apr 2018 15:49:42 +1000 Subject: Questions about value types, numerics, Valhalla progress. In-Reply-To: References: Message-ID: Redirecting to valhalla-dev On 16/04/2018 12:02 PM, A Z wrote: > Is this the place to ask informal questions about progress > and efforts within Valhalla? No, as you've been informed before. Such questions belong on valhalla-dev. Please don't reply to valhalla-spec-observers. > What gains in the area of value types have been made? > Rill those acomplishments be included in Java 11? See the valhalla-dev archives - there is a lot of activity with values types: http://mail.openjdk.java.net/pipermail/valhalla-dev/ Also see: https://wiki.openjdk.java.net/display/valhalla/Minimal+Value+Types > What gains are being made in the area of enhancements > for Java numerics, pertaining to the areas of > type concordance, non-floating point arithmetic types, > arithmetic operator, true arbitrary precision arithmetic, > algebraic functions support? None that I'm aware of. David From qr60280 at gmail.com Mon Apr 16 08:12:50 2018 From: qr60280 at gmail.com (Zachary1234) Date: Mon, 16 Apr 2018 17:42:50 +0930 Subject: Valhalla, Java Operators, Floating Point Options. Message-ID: To whom it may concern, do the Value Types of Valhalla have practical implications for the future of Java numerics, particularly non-floating point integer and decimal numeric types, library support for those types like a StrictMath equivalent, along with granted options for Operator support with those types? How far away are non-floating point Java numeric improvements like this? Do value types include and facilitate options in this area? Will Java 11 included numeric oriented changes in these areas by means of the Valhalla Value types, with operators support options? qr From frederic.parain at oracle.com Wed Apr 18 19:38:03 2018 From: frederic.parain at oracle.com (Frederic Parain) Date: Wed, 18 Apr 2018 15:38:03 -0400 Subject: Lworld and calling convention In-Reply-To: References: Message-ID: <83EF89AC-B3A2-4091-998B-C1DEB6E8D9F6@oracle.com> Roland, Thank you for this summary. Would it help to have javac to annotate which arguments are expected to be value classes? In this case: - only classes of annotated arguments would be pre-loaded (no additional pre-loading for old code) - after pre-loading, if the class is a value class, the calling convention could use scalarisation, otherwise argument is passed by reference - arguments without the annotation would always be passed by reference With this proposal, the calling convention would depend only on the information provided by javac, not on the value of the arguments being passed (passing null would not impact the determination of the calling convention). However, I?m not sure it would solve the issue with method inlining if the method candidate for in-lining are not known before the compilation starts. Fred > On Apr 5, 2018, at 11:53, Roland Westrelin wrote: > > > I started to work on bringing the calling convention from MVT to the > Lworld. > > The first problem I hit is that when adapters are generated, classes of > the method's signature may not have been loaded yet so it's impossible > to tell which argument is a value and which is not. > > I then looked at what it would take to make adapter generation lazy. I > have a prototype that seems to allow for lazy generation but then the > question is what are the events that should trigger adapter generation? > > Going from interpreter to compiled code (where the i2c is needed) is > fairly simple. We don't need the i2c until compiled code exists. We > already load the classes of the signature before we trigger the > compilation of the method so generating the adapters at that point would > be fine. > > Going from compiled code to the interpreter seems much trickier. Let's > say we compile m(). The compiler will trim some untaken paths and inline > some methods so it's only possible to tell what call sites will be in > the compiled m() as it's being compiled or once it's compiled. There's > no guarantee that the classes of the signatures of these call sites are > loaded when the call sites are compiled because, in legacy code, null > may be passed for a value argument. > > We can't load classes as we compile the method because the compiler > threads don't perform class loading. > > If compiled method m() has a call site: > > m2(v1, v2) > > and v1 and v2 are values (from 2 different classes), that call site may > be compiled as: > > m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) > > (passing fields) if when the call site was compiled, classes for v1 & v2 > are loaded. > > or: > > m2(v1, v2.f1, v2.f2, ..) > > (passing a reference to v1) if the class for v1 was not loaded when the > call site was compiled > > or: > > m2(v1.f1, v1.f2, .., v2) > > if the class for v2 was not loaded when the call site was compiled > > or: > > m2(v1, v2) > > if both classes were not loaded when the call site was compiled. > > So for a single call site with 2 value arguments, there are 4 ways of > compiling the call site. > > We could generate the adapters the first time the call in compiled > method m() is executed (at call resolution time) but then we need to > generate an adapter that matches how the call site was compiled. How do > we know which of the 4 ways of performing the call it is? > > As code executes and classes get loaded, we might need several adapters > generated. Maybe some m2() call site was compiled as: > > m2(v1, v2) > > but then one class got loaded so another one got compiled as: > > m2(v1, v2.f1, v2.f2, ..) > > and then another one as: > > m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) > > and we need 3 different c2i adapters. > > Add to this, that we can't deoptimize at call resolution time because > compiled code only has debug info to resume execution after the call. > > I see 2 ways forward with this. Either we eagerly load classes of > signatures so we can generate the adapters eagerly as is done > currently. Or we refuse to compile a call site for which the classes of > the signature are not loaded (replace the call with an uncommon trap and > trigger class loading?). In that case, we would sometime drop perfectly > good code. > > Comments? > > Roland. > From david.simms at oracle.com Thu Apr 19 08:04:42 2018 From: david.simms at oracle.com (David Simms) Date: Thu, 19 Apr 2018 10:04:42 +0200 Subject: Value type hash code In-Reply-To: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> Message-ID: <689755dd-cb2e-705c-49da-26b1c8af6798@oracle.com> Summary of points raised: * Implementation specification: besides the general contract [1], implementation doesn't need to be specified o this has advantages to JDK and JVM developers to enable change, protects users from said future changes * Default implementation o Javac could provide the default implementation + bloats class file forever o BSM mechanism described by John enables more flexibility, efficiency and better optimization opportunities + e.g. BSM may read annotations at lookup time, allowing users to decoratively specify which fields and which method for handling references + may have bootstrapping issues, if so, said JDK classes need to implement hashCode themselves o Even if the JVM doesn't implement it directly, it shouldn't crash or behave erratically + JVM: Return 0, -1, 4711, or throw exception (doesn't matter given the point above, 0 for argument's sake) ? * On the topic of calling reference fields, calling "hashCode()" or using "System.identityHashCode()" o "System.identityHashCode()" is consistent with "Arrays.hashCode(Object[])" [2] + Almost meaningless to the user, many think it is a mistake o Calling "hashCode()" is consistent with "List.hashCode(Object[])" [3] + may result in recursion or costly traversal # This is fine, user needs to decide what to do by supplying their own... o BSM method can help user to declare what they prefer Obviously a similar discussion can be had for "equals()", except this issue doesn't really involve the JVM (as hashCode does). Clearly being able to declaratively control hash/equals deep vs identity is very powerful...we'll be prototyping looking for further technical issues. Feel free to call shenanigans if I have something wrong. Agreeing to disagree is also an option, and nothing is set in stone, still prototyping. Thanks for all the feedback ! /David Simms [1] https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() [2] https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) [3] https://docs.oracle.com/javase/10/docs/api/java/util/List.html#hashCode() From daniel.latremoliere at gmail.com Thu Apr 19 10:38:44 2018 From: daniel.latremoliere at gmail.com (=?UTF-8?B?RGFuaWVsIExhdHLDqW1vbGnDqHJl?=) Date: Thu, 19 Apr 2018 12:38:44 +0200 Subject: Value type hash code In-Reply-To: <689755dd-cb2e-705c-49da-26b1c8af6798@oracle.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <689755dd-cb2e-705c-49da-26b1c8af6798@oracle.com> Message-ID: <39040980-db0e-94f9-679b-b1d14c47b0e9@gmail.com> A value type is explicitly immutable by design and not by documentation, then equals/hashcode methods needs to have the same immutable behaviour not just by documentation but also by design. These methods can not be delegated to user (because it would allow value type design bugs in immutability if hashCode change when user implement hash code with a random function or by following a reference to a mutable object. The only really immutable available information for a reference field is System.identityHashCode(), then it need to be used. NB: A value type is (for me) pure data designed for performance: it can be a pair of integers, but it can not be a fraction. If you want comparison behaviour of a fraction, you can do a fast equalsAsFraction method by cross multiplication, but you can not implements fast and correct hash code (you would need to simplify the fraction to have no common divider between numerator and denominator). Daniel. Le 19/04/2018 ? 10:04, David Simms a ?crit?: > > Summary of points raised: > > ?* Implementation specification: besides the general contract [1], > ?? implementation doesn't need to be specified > ???? o this has advantages to JDK and JVM developers to enable change, > ?????? protects users from said future changes > ?* Default implementation > ???? o Javac could provide the default implementation > ???????? + bloats class file forever > ???? o BSM mechanism described by John enables more flexibility, > ?????? efficiency and better optimization opportunities > ???????? + e.g. BSM may read annotations at lookup time, allowing users > ?????????? to decoratively specify which fields and which method for > ?????????? handling references > ???????? + may have bootstrapping issues, if so, said JDK classes need > ?????????? to implement hashCode themselves > ???? o Even if the JVM doesn't implement it directly, it shouldn't > ?????? crash or behave erratically > ???????? + JVM: Return 0, -1, 4711, or throw exception (doesn't matter > ?????????? given the point above, 0 for argument's sake) ? > ?* On the topic of calling reference fields, calling "hashCode()" or > ?? using "System.identityHashCode()" > ???? o "System.identityHashCode()" is consistent with > ?????? "Arrays.hashCode(Object[])" [2] > ???????? + Almost meaningless to the user, many think it is a mistake > ???? o Calling "hashCode()" is consistent with > ?????? "List.hashCode(Object[])" [3] > ???????? + may result in recursion or costly traversal > ???????????? # This is fine, user needs to decide what to do by > ?????????????? supplying their own... > ???? o BSM method can help user to declare what they prefer > > Obviously a similar discussion can be had for "equals()", except this > issue doesn't really involve the JVM (as hashCode does). > > Clearly being able to declaratively control hash/equals deep vs > identity is very powerful...we'll be prototyping looking for further > technical issues. > > > Feel free to call shenanigans if I have something wrong. Agreeing to > disagree is also an option, and nothing is set in stone, still > prototyping. > > Thanks for all the feedback ! > > /David Simms > > > [1] > https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() > [2] > https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) > [3] > https://docs.oracle.com/javase/10/docs/api/java/util/List.html#hashCode() > > --- Just for history, my response to R?mi's mail last week on this subject in amber (forbidden because discussion is not allowed on the corresponding mailing list, and his following copy [1] of his mail was on a reserved mailing list, then I had administrative phobia): [1]: http://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000557.html -------- Message transf?r? -------- Sujet?: Re: Record design (and ancillary fields) Date?: Sun, 15 Apr 2018 06:19:44 +0200 De?: Daniel Latr?moli?re Pour?: Remi Forax Copie ??: amber-spec-comments Le 14/04/2018 ? 23:18, Remi Forax a ?crit?: > I do not think we have to do something specific for supporting > relational database mapping,[...] I'm not asking for object-relational mapping, only for not forgetting experience from database design. MapReduce in Google index database is not the same than map/reduce in java.util.stream, but they are the same design pattern. >> PS: Given primitive/value type disallow cyclical references, this will >> prohibit StackOverflowException in equals/hashCode methods. > only if an equals on a value type that contains an object doesn't call > equals on that object. Another design would probably be a bug in these compiler generated methods for value type: value types are using pass-by-value convention for methods. They are like primitives (boolean, int, float, ... and address!). For a value type, a field targeting an object is opaque, value type know only address, not pointed object. From point of view of compiler, equals/hashCode methods of value types would be using all fields but these fields can only be primitive or value types. Then, recursion is only possible between value types, and always descending, then finite (like Fermat). After flattening all levels of value types inside a value type, it will become non recursive and using only primitives. Given pass-by-value design, these generated methods would be required to be defined like a field containing an address value (not a field targeting an object): - equals use identity test on the field (not equality test). - hashCode use result of System.identityHashCode on targeted object (not hashCode virtual method, which would also create potentially NullPointerException in case of null address if not tested before). Daniel. From karen.kinnear at oracle.com Thu Apr 19 13:27:59 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 19 Apr 2018 09:27:59 -0400 Subject: Lworld and calling convention In-Reply-To: <83EF89AC-B3A2-4091-998B-C1DEB6E8D9F6@oracle.com> References: <83EF89AC-B3A2-4091-998B-C1DEB6E8D9F6@oracle.com> Message-ID: <26EC1932-5CA5-44D1-86C3-0A702E370C50@oracle.com> Roland, Frederic, Ignoring -Xcomp - Do you have a sense of how often we have a method that is being compiled due to profiling and the methods being inlined have never been interpreted or compiled? What if the interpreter were to load all classes for the method signature as part of invocation? Right now, any argument that is not null should already have the class loaded, so perhaps this would not be a huge additional overhead for the first invocation of a method? Or combine with Frederic?s proposal, and the interpreter would preload any classes in the signature that are annotated as value types? Then if the compiler were to check the methods it is inlining and if the signature classes have not been loaded yet, then perform the uncommon trap - or stop inlining at that point. Perhaps if the interpreter preloads then this becomes very rare? One challenge I see with the javac annotation is that we still run the risk of a mismatch between the caller and callee - if we have separate compilation and one thinks we have a value type and the other does not. If the caller thinks we have a value type - and we therefore preload the class, and it is not, then ICCE - so not a problem. If the caller thinks we have a value type and the class is a value type and the callee does not think so - is there a way to detect the mismatch and deopt? Same issue if the caller thinks we do not have a value type and the callee thinks we do. thanks, Karen > On Apr 18, 2018, at 3:38 PM, Frederic Parain wrote: > > Roland, > > Thank you for this summary. > > Would it help to have javac to annotate which arguments are expected > to be value classes? In this case: > - only classes of annotated arguments would be pre-loaded (no additional > pre-loading for old code) > - after pre-loading, if the class is a value class, the calling convention could > use scalarisation, otherwise argument is passed by reference > - arguments without the annotation would always be passed by reference > > With this proposal, the calling convention would depend only on the > information provided by javac, not on the value of the arguments being > passed (passing null would not impact the determination of the calling > convention). > > However, I?m not sure it would solve the issue with method inlining if the > method candidate for in-lining are not known before the compilation starts. > > Fred > > >> On Apr 5, 2018, at 11:53, Roland Westrelin wrote: >> >> >> I started to work on bringing the calling convention from MVT to the >> Lworld. >> >> The first problem I hit is that when adapters are generated, classes of >> the method's signature may not have been loaded yet so it's impossible >> to tell which argument is a value and which is not. >> >> I then looked at what it would take to make adapter generation lazy. I >> have a prototype that seems to allow for lazy generation but then the >> question is what are the events that should trigger adapter generation? >> >> Going from interpreter to compiled code (where the i2c is needed) is >> fairly simple. We don't need the i2c until compiled code exists. We >> already load the classes of the signature before we trigger the >> compilation of the method so generating the adapters at that point would >> be fine. >> >> Going from compiled code to the interpreter seems much trickier. Let's >> say we compile m(). The compiler will trim some untaken paths and inline >> some methods so it's only possible to tell what call sites will be in >> the compiled m() as it's being compiled or once it's compiled. There's >> no guarantee that the classes of the signatures of these call sites are >> loaded when the call sites are compiled because, in legacy code, null >> may be passed for a value argument. >> >> We can't load classes as we compile the method because the compiler >> threads don't perform class loading. >> >> If compiled method m() has a call site: >> >> m2(v1, v2) >> >> and v1 and v2 are values (from 2 different classes), that call site may >> be compiled as: >> >> m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) >> >> (passing fields) if when the call site was compiled, classes for v1 & v2 >> are loaded. >> >> or: >> >> m2(v1, v2.f1, v2.f2, ..) >> >> (passing a reference to v1) if the class for v1 was not loaded when the >> call site was compiled >> >> or: >> >> m2(v1.f1, v1.f2, .., v2) >> >> if the class for v2 was not loaded when the call site was compiled >> >> or: >> >> m2(v1, v2) >> >> if both classes were not loaded when the call site was compiled. >> >> So for a single call site with 2 value arguments, there are 4 ways of >> compiling the call site. >> >> We could generate the adapters the first time the call in compiled >> method m() is executed (at call resolution time) but then we need to >> generate an adapter that matches how the call site was compiled. How do >> we know which of the 4 ways of performing the call it is? >> >> As code executes and classes get loaded, we might need several adapters >> generated. Maybe some m2() call site was compiled as: >> >> m2(v1, v2) >> >> but then one class got loaded so another one got compiled as: >> >> m2(v1, v2.f1, v2.f2, ..) >> >> and then another one as: >> >> m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) >> >> and we need 3 different c2i adapters. >> >> Add to this, that we can't deoptimize at call resolution time because >> compiled code only has debug info to resume execution after the call. >> >> I see 2 ways forward with this. Either we eagerly load classes of >> signatures so we can generate the adapters eagerly as is done >> currently. Or we refuse to compile a call site for which the classes of >> the signature are not loaded (replace the call with an uncommon trap and >> trigger class loading?). In that case, we would sometime drop perfectly >> good code. >> >> Comments? >> >> Roland. >> > From david.simms at oracle.com Thu Apr 19 13:51:21 2018 From: david.simms at oracle.com (david.simms at oracle.com) Date: Thu, 19 Apr 2018 13:51:21 +0000 Subject: hg: valhalla/valhalla: 8201329: [lword] Interpreter crashed on attempt to allocate two-dimensional array of values Message-ID: <201804191351.w3JDpM1x010581@aojmv0008.oracle.com> Changeset: edb20ed58f7a Author: dsimms Date: 2018-04-19 15:04 +0200 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/edb20ed58f7a 8201329: [lword] Interpreter crashed on attempt to allocate two-dimensional array of values ! src/hotspot/share/oops/valueArrayKlass.cpp ! test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java From me at yawk.at Thu Apr 19 16:04:50 2018 From: me at yawk.at (Jonas Konrad) Date: Thu, 19 Apr 2018 18:04:50 +0200 Subject: Value type hash code In-Reply-To: <39040980-db0e-94f9-679b-b1d14c47b0e9@gmail.com> References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <689755dd-cb2e-705c-49da-26b1c8af6798@oracle.com> <39040980-db0e-94f9-679b-b1d14c47b0e9@gmail.com> Message-ID: That would make it useless in almost all cases where reference types are present in the value. Even something simple like a String field (which is definitely immutable) would use identity hash and make this hashcode useless. It might be nice conceptually but if we do that we might as well throw an exception when a reference type is present. It'd be useful in the same cases (meaning none) and it would at least be fail-fast and users wouldn't be bitten by behaviour like identityHashCode of strings. - Jonas On 04/19/2018 12:38 PM, Daniel Latr?moli?re wrote: > A value type is explicitly immutable by design and not by documentation, > then equals/hashcode methods needs to have the same immutable behaviour > not just by documentation but also by design. These methods can not be > delegated to user (because it would allow value type design bugs in > immutability if hashCode change when user implement hash code with a > random function or by following a reference to a mutable object. > > The only really immutable available information for a reference field is > System.identityHashCode(), then it need to be used. > > NB: A value type is (for me) pure data designed for performance: it can > be a pair of integers, but it can not be a fraction. If you want > comparison behaviour of a fraction, you can do a fast equalsAsFraction > method by cross multiplication, but you can not implements fast and > correct hash code (you would need to simplify the fraction to have no > common divider between numerator and denominator). > > > Daniel. > > > Le 19/04/2018 ? 10:04, David Simms a ?crit?: >> >> Summary of points raised: >> >> ?* Implementation specification: besides the general contract [1], >> ?? implementation doesn't need to be specified >> ???? o this has advantages to JDK and JVM developers to enable change, >> ?????? protects users from said future changes >> ?* Default implementation >> ???? o Javac could provide the default implementation >> ???????? + bloats class file forever >> ???? o BSM mechanism described by John enables more flexibility, >> ?????? efficiency and better optimization opportunities >> ???????? + e.g. BSM may read annotations at lookup time, allowing users >> ?????????? to decoratively specify which fields and which method for >> ?????????? handling references >> ???????? + may have bootstrapping issues, if so, said JDK classes need >> ?????????? to implement hashCode themselves >> ???? o Even if the JVM doesn't implement it directly, it shouldn't >> ?????? crash or behave erratically >> ???????? + JVM: Return 0, -1, 4711, or throw exception (doesn't matter >> ?????????? given the point above, 0 for argument's sake) ? >> ?* On the topic of calling reference fields, calling "hashCode()" or >> ?? using "System.identityHashCode()" >> ???? o "System.identityHashCode()" is consistent with >> ?????? "Arrays.hashCode(Object[])" [2] >> ???????? + Almost meaningless to the user, many think it is a mistake >> ???? o Calling "hashCode()" is consistent with >> ?????? "List.hashCode(Object[])" [3] >> ???????? + may result in recursion or costly traversal >> ???????????? # This is fine, user needs to decide what to do by >> ?????????????? supplying their own... >> ???? o BSM method can help user to declare what they prefer >> >> Obviously a similar discussion can be had for "equals()", except this >> issue doesn't really involve the JVM (as hashCode does). >> >> Clearly being able to declaratively control hash/equals deep vs >> identity is very powerful...we'll be prototyping looking for further >> technical issues. >> >> >> Feel free to call shenanigans if I have something wrong. Agreeing to >> disagree is also an option, and nothing is set in stone, still >> prototyping. >> >> Thanks for all the feedback ! >> >> /David Simms >> >> >> [1] >> https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() >> >> [2] >> https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) >> >> [3] >> https://docs.oracle.com/javase/10/docs/api/java/util/List.html#hashCode() >> >> > > --- > > Just for history, my response to R?mi's mail last week on this subject > in amber (forbidden because discussion is not allowed on the > corresponding mailing list, and his following copy [1] of his mail was > on a reserved mailing list, then I had administrative phobia): > > [1]: > http://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000557.html > > > > -------- Message transf?r? -------- > Sujet?:???? Re: Record design (and ancillary fields) > Date?:???? Sun, 15 Apr 2018 06:19:44 +0200 > De?:???? Daniel Latr?moli?re > Pour?:???? Remi Forax > Copie ??:???? amber-spec-comments > > > Le 14/04/2018 ? 23:18, Remi Forax a ?crit?: >> I do not think we have to do something specific for supporting >> relational database mapping,[...] > I'm not asking for object-relational mapping, only for not forgetting > experience from database design. > MapReduce in Google index database is not the same than map/reduce in > java.util.stream, but they are the same design pattern. > >>> PS: Given primitive/value type disallow cyclical references, this will >>> prohibit StackOverflowException in equals/hashCode methods. >> only if an equals on a value type that contains an object doesn't call >> equals on that object. > Another design would probably be a bug in these compiler generated > methods for value type: value types are using pass-by-value convention > for methods. > > They are like primitives (boolean, int, float, ... and address!). For a > value type, a field targeting an object is opaque, value type know only > address, not pointed object. > > From point of view of compiler, equals/hashCode methods of value types > would be using all fields but these fields can only be primitive or > value types. Then, recursion is only possible between value types, and > always descending, then finite (like Fermat). After flattening all > levels of value types inside a value type, it will become non recursive > and using only primitives. > > Given pass-by-value design, these generated methods would be required to > be defined like a field containing an address value (not a field > targeting an object): > - equals use identity test on the field (not equality test). > - hashCode use result of System.identityHashCode on targeted object (not > hashCode virtual method, which would also create potentially > NullPointerException in case of null address if not tested before). > > Daniel. From karen.kinnear at oracle.com Thu Apr 19 19:09:49 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 19 Apr 2018 15:09:49 -0400 Subject: Lworld and calling convention In-Reply-To: <26EC1932-5CA5-44D1-86C3-0A702E370C50@oracle.com> References: <83EF89AC-B3A2-4091-998B-C1DEB6E8D9F6@oracle.com> <26EC1932-5CA5-44D1-86C3-0A702E370C50@oracle.com> Message-ID: Roland - You can ignore my email below here - I had misunderstood what Frederic was suggesting. Only addition to add to Frederic?s proposal - which has javac just annotate the declaring class for a method - is that perhaps we can do the pre-loading of the classes for parameters annotated as value classes when we link a class - so a bit lazily - since we need the information to create the vtables and itables. I do not know the C2 code. What little I have read implies that the static receiver class has to be initialized or we uncommon trap. I don?t know if inlining decisions have the same prerequisite. thanks, Karen > On Apr 19, 2018, at 9:27 AM, Karen Kinnear wrote: > > thanks, > Karen > >> On Apr 18, 2018, at 3:38 PM, Frederic Parain wrote: >> >> Roland, >> >> Thank you for this summary. >> >> Would it help to have javac to annotate which arguments are expected >> to be value classes? In this case: >> - only classes of annotated arguments would be pre-loaded (no additional >> pre-loading for old code) >> - after pre-loading, if the class is a value class, the calling convention could >> use scalarisation, otherwise argument is passed by reference >> - arguments without the annotation would always be passed by reference >> >> With this proposal, the calling convention would depend only on the >> information provided by javac, not on the value of the arguments being >> passed (passing null would not impact the determination of the calling >> convention). >> >> However, I?m not sure it would solve the issue with method inlining if the >> method candidate for in-lining are not known before the compilation starts. >> >> Fred >> >> >>> On Apr 5, 2018, at 11:53, Roland Westrelin wrote: >>> >>> >>> I started to work on bringing the calling convention from MVT to the >>> Lworld. >>> >>> The first problem I hit is that when adapters are generated, classes of >>> the method's signature may not have been loaded yet so it's impossible >>> to tell which argument is a value and which is not. >>> >>> I then looked at what it would take to make adapter generation lazy. I >>> have a prototype that seems to allow for lazy generation but then the >>> question is what are the events that should trigger adapter generation? >>> >>> Going from interpreter to compiled code (where the i2c is needed) is >>> fairly simple. We don't need the i2c until compiled code exists. We >>> already load the classes of the signature before we trigger the >>> compilation of the method so generating the adapters at that point would >>> be fine. >>> >>> Going from compiled code to the interpreter seems much trickier. Let's >>> say we compile m(). The compiler will trim some untaken paths and inline >>> some methods so it's only possible to tell what call sites will be in >>> the compiled m() as it's being compiled or once it's compiled. There's >>> no guarantee that the classes of the signatures of these call sites are >>> loaded when the call sites are compiled because, in legacy code, null >>> may be passed for a value argument. >>> >>> We can't load classes as we compile the method because the compiler >>> threads don't perform class loading. >>> >>> If compiled method m() has a call site: >>> >>> m2(v1, v2) >>> >>> and v1 and v2 are values (from 2 different classes), that call site may >>> be compiled as: >>> >>> m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) >>> >>> (passing fields) if when the call site was compiled, classes for v1 & v2 >>> are loaded. >>> >>> or: >>> >>> m2(v1, v2.f1, v2.f2, ..) >>> >>> (passing a reference to v1) if the class for v1 was not loaded when the >>> call site was compiled >>> >>> or: >>> >>> m2(v1.f1, v1.f2, .., v2) >>> >>> if the class for v2 was not loaded when the call site was compiled >>> >>> or: >>> >>> m2(v1, v2) >>> >>> if both classes were not loaded when the call site was compiled. >>> >>> So for a single call site with 2 value arguments, there are 4 ways of >>> compiling the call site. >>> >>> We could generate the adapters the first time the call in compiled >>> method m() is executed (at call resolution time) but then we need to >>> generate an adapter that matches how the call site was compiled. How do >>> we know which of the 4 ways of performing the call it is? >>> >>> As code executes and classes get loaded, we might need several adapters >>> generated. Maybe some m2() call site was compiled as: >>> >>> m2(v1, v2) >>> >>> but then one class got loaded so another one got compiled as: >>> >>> m2(v1, v2.f1, v2.f2, ..) >>> >>> and then another one as: >>> >>> m2(v1.f1, v1.f2, .., v2.f1, v2.f2, ..) >>> >>> and we need 3 different c2i adapters. >>> >>> Add to this, that we can't deoptimize at call resolution time because >>> compiled code only has debug info to resume execution after the call. >>> >>> I see 2 ways forward with this. Either we eagerly load classes of >>> signatures so we can generate the adapters eagerly as is done >>> currently. Or we refuse to compile a call site for which the classes of >>> the signature are not loaded (replace the call with an uncommon trap and >>> trigger class loading?). In that case, we would sometime drop perfectly >>> good code. >>> >>> Comments? >>> >>> Roland. >>> >> > From daniel.latremoliere at gmail.com Thu Apr 19 20:13:17 2018 From: daniel.latremoliere at gmail.com (=?ISO-8859-1?Q?Daniel_Latr=E9moli=E8re?=) Date: Thu, 19 Apr 2018 22:13:17 +0200 Subject: Value type hash code In-Reply-To: References: <0a2cabb9-f032-a371-b5e6-b56d2dce65d6@oracle.com> <689755dd-cb2e-705c-49da-26b1c8af6798@oracle.com> <39040980-db0e-94f9-679b-b1d14c47b0e9@gmail.com> Message-ID: Why? If you want to use value types as keys in HashMap, you will probably need enhancement to java.util.HashMap implementation for allowing custom hashing strategy. This is already possible in SortedMap where you can provide your own Comparator and this is perfectly doable in HashMap, like done in Eclipse Collections: https://www.eclipse.org/collections/javadoc/9.1.0/org/eclipse/collections/api/block/HashingStrategy.html --- Honestly, I can perfectly understand that you dislike this implementation of equals/hashCode but (for me), the root cause of problem is the existence of these methods in Object. Given this mandatory existence in all classes, clients expects these methods exists with declared contracts, but their implementation is frequently lacking or erroneous/obsolete in practice. I would prefer if these methods doesn't exists in new code, like value types or records. The algorithm using identity test for reference fields would then be used only for testing if two value types containing these references have same identity (a == b), which would be a clear behavior. But this would need that Oracle change the root "class" of all instances and create a super-class of Object for, at least, value types and records, with only the really defined "methods" (getClass(), ==) and removing all others methods: - like hashCode(), equals(Object), toString(), clone(), finalize(): for ceasing to mandate their existence even if the developer doesn't implemented these methods in practice for a specific class. - notify* and wait* because their behavior will be problematic for value types. Given, this doesn't seems to be the direction of Oracle, I try to avoid the biggest issue of unuseful methods (hashCode, equals) due to being frequently untrustable, because they are existing even if developer doesn't want/had time to implement these methods. In a simple sentence: I prefer a trustable method doing unuseful things than an untrustable method. Daniel. Le 19 avril 2018 18:04:50 GMT+02:00, Jonas Konrad a ?crit : >That would make it useless in almost all cases where reference types >are >present in the value. Even something simple like a String field (which >is definitely immutable) would use identity hash and make this hashcode > >useless. > >It might be nice conceptually but if we do that we might as well throw >an exception when a reference type is present. It'd be useful in the >same cases (meaning none) and it would at least be fail-fast and users >wouldn't be bitten by behaviour like identityHashCode of strings. > >- Jonas > >On 04/19/2018 12:38 PM, Daniel Latr?moli?re wrote: >> A value type is explicitly immutable by design and not by >documentation, >> then equals/hashcode methods needs to have the same immutable >behaviour >> not just by documentation but also by design. These methods can not >be >> delegated to user (because it would allow value type design bugs in >> immutability if hashCode change when user implement hash code with a >> random function or by following a reference to a mutable object. >> >> The only really immutable available information for a reference field >is >> System.identityHashCode(), then it need to be used. >> >> NB: A value type is (for me) pure data designed for performance: it >can >> be a pair of integers, but it can not be a fraction. If you want >> comparison behaviour of a fraction, you can do a fast >equalsAsFraction >> method by cross multiplication, but you can not implements fast and >> correct hash code (you would need to simplify the fraction to have no > >> common divider between numerator and denominator). >> >> >> Daniel. >> >> >> Le 19/04/2018 ? 10:04, David Simms a ?crit?: >>> >>> Summary of points raised: >>> >>> ?* Implementation specification: besides the general contract [1], >>> ?? implementation doesn't need to be specified >>> ???? o this has advantages to JDK and JVM developers to enable >change, >>> ?????? protects users from said future changes >>> ?* Default implementation >>> ???? o Javac could provide the default implementation >>> ???????? + bloats class file forever >>> ???? o BSM mechanism described by John enables more flexibility, >>> ?????? efficiency and better optimization opportunities >>> ???????? + e.g. BSM may read annotations at lookup time, allowing >users >>> ?????????? to decoratively specify which fields and which method for >>> ?????????? handling references >>> ???????? + may have bootstrapping issues, if so, said JDK classes >need >>> ?????????? to implement hashCode themselves >>> ???? o Even if the JVM doesn't implement it directly, it shouldn't >>> ?????? crash or behave erratically >>> ???????? + JVM: Return 0, -1, 4711, or throw exception (doesn't >matter >>> ?????????? given the point above, 0 for argument's sake) ? >>> ?* On the topic of calling reference fields, calling "hashCode()" or >>> ?? using "System.identityHashCode()" >>> ???? o "System.identityHashCode()" is consistent with >>> ?????? "Arrays.hashCode(Object[])" [2] >>> ???????? + Almost meaningless to the user, many think it is a >mistake >>> ???? o Calling "hashCode()" is consistent with >>> ?????? "List.hashCode(Object[])" [3] >>> ???????? + may result in recursion or costly traversal >>> ???????????? # This is fine, user needs to decide what to do by >>> ?????????????? supplying their own... >>> ???? o BSM method can help user to declare what they prefer >>> >>> Obviously a similar discussion can be had for "equals()", except >this >>> issue doesn't really involve the JVM (as hashCode does). >>> >>> Clearly being able to declaratively control hash/equals deep vs >>> identity is very powerful...we'll be prototyping looking for further > >>> technical issues. >>> >>> >>> Feel free to call shenanigans if I have something wrong. Agreeing to > >>> disagree is also an option, and nothing is set in stone, still >>> prototyping. >>> >>> Thanks for all the feedback ! >>> >>> /David Simms >>> >>> >>> [1] >>> >https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode() > >>> >>> [2] >>> >https://docs.oracle.com/javase/10/docs/api/java/util/Arrays.html#hashCode(java.lang.Object%5B%5D) > >>> >>> [3] >>> >https://docs.oracle.com/javase/10/docs/api/java/util/List.html#hashCode() >>> >>> >> >> --- >> >> Just for history, my response to R?mi's mail last week on this >subject >> in amber (forbidden because discussion is not allowed on the >> corresponding mailing list, and his following copy [1] of his mail >was >> on a reserved mailing list, then I had administrative phobia): >> >> [1]: >> >http://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000557.html > >> >> >> >> -------- Message transf?r? -------- >> Sujet?:???? Re: Record design (and ancillary fields) >> Date?:???? Sun, 15 Apr 2018 06:19:44 +0200 >> De?:???? Daniel Latr?moli?re >> Pour?:???? Remi Forax >> Copie ??:???? amber-spec-comments > >> >> >> Le 14/04/2018 ? 23:18, Remi Forax a ?crit?: >>> I do not think we have to do something specific for supporting >>> relational database mapping,[...] >> I'm not asking for object-relational mapping, only for not forgetting > >> experience from database design. >> MapReduce in Google index database is not the same than map/reduce in > >> java.util.stream, but they are the same design pattern. >> >>>> PS: Given primitive/value type disallow cyclical references, this >will >>>> prohibit StackOverflowException in equals/hashCode methods. >>> only if an equals on a value type that contains an object doesn't >call >>> equals on that object. >> Another design would probably be a bug in these compiler generated >> methods for value type: value types are using pass-by-value >convention >> for methods. >> >> They are like primitives (boolean, int, float, ... and address!). For >a >> value type, a field targeting an object is opaque, value type know >only >> address, not pointed object. >> >> From point of view of compiler, equals/hashCode methods of value >types >> would be using all fields but these fields can only be primitive or >> value types. Then, recursion is only possible between value types, >and >> always descending, then finite (like Fermat). After flattening all >> levels of value types inside a value type, it will become non >recursive >> and using only primitives. >> >> Given pass-by-value design, these generated methods would be required >to >> be defined like a field containing an address value (not a field >> targeting an object): >> - equals use identity test on the field (not equality test). >> - hashCode use result of System.identityHashCode on targeted object >(not >> hashCode virtual method, which would also create potentially >> NullPointerException in case of null address if not tested before). >> >> Daniel. From kumar.x.srinivasan at oracle.com Fri Apr 20 20:43:22 2018 From: kumar.x.srinivasan at oracle.com (Kumar Srinivasan) Date: Fri, 20 Apr 2018 13:43:22 -0700 Subject: RFR: 8187645: [Nestmates] Update Pack200 and tests, to recognize and process new Nestmate attributes Message-ID: <5ADA50EA.6000600@oracle.com> Hi David, Could you please sponsor this patch and push to valhalla's nestmates branch. http://cr.openjdk.java.net/~ksrini/8187645/ Thanks Kumar PS: I am not a member on this list, so please email me directly. From rahman.usta.88 at gmail.com Sat Apr 21 14:55:49 2018 From: rahman.usta.88 at gmail.com (Rahman USTA) Date: Sat, 21 Apr 2018 16:55:49 +0200 Subject: Testing Primitives in Generics and Value Types Message-ID: Hi, I built valhalla from source code and want to test primitives in generics and value types. For testing primitives I created Box class; public class Box { private final T t; public Box(T t) {this.t= t;} public T get() {return t;} public static void main(String[] args){ Box box= new Box<>(5); System.out.println(box.get()); } } and tried to compile with javac in valhalla, but it gives; Box.java:8: error: unexpected type Box box= new Box<>(5); ^ required: reference found: int 1 error Do I miss something? Additionally, can you point me to an example for testing value types if something is ready? Thanks. -- Rahman USTA Istanbul JUG https://istanbul-jug.org/ From john.r.rose at oracle.com Sun Apr 22 00:17:18 2018 From: john.r.rose at oracle.com (John Rose) Date: Sat, 21 Apr 2018 17:17:18 -0700 Subject: values vs. statics Message-ID: In L-world (which is working out very well, I think) the same L-type descriptors are used to denote both classic object types and new-fangled value types. When stored in an instance field (or an array element), a value type behaves slightly but importantly from a regular object type, even though the field descriptor (or array element descriptor) is an L-type in both cases. There are three differences: 1. A value type field (or element) is usually "flattened" by the JVM. 2. A value type is preloaded before any of its containing types is preloaded. 3. A value type field (or element) is never null. Flattening means the value can be more efficiently accessed as a part of the enclosing object (or array). It's as vague as that, but important; it is the difference between having a field of type int and a field of type java.lang.Integer. (A value "?works like an int".) So the important property is 1., flattenability. We don't just say "flattening" because of certain second-order details, which may lead the JVM to use a pointer to a buffer, in some cases, instead of a truly inlined and flattened representation for a variable of a value type. These cases include: A. Jumbo value types are buffered, not inlined, for a platform-dependent definition of "jumbo". B. Volatile variables of value type might be buffered as a way to control races, if no alternative (such as TSX or STM) is applicable. C. Values in containers which are inconvenient to flatten may be buffered, so that the container does not need to deal with the complexities of inlined values. D. A classfile may have been compiled against an old version of an L-type when it was an object, but now it has migrated to be a value. In that case, fields in the old class requires nullability, breaking condition #3 above. The JVM can detect this on a case-to-case basis. This means a type may be flattenable, but in these corner cases, a variable of that type might *not* be flattened. Still, even if an internal buffer pointer is used to represent a value, conditions #2 and #3 apply to value types. If a class makes a field which is a value type, that value type must be loaded first. (If an array is created, its element type is already loaded, so condition #2 is already true, even for object types.) Also, the JVM must never, ever allow a null value to appear, even if a value is buffered. There is a user-visible exception to non-nullability of instance variables of value type, and that is when the instance variable is defined by a deficient container, which we are choosing to support compatibly; that is case D above. In the other cases (A,B,C), nulls are not allowed. This non-nullability has three sub-cases: a. A getfield on the variable is never observed to produce a null. b. A putfield of a null, if the verifier allows it, is rejected by the putfield instruction itself (with NPE). c. The default initial value of such a field is not null, but rather the default of the value type. Condition c. is the reason for condition #3 above. Before the first instance of a class is created, each value type used by any of that class's fields must be loaded, and its layout (including size, alignment, and oop content) must be determined. The default value of this value type must also be determined, so that freshly created instances of the class can be pre-packed with that default value. Note that if, for a particular field of value type, one of the cases A-D applies, then the default value must be "plugged in" to the instance in the form of an invisible buffer pointer, not copied bitwise. This implies that when a value type is preloaded, an important early activity is to register a pointer to (a bitwise image of) the default value of that value type, so that all clients of it can use the pointer, either as the base of a copy operation or as-is, in one of the cases A-D. So, what about static fields of value type? Condition #1 above does not really apply to static fields, and since condition #1 started this whole mess, one might think that none of the remaining considerations apply to static fields of value types. (I'm leaving aside the argument of whether, in some cases, there might be a large enough number of static variables of value type that, in bulk, cache-coherence effects would allow flattening to make a discernable difference. I'm assuming that there are few enough statics in the world that they all fit in cache comfortably. This assumption is true today but might change after template classes are introduced, if a template species could have a bunch of statics?in that case, a template species would have many of the same scaling properties of instances, if the template were specialized many times.) Even if we rule out #1 for statics, I claim that conditions #2 and #3 should be applied to static fields just as much as instance fields. In particular, if a field (static or instance) is marked ACC_FLATTENABLE, the type must be preloaded before the containing class is "prepared". The default initial value of the static must be the default value of the preloaded class (as determined during the "preparation" phase of *that* class). The value of the static must never assume the value "null", whether as a default initial value, or in response to a "putstatic" instruction. Statics defined in case D would be exempt from these restrictions, just like non-statics. In all other cases, a static variable of value type would never be null. It appears that statics of value type might qualify for the exception in case C. After all, who wants to do the extra work of wedging inlined values into the static holder of a class that defines statics of value type? (For the record, the current static holder, in HotSpot, is the java.lang.Class mirror of the class holding the static. I think this is a slick move. If we were to inline static value fields into the java.lang.Class, we'd have to add more "stuff" to the already magic logic that lays out each java.lang.Class in a customized way.) So, using case C above, I'm happy to imagine that value type static fields are implemented as hidden L-type buffer pointers stored, alongside the other statics, inside their class mirror. I think I want to re-examine this eventually when we do templates. What's left to implement conditions #1-#3? Well, #1 is not applicable, so that's easy. #2 is simple also: We simply preload a value type class if we see the ACC_FLATTENABLE bit, and don't inquire (at that moment) whether the ACC_STATIC bit is set at the same time. Condition #3 breaks into the sub-conditions a, b, c, which adapt to statics as follows: a. A getstatic on the variable is never observed to produce a null. b. A putstatic of a null, if the verifier allows it, is rejected by the putfield instruction itself (with NPE). c. The default initial value of such a field is not null, but rather the default of the value type. How do we implement this? Well, c. is handled by ensuring that the Class mirror is populated with a pointer to the default value pointer created when the value type was preloaded. And b. is handled by asking the link resolver to mark static fields which are of value type, so that the interpreter will not accidentally store a null there. For instance fields we do this by consulting the ACC_FLATTENABLE bit, and throwing NPE if the putfield detects a null. We can do the same for putstatic (at the cost of some copied assembly code). Sub-condition b. falls out naturally from a. and c. Note that down-rev. classes (which don't know about value types, in case D) can't get away with a putfield or putstatic of null, since it is the container, not the client, that gets to see when a field is not nullable. The down-rev. classes of course can define fields (static or not) which are of value types, and they have a "special" ability to store nulls in those fields too. This special ability goes away when their code is recompiled. (I'm not arguing at this point for *any* other support for nullability control, other than recompiling in the presence of value types. I don't want emotional types like String! and String?, at least not any time soon. We have enough to do as it is. Case D is not there because we want expressiveness for down-rev. classes, but because we must have compatibility.) Why am I worried about statics? Why not just let them be nullable whenever they are L-types, even if they are value types? Because if we allow statics to be nullable, they will be a significant source of null-pollution, even in new code. It's not enough for javac to insert "vdefault" and "putstatic" into the "" of all classes with value statics. The "putstatic" is too late in too many edge cases. The nulls will be observed in the wild, when programmers write code that reads statics inside of explicit "" code. The default value of the static must be plugged in before "" runs, at preparation time. More vaguely but still significantly, my personally "symmetry design heuristic" barfs on a language design which would say that values are not nullable, except when defined as static variables, or on a JVM design which supports this language and then requires javac to emit fix-up code ("vdefault;putstatic") to implement the correct semantics. This heuristic also makes me queasy when I think about refactoring values between static variable containers and instance variable containers. I want to refactor freely, and not worry about nulls popping up like little goblins. So I think what I'm asking for, in terms of JVM coding, is an extra null barrier on "putstatic", and some review of the sequence of preparation time vs. class preloading, as it interacts with the logic for ACC_FLATTENABLE. I am *not* asking for ACC_FLATTENED (the internal flag, I mean) to be set on any static field. Just ACC_FLATTENABLE, with the corresponding null checks. If the preparation-type patching of the default value into the java.lang.Class mirror is inconvenient, then the alternate technique of putting a null barrier on "getstatic" is acceptable. In fact, that points to a refactoring of the interpreter assembly code to cover the ACC_F* logic for all four cases of put/get times field/static. Comments? ? John From john.r.rose at oracle.com Sun Apr 22 03:32:08 2018 From: john.r.rose at oracle.com (John Rose) Date: Sat, 21 Apr 2018 20:32:08 -0700 Subject: values vs. statics In-Reply-To: References: Message-ID: <928549B7-F9DC-4A3A-B429-9ED77EB721F6@oracle.com> On Apr 21, 2018, at 5:17 PM, John Rose wrote: > > a value type > behaves slightly but importantly from a regular object type oops, s/ from / differently from / or just s/ slightly but importantly / differently / From david.holmes at oracle.com Sun Apr 22 23:48:28 2018 From: david.holmes at oracle.com (david.holmes at oracle.com) Date: Sun, 22 Apr 2018 23:48:28 +0000 Subject: hg: valhalla/valhalla: 8187645: [Nestmates] Update Pack200 and tests, to recognize and process new Nestmate attributes Message-ID: <201804222348.w3MNmTV0007180@aojmv0008.oracle.com> Changeset: e1db0c442ee7 Author: ksrini Date: 2018-04-22 19:47 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/e1db0c442ee7 8187645: [Nestmates] Update Pack200 and tests, to recognize and process new Nestmate attributes Reviewed-by: dholmes ! src/java.base/share/classes/com/sun/java/util/jar/pack/intrinsic.properties ! test/jdk/ProblemList.txt ! test/jdk/tools/pack200/BandIntegrity.java ! test/jdk/tools/pack200/pack200-verifier/make/build.xml ! test/jdk/tools/pack200/pack200-verifier/src/xmlkit/ClassReader.java From david.holmes at oracle.com Sun Apr 22 23:49:14 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 23 Apr 2018 09:49:14 +1000 Subject: RFR: 8187645: [Nestmates] Update Pack200 and tests, to recognize and process new Nestmate attributes In-Reply-To: <5ADA50EA.6000600@oracle.com> References: <5ADA50EA.6000600@oracle.com> Message-ID: Thanks Kumar! Reviewed and sponsored. David On 21/04/2018 6:43 AM, Kumar Srinivasan wrote: > Hi David, > > Could you please sponsor this patch and push to? valhalla's nestmates > branch. > > http://cr.openjdk.java.net/~ksrini/8187645/ > > Thanks > Kumar > PS: I am not a member on this list, so please email me directly. From srikanth.adayapalam at oracle.com Mon Apr 23 06:13:00 2018 From: srikanth.adayapalam at oracle.com (srikanth.adayapalam at oracle.com) Date: Mon, 23 Apr 2018 06:13:00 +0000 Subject: hg: valhalla/valhalla: [lworld] Emit a warning on potential null pollution into value based instances Message-ID: <201804230613.w3N6D1N7015459@aojmv0008.oracle.com> Changeset: 9cefc46cf42a Author: sadayapalam Date: 2018-04-23 11:42 +0530 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/9cefc46cf42a [lworld] Emit a warning on potential null pollution into value based instances ! src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java ! src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties ! test/langtools/tools/javac/diags/examples.not-yet.txt + test/langtools/tools/javac/valhalla/lworld-values/NullPollutionTest.java + test/langtools/tools/javac/valhalla/lworld-values/NullPollutionTest.out From david.holmes at oracle.com Tue Apr 24 04:25:03 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 24 Apr 2018 14:25:03 +1000 Subject: [Nestmates] RFR: 8202159: [Nestmates] JVM TI version update was incomplete Message-ID: webrev: http://cr.openjdk.java.net/~dholmes/8202159/webrev/ bug: https://bugs.openjdk.java.net/browse/JDK-8202159 Missed two places where the JVM TI version update wasn't reflected. Testing: runtime/appcds/sharedStrings/FlagsCombo (which exposed the problem when using JFR) serviceability/jvmti Thanks, David From david.holmes at oracle.com Tue Apr 24 05:03:52 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 24 Apr 2018 15:03:52 +1000 Subject: [Nestmates] RFR: 8202159: [Nestmates] JVM TI version update was incomplete In-Reply-To: References: Message-ID: <7d7700bc-5f08-c6b1-9040-92c84cf54ac7@oracle.com> Thanks Serguei! On 24/04/2018 2:36 PM, serguei.spitsyn at oracle.com wrote: > Hi David, > > It looks good. > > Thanks, > Serguei > > > On 4/23/18 21:25, David Holmes wrote: >> webrev: http://cr.openjdk.java.net/~dholmes/8202159/webrev/ >> bug: https://bugs.openjdk.java.net/browse/JDK-8202159 >> >> Missed two places where the JVM TI version update wasn't reflected. >> >> Testing: >> ? runtime/appcds/sharedStrings/FlagsCombo (which exposed the problem >> when using JFR) >> ? serviceability/jvmti >> >> Thanks, >> David > From david.holmes at oracle.com Tue Apr 24 05:04:57 2018 From: david.holmes at oracle.com (david.holmes at oracle.com) Date: Tue, 24 Apr 2018 05:04:57 +0000 Subject: hg: valhalla/valhalla: 8202159: [Nestmates] JVM TI version update was incomplete Message-ID: <201804240504.w3O54wtV001413@aojmv0008.oracle.com> Changeset: e02ca1ac5450 Author: dholmes Date: 2018-04-24 01:04 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/e02ca1ac5450 8202159: [Nestmates] JVM TI version update was incomplete Reviewed-by: sspitsyn ! src/hotspot/share/prims/jvmtiExport.cpp ! src/hotspot/share/prims/jvmtiH.xsl From david.holmes at oracle.com Tue Apr 24 10:23:30 2018 From: david.holmes at oracle.com (david.holmes at oracle.com) Date: Tue, 24 Apr 2018 10:23:30 +0000 Subject: hg: valhalla/valhalla: Fix compiler warning on Windows regarding operator precedence - added parantheses Message-ID: <201804241023.w3OANUWl012981@aojmv0008.oracle.com> Changeset: efbe6da6cc1c Author: dholmes Date: 2018-04-24 06:23 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/efbe6da6cc1c Fix compiler warning on Windows regarding operator precedence - added parantheses ! src/hotspot/share/prims/jvmtiRedefineClasses.cpp From rwestrel at redhat.com Wed Apr 25 12:24:18 2018 From: rwestrel at redhat.com (rwestrel at redhat.com) Date: Wed, 25 Apr 2018 12:24:18 +0000 Subject: hg: valhalla/valhalla: Lworld C2 fixes Message-ID: <201804251224.w3PCOIuD025247@aojmv0008.oracle.com> Changeset: d50869a64b06 Author: roland Date: 2018-04-25 14:19 +0200 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/d50869a64b06 Lworld C2 fixes ! src/hotspot/share/opto/callGenerator.cpp ! src/hotspot/share/opto/callnode.cpp ! src/hotspot/share/opto/doCall.cpp ! src/hotspot/share/opto/graphKit.cpp ! src/hotspot/share/opto/graphKit.hpp ! src/hotspot/share/opto/parse1.cpp ! src/hotspot/share/opto/parse3.cpp ! src/hotspot/share/opto/type.cpp ! src/hotspot/share/opto/valuetypenode.cpp ! src/hotspot/share/opto/valuetypenode.hpp ! test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java From rwestrel at redhat.com Wed Apr 25 12:26:46 2018 From: rwestrel at redhat.com (Roland Westrelin) Date: Wed, 25 Apr 2018 14:26:46 +0200 Subject: MethodHandleBuilder bug? In-Reply-To: References: Message-ID: > Try with the patch below. That seems to work ok. Do you intend to push it? Roland. From rwestrel at redhat.com Wed Apr 25 12:36:29 2018 From: rwestrel at redhat.com (Roland Westrelin) Date: Wed, 25 Apr 2018 14:36:29 +0200 Subject: hg: valhalla/valhalla: Lworld C2 fixes In-Reply-To: <201804251224.w3PCOIuD025247@aojmv0008.oracle.com> References: <201804251224.w3PCOIuD025247@aojmv0008.oracle.com> Message-ID: I fixed some issues with Lworld support: - A merge of values and non values or of values of different types requires a buffered value. The existing code didn't handle all case (it works if a non value is seen first but not if a value is seen first). I fixed it by relying on types reported by type flow analysis. - Still at a merge point: allocating to buffer a value can cause an exception but I found handling exceptions there would sometimes break so, instead, a failure to allocate now causes a deoptimization - Still at a merge point: when a buffered value is created, the code now uses a ValueTypePtrNode so useless allocations have a better change of being optimized out - I wrote some test cases that attempt to store a null constant in a flattenable value type field. That requires extra checks at a store and at a merge point to deoptimize if a value is null. - I also added a check for null at the return of a call (that returns a value). Deoptimization needs to resume execution at the bytecode after the call so I had to move the logic that builds a new ValueTypeNode around. Roland. From tobias.hartmann at oracle.com Wed Apr 25 12:38:53 2018 From: tobias.hartmann at oracle.com (Tobias Hartmann) Date: Wed, 25 Apr 2018 14:38:53 +0200 Subject: hg: valhalla/valhalla: Lworld C2 fixes In-Reply-To: References: <201804251224.w3PCOIuD025247@aojmv0008.oracle.com> Message-ID: <46e9ce1b-88c7-80bd-a6b7-4c5035b1540d@oracle.com> Looks great, thanks Roland! Best regards, Tobias On 25.04.2018 14:36, Roland Westrelin wrote: > > I fixed some issues with Lworld support: > > - A merge of values and non values or of values of different types > requires a buffered value. The existing code didn't handle all case > (it works if a non value is seen first but not if a value is seen > first). I fixed it by relying on types reported by type flow analysis. > > - Still at a merge point: allocating to buffer a value can cause an > exception but I found handling exceptions there would sometimes break > so, instead, a failure to allocate now causes a deoptimization > > - Still at a merge point: when a buffered value is created, the code now > uses a ValueTypePtrNode so useless allocations have a better change of > being optimized out > > - I wrote some test cases that attempt to store a null constant in a > flattenable value type field. That requires extra checks at a store > and at a merge point to deoptimize if a value is null. > > - I also added a check for null at the return of a call (that returns a > value). Deoptimization needs to resume execution at the bytecode after > the call so I had to move the logic that builds a new ValueTypeNode > around. > > Roland. > From paul.sandoz at oracle.com Wed Apr 25 14:38:35 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Wed, 25 Apr 2018 07:38:35 -0700 Subject: MethodHandleBuilder bug? In-Reply-To: References: Message-ID: <4D67BADA-75DB-455F-98A8-1B239D0AC9A4@oracle.com> > On Apr 25, 2018, at 5:26 AM, Roland Westrelin wrote: > > >> Try with the patch below. > > That seems to work ok. Do you intend to push it? > Thanks, yes, i'll do it today. Paul. From paul.sandoz at oracle.com Wed Apr 25 21:16:50 2018 From: paul.sandoz at oracle.com (paul.sandoz at oracle.com) Date: Wed, 25 Apr 2018 21:16:50 +0000 Subject: hg: valhalla/valhalla: Fix stack map creation in byte code API Message-ID: <201804252116.w3PLGpRO016055@aojmv0008.oracle.com> Changeset: e65277a7109a Author: psandoz Date: 2018-04-25 14:15 -0700 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/e65277a7109a Fix stack map creation in byte code API ! src/java.base/share/classes/jdk/experimental/bytecode/BasicTypeHelper.java ! src/java.base/share/classes/jdk/experimental/bytecode/TypedCodeBuilder.java From david.simms at oracle.com Thu Apr 26 15:20:46 2018 From: david.simms at oracle.com (David Simms) Date: Thu, 26 Apr 2018 17:20:46 +0200 Subject: [lworld] RFR: object methods in VM for lworld value type Message-ID: Greetings, Here is a patch that for the most part ensures Object methods implemented by the JVM do not crash (as some do today): http://cr.openjdk.java.net/~dsimms/valhalla/object_methods/webrev0/ Summary of changes, interpreter only (-Xint): * "Object.getClass()": sanity test * "Object.hashCode()" / "System.identityHashCode()": simply return 0 o should be revisited for "System.identityHashCode()", once we have BSM hashCode generation in place * "Object.clone()": disallow "Cloneable" value types, throws ClassFormatError o implicit cloning via "pass by value" does not allow user code (as clone does), so no clone * "Object.wait()", "notify()" and monitorenter byte-code: throw IllegalMonitorStateException o missing test for monitorexit (whoops) This change is primarily to enable further prototyping with -Xint, giving JIT implementation further time to adjust to lworld, and ignoring JDK methods whom may or may not provide alternative implementations for lworld "objectification" of value types. Cheers /David Simms From tobias.hartmann at oracle.com Thu Apr 26 16:04:49 2018 From: tobias.hartmann at oracle.com (tobias.hartmann at oracle.com) Date: Thu, 26 Apr 2018 16:04:49 +0000 Subject: hg: valhalla/valhalla: [lworld] Compiler tests for value types that implement interfaces Message-ID: <201804261604.w3QG4oFl029500@aojmv0008.oracle.com> Changeset: 048139cd8f32 Author: thartmann Date: 2018-04-26 18:04 +0200 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/048139cd8f32 [lworld] Compiler tests for value types that implement interfaces ! src/hotspot/share/opto/parse1.cpp ! src/hotspot/share/opto/parse2.cpp + test/hotspot/jtreg/compiler/valhalla/valuetypes/MyInterface.java ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue1.java ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue2.java ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue3.java ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue4.java ! test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java From tobias.hartmann at oracle.com Thu Apr 26 16:07:00 2018 From: tobias.hartmann at oracle.com (Tobias Hartmann) Date: Thu, 26 Apr 2018 18:07:00 +0200 Subject: hg: valhalla/valhalla: [lworld] Compiler tests for value types that implement interfaces In-Reply-To: <201804261604.w3QG4oFl029500@aojmv0008.oracle.com> References: <201804261604.w3QG4oFl029500@aojmv0008.oracle.com> Message-ID: <367be039-de54-0666-6db5-81ab4ab18907@oracle.com> Summary of changes: - Added compiler tests for value types implementing interfaces - Re-enabled test19 after MethodHandleBuilder bug was fixed - Removed obsolete TODOs - Fixed assert in parse1.cpp Thanks, Tobias On 26.04.2018 18:04, tobias.hartmann at oracle.com wrote: > Changeset: 048139cd8f32 > Author: thartmann > Date: 2018-04-26 18:04 +0200 > URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/048139cd8f32 > > [lworld] Compiler tests for value types that implement interfaces > > ! src/hotspot/share/opto/parse1.cpp > ! src/hotspot/share/opto/parse2.cpp > + test/hotspot/jtreg/compiler/valhalla/valuetypes/MyInterface.java > ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue1.java > ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue2.java > ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue3.java > ! test/hotspot/jtreg/compiler/valhalla/valuetypes/MyValue4.java > ! test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java > From karen.kinnear at oracle.com Thu Apr 26 19:36:08 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 26 Apr 2018 15:36:08 -0400 Subject: CFV:New Valhalla Committer: Sergey Kuksenko Message-ID: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK valhalla [0] Committer [1]. Sergey has been contributing performance improvements to the JDK since 2011. He created benchmarks for the Valhalla Minimal Value Types (MVT) project and has converted those for the Valhalla LWorld Value Types project as well as creating new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes and performance improvements [3]. Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes must be cast in the open by replying to this mailing list. For Lazy Consensus voting instructions, see [2] [0] http://openjdk.java.net/projects/valhalla/ [1] http://openjdk.java.net/census [2] http://openjdk.java.net/projects/#committer-vote [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 From brian.goetz at oracle.com Thu Apr 26 19:45:02 2018 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 26 Apr 2018 21:45:02 +0200 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: <5EB3AA2A-D274-4B1E-9D7B-6C944C66AB9F@oracle.com> Vote: Da! Sent from my MacBook Wheel > On Apr 26, 2018, at 9:36 PM, Karen Kinnear wrote: > > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. > > Sergey has been contributing performance improvements to the JDK since 2011. > He created benchmarks for the Valhalla Minimal Value Types (MVT) project and > has converted those for the Valhalla LWorld Value Types project as well as creating > new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes > and performance improvements [3]. > > Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). > > Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes > must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [2] > > [0] http://openjdk.java.net/projects/valhalla/ > [1] http://openjdk.java.net/census > [2] http://openjdk.java.net/projects/#committer-vote > [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 From frederic.parain at oracle.com Thu Apr 26 19:46:07 2018 From: frederic.parain at oracle.com (Frederic Parain) Date: Thu, 26 Apr 2018 15:46:07 -0400 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: Vote: Yes Fred > On Apr 26, 2018, at 15:36, Karen Kinnear wrote: > > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. > > Sergey has been contributing performance improvements to the JDK since 2011. > He created benchmarks for the Valhalla Minimal Value Types (MVT) project and > has converted those for the Valhalla LWorld Value Types project as well as creating > new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes > and performance improvements [3]. > > Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). > > Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes > must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [2] > > [0] http://openjdk.java.net/projects/valhalla/ > [1] http://openjdk.java.net/census > [2] http://openjdk.java.net/projects/#committer-vote > [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 From karen.kinnear at oracle.com Thu Apr 26 19:46:33 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Thu, 26 Apr 2018 15:46:33 -0400 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: Vote: yes thanks, Karen > On Apr 26, 2018, at 3:36 PM, Karen Kinnear wrote: > > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. > > Sergey has been contributing performance improvements to the JDK since 2011. > He created benchmarks for the Valhalla Minimal Value Types (MVT) project and > has converted those for the Valhalla LWorld Value Types project as well as creating > new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes > and performance improvements [3]. > > Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). > > Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes > must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [2] > > [0] http://openjdk.java.net/projects/valhalla/ > [1] http://openjdk.java.net/census > [2] http://openjdk.java.net/projects/#committer-vote > [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 From vladimir.x.ivanov at oracle.com Thu Apr 26 21:10:05 2018 From: vladimir.x.ivanov at oracle.com (Vladimir Ivanov) Date: Thu, 26 Apr 2018 14:10:05 -0700 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: <22cbd252-8e1f-227c-1c44-e5d3356f120b@oracle.com> Vote: yes Best regards, Vladimir Ivanov On 4/26/18 12:36, Karen Kinnear wrote: > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. From david.holmes at oracle.com Thu Apr 26 22:26:00 2018 From: david.holmes at oracle.com (David Holmes) Date: Fri, 27 Apr 2018 08:26:00 +1000 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: Vote: yes David On 27/04/2018 5:36 AM, Karen Kinnear wrote: > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. > > Sergey has been contributing performance improvements to the JDK since 2011. > He created benchmarks for the Valhalla Minimal Value Types (MVT) project and > has converted those for the Valhalla LWorld Value Types project as well as creating > new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes > and performance improvements [3]. > > Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). > > Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes > must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [2] > > [0] http://openjdk.java.net/projects/valhalla/ > [1] http://openjdk.java.net/census > [2] http://openjdk.java.net/projects/#committer-vote > [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 > From paul.sandoz at oracle.com Thu Apr 26 22:39:37 2018 From: paul.sandoz at oracle.com (Paul Sandoz) Date: Thu, 26 Apr 2018 15:39:37 -0700 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: <0677FD4C-DF57-4604-9E26-627657AF8E0E@oracle.com> Vote: yes Paul. From tobias.hartmann at oracle.com Fri Apr 27 05:57:02 2018 From: tobias.hartmann at oracle.com (Tobias Hartmann) Date: Fri, 27 Apr 2018 07:57:02 +0200 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: Vote: yes Best regards, Tobias On 26.04.2018 21:36, Karen Kinnear wrote: > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. > > Sergey has been contributing performance improvements to the JDK since 2011. > He created benchmarks for the Valhalla Minimal Value Types (MVT) project and > has converted those for the Valhalla LWorld Value Types project as well as creating > new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes > and performance improvements [3]. > > Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). > > Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes > must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [2] > > [0] http://openjdk.java.net/projects/valhalla/ > [1] http://openjdk.java.net/census > [2] http://openjdk.java.net/projects/#committer-vote > [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 > From david.simms at oracle.com Fri Apr 27 05:58:58 2018 From: david.simms at oracle.com (David Simms) Date: Fri, 27 Apr 2018 07:58:58 +0200 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: <7536c7c4-ded7-3d0d-6198-046e0fa286d3@oracle.com> Vote: yes On 26/04/18 21:36, Karen Kinnear wrote: > I hereby nominate Sergey Kuksenko (openjdk username: skuksenko) to be an OpenJDK > valhalla [0] Committer [1]. > > Sergey has been contributing performance improvements to the JDK since 2011. > He created benchmarks for the Valhalla Minimal Value Types (MVT) project and > has converted those for the Valhalla LWorld Value Types project as well as creating > new LWorld specific benchmarks. He has created numerous benchmarks and contributed a range of fixes > and performance improvements [3]. > > Votes are due Thursday May 10th at 16:00:00 UTC (two week voting period). > > Only current Valhalla Committers [1] are eligible to vote on this nomination. Votes > must be cast in the open by replying to this mailing list. > > For Lazy Consensus voting instructions, see [2] > > [0] http://openjdk.java.net/projects/valhalla/ > [1] http://openjdk.java.net/census > [2] http://openjdk.java.net/projects/#committer-vote > [3] http://hg.openjdk.java.net/valhalla/valhalla/log?rev=%28author%28%22skuksenko%22%29+or+desc%28%22Contributed-by%3A+sergey.kuksenko%40oracle.com%22%29%29 From rwestrel at redhat.com Fri Apr 27 13:32:56 2018 From: rwestrel at redhat.com (Roland Westrelin) Date: Fri, 27 Apr 2018 15:32:56 +0200 Subject: CFV:New Valhalla Committer: Sergey Kuksenko In-Reply-To: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> References: <7D55FEA4-32BC-437C-BC6D-558F42947553@oracle.com> Message-ID: Vote: yes Roland. From karen.kinnear at oracle.com Fri Apr 27 21:55:22 2018 From: karen.kinnear at oracle.com (Karen Kinnear) Date: Fri, 27 Apr 2018 17:55:22 -0400 Subject: [lworld] RFR: object methods in VM for lworld value type In-Reply-To: References: Message-ID: Mr Simms, Yay! Thank you so much for doing the vm changes for Object methods for -Xint. Question on functionality: 1) Cloneable - this is different than we had originally discussed - so I should bring this to an EG discussion - hopefully for when you are there Hard to catch all our sync fast paths - many thanks. Looks like the fast way to do this - hopefully below radar. I don?t know all the JIT paths, but sounds like that is a follow-on for our JIT folks. 1.templateTable_x86.cpp What happens if you skip verification and generate bytecodes with a monitor exit but no monitorenter for a value type? Does this already fall through to IMSE? 2. synchronizer.cpp Do you need checks for: jni_enter, jni_exit, reenter, complete_exit otherwise they seem to go into revoke_and_rebias and then inflate, never checking for exceptions 3. jvm.cpp So JVM_Clone doesn?t need to throw CloneNotSupported because we ensure that this is not a cloneable in classfileparser, and j.l.Object catches? Is it worth adding an assertion here? thanks, Karen > On Apr 26, 2018, at 11:20 AM, David Simms wrote: > > Greetings, > > Here is a patch that for the most part ensures Object methods implemented by the JVM do not crash (as some do today): > > http://cr.openjdk.java.net/~dsimms/valhalla/object_methods/webrev0/ > > Summary of changes, interpreter only (-Xint): > > * "Object.getClass()": sanity test > * "Object.hashCode()" / "System.identityHashCode()": simply return 0 > o should be revisited for "System.identityHashCode()", once we > have BSM hashCode generation in place > * "Object.clone()": disallow "Cloneable" value types, throws > ClassFormatError > o implicit cloning via "pass by value" does not allow user code > (as clone does), so no clone > * "Object.wait()", "notify()" and monitorenter byte-code: throw > IllegalMonitorStateException > o missing test for monitorexit (whoops) > > This change is primarily to enable further prototyping with -Xint, giving JIT implementation further time to adjust to lworld, and ignoring JDK methods whom may or may not provide alternative implementations for lworld "objectification" of value types. > > Cheers > > /David Simms > > From david.holmes at oracle.com Mon Apr 30 04:55:14 2018 From: david.holmes at oracle.com (David Holmes) Date: Mon, 30 Apr 2018 14:55:14 +1000 Subject: [Nestmates] RFR (S) 8202401: [Nestmates] jshell tests fail due to class redefinition limitation on nested types Message-ID: Bug: https://bugs.openjdk.java.net/browse/JDK-8202401 webrev: http://cr.openjdk.java.net/~dholmes/8202401/webrev/ As jshell tries to use class redefinition when possible, it will hit errors if trying to redefine classes in a way that would modify the NestHost or NestMembers attributes. It then falls back to an alternative technique. For the tests this results in a "signature-change" that is unexpected. The simple fix (courtesy of Jan) is to change the "expects signature parameter" from false to true for those test cases. Thanks, David From jan.lahoda at oracle.com Mon Apr 30 14:18:29 2018 From: jan.lahoda at oracle.com (Jan Lahoda) Date: Mon, 30 Apr 2018 16:18:29 +0200 Subject: [Nestmates] RFR (S) 8202401: [Nestmates] jshell tests fail due to class redefinition limitation on nested types In-Reply-To: References: Message-ID: <5AE725B5.90701@oracle.com> To me, looks OK. Jan On 30.4.2018 06:55, David Holmes wrote: > Bug: https://bugs.openjdk.java.net/browse/JDK-8202401 > webrev: http://cr.openjdk.java.net/~dholmes/8202401/webrev/ > > As jshell tries to use class redefinition when possible, it will hit > errors if trying to redefine classes in a way that would modify the > NestHost or NestMembers attributes. It then falls back to an alternative > technique. For the tests this results in a "signature-change" that is > unexpected. > > The simple fix (courtesy of Jan) is to change the "expects signature > parameter" from false to true for those test cases. > > Thanks, > David From serguei.spitsyn at oracle.com Mon Apr 30 19:23:31 2018 From: serguei.spitsyn at oracle.com (serguei.spitsyn at oracle.com) Date: Mon, 30 Apr 2018 12:23:31 -0700 Subject: [Nestmates] RFR (S) 8202401: [Nestmates] jshell tests fail due to class redefinition limitation on nested types In-Reply-To: <5AE725B5.90701@oracle.com> References: <5AE725B5.90701@oracle.com> Message-ID: <8bf6c7da-66b3-4ea8-bc5e-30a349c6a451@oracle.com> +1 Thanks, Serguei On 4/30/18 07:18, Jan Lahoda wrote: > To me, looks OK. > > Jan > > On 30.4.2018 06:55, David Holmes wrote: >> Bug: https://bugs.openjdk.java.net/browse/JDK-8202401 >> webrev: http://cr.openjdk.java.net/~dholmes/8202401/webrev/ >> >> As jshell tries to use class redefinition when possible, it will hit >> errors if trying to redefine classes in a way that would modify the >> NestHost or NestMembers attributes. It then falls back to an alternative >> technique. For the tests this results in a "signature-change" that is >> unexpected. >> >> The simple fix (courtesy of Jan) is to change the "expects signature >> parameter" from false to true for those test cases. >> >> Thanks, >> David From david.holmes at oracle.com Mon Apr 30 21:03:51 2018 From: david.holmes at oracle.com (David Holmes) Date: Tue, 1 May 2018 07:03:51 +1000 Subject: [Nestmates] RFR (S) 8202401: [Nestmates] jshell tests fail due to class redefinition limitation on nested types In-Reply-To: <8bf6c7da-66b3-4ea8-bc5e-30a349c6a451@oracle.com> References: <5AE725B5.90701@oracle.com> <8bf6c7da-66b3-4ea8-bc5e-30a349c6a451@oracle.com> Message-ID: <5ae48e6d-2b9d-0691-b34a-72a148425511@oracle.com> Thanks Jan and Serguei. David On 1/05/2018 5:23 AM, serguei.spitsyn at oracle.com wrote: > +1 > > Thanks, > Serguei > > > On 4/30/18 07:18, Jan Lahoda wrote: >> To me, looks OK. >> >> Jan >> >> On 30.4.2018 06:55, David Holmes wrote: >>> Bug: https://bugs.openjdk.java.net/browse/JDK-8202401 >>> webrev: http://cr.openjdk.java.net/~dholmes/8202401/webrev/ >>> >>> As jshell tries to use class redefinition when possible, it will hit >>> errors if trying to redefine classes in a way that would modify the >>> NestHost or NestMembers attributes. It then falls back to an alternative >>> technique. For the tests this results in a "signature-change" that is >>> unexpected. >>> >>> The simple fix (courtesy of Jan) is to change the "expects signature >>> parameter" from false to true for those test cases. >>> >>> Thanks, >>> David > From david.holmes at oracle.com Mon Apr 30 21:05:25 2018 From: david.holmes at oracle.com (david.holmes at oracle.com) Date: Mon, 30 Apr 2018 21:05:25 +0000 Subject: hg: valhalla/valhalla: 8202401: [Nestmates] jshell tests fail due to class redefinition limitation on nested types Message-ID: <201804302105.w3UL5QW0024893@aojmv0008.oracle.com> Changeset: d378e593a885 Author: dholmes Date: 2018-04-30 17:05 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/rev/d378e593a885 8202401: [Nestmates] jshell tests fail due to class redefinition limitation on nested types Reviewed-by: sspitsyn Contributed-by: Jan Lahoda ! test/langtools/jdk/jshell/ClassesTest.java ! test/langtools/jdk/jshell/ForwardReferenceTest.java ! test/langtools/jdk/jshell/GetResourceTest.java From serguei.spitsyn at oracle.com Tue Apr 24 04:36:33 2018 From: serguei.spitsyn at oracle.com (serguei.spitsyn at oracle.com) Date: Tue, 24 Apr 2018 04:36:33 -0000 Subject: [Nestmates] RFR: 8202159: [Nestmates] JVM TI version update was incomplete In-Reply-To: References: Message-ID: Hi David, It looks good. Thanks, Serguei On 4/23/18 21:25, David Holmes wrote: > webrev: http://cr.openjdk.java.net/~dholmes/8202159/webrev/ > bug: https://bugs.openjdk.java.net/browse/JDK-8202159 > > Missed two places where the JVM TI version update wasn't reflected. > > Testing: > ? runtime/appcds/sharedStrings/FlagsCombo (which exposed the problem > when using JFR) > ? serviceability/jvmti > > Thanks, > David