From brian.goetz at oracle.com Thu Jul 10 21:27:09 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 10 Jul 2014 17:27:09 -0400 Subject: Welcome to Valhalla! Message-ID: <53BF052D.3060200@oracle.com> Welcome to Project Valhalla, our incubation grounds for advanced language-VM co-development projects such as Value Types (http://cr.openjdk.java.net/~jrose/values/values-0.html) and Generic Specialization (https://bugs.openjdk.java.net/browse/JDK-8046267). The code repositories should open shortly. To start with, I've published a more details writeup of the design ideas for Generic Specialization here: http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html This remains quite rough, but should give an idea of the scope of what we're considering. We'll be starting to prototype these concepts soon. As the prototypes emerge, please bear in mind that the first several rounds will likely not look anything like the final result. So, don't assume that just because the prototype operates by name mangling, or classfile mangling, or requires the operator to do the Chicken Dance, that this is the ultimate plan -- its just an expedient way to get to the point where we can experiment with something tangible. And, for those of you with a million questions, please bear in mind that we do not necessarily have a million answers. (I, for one, won't have any answers for a while, since I'm going on vacation.) I'll just answer one question that's probably on everyone's mind: no, none of this is stuff we're targeting for Java 9. This is the early-stage explorations of stuff that hopefully will make it into a later release. From brian.goetz at oracle.com Fri Jul 11 16:58:32 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Fri, 11 Jul 2014 12:58:32 -0400 Subject: Classfile representation of specializable classes Message-ID: <53C017B8.2090802@oracle.com> We can think of a specializable class: class Box { T t; public Box(T t) { this.t = t; } public T get() { return t; } } as being both a class (we're used to compiling the above into an erased class for reference instantiations of T) and a template (for specialized instantiations.) We have a range of options for what javac could produce this class: - A template file only, from which both specialized instantiations (Box) and erased instantiations are derived; - An erased class file (like we do today) plus a template file (where the erased version is technically unnecessary, but statically generated as an startup-time optimization) - An erased class file with a template embedded in it, accessible via reflection - An erased class file with attributes identifying how to transform it into a specialized class (this was the example given in the writeup.) Further, the notion of "template" itself ranges over many possible options. (Note that it is not a goal to produce a feature like Expression Trees.) The example in the writeup has many pleasing properties (one artifact, so can't get out of sync; encode minimal additional metadata needed to efficiently transform an erased classfile to a specialized classfile; the "template" can be used as an erased classfile as is, just by ignoring the specialization metadata attributes.) It also has an unpleasant property: the bytecode for an already loaded class is not available easily through its classloader or reflection, meaning that a runtime specialization mechanism would have to jump through hoops (e.g., retransform-classes) to get at the bytecode. Since specializing a class under this scheme requires, as input, the bytecode of the original class, this could become problematic for classes that are themselves generated (i.e., not findable with ClassLoader.getResource("Foo.class")). The factors being traded off here are: - classfile size -- the classfile+template approach would be ~2x the size of the classfile alone; other approaches might be as little as a few percent bigger - startup cost -- deriving the erased classfile from a template costs us startup time, and the "load erased classfile" use case isn't going away any time soon - specialization cost -- some template forms are cheaper than others to generate bytecode from - security -- exposing the bytecode directly may have security consequences For the initial prototype, which will operate by offline classfile transformation, any of these will do, so for that we should do the simplest thing that gets us to a prototype. But we should also continue to evolve the representation story. From daniel.smith at oracle.com Fri Jul 11 17:21:48 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Fri, 11 Jul 2014 11:21:48 -0600 Subject: Classfile representation of specializable classes In-Reply-To: <53C017B8.2090802@oracle.com> References: <53C017B8.2090802@oracle.com> Message-ID: <02120BFE-B4A9-4CD0-9129-931FC836F2EB@oracle.com> On Jul 11, 2014, at 10:58 AM, Brian Goetz wrote: > The example in the writeup has many pleasing properties (one artifact, so can't get out of sync; encode minimal additional metadata needed to efficiently transform an erased classfile to a specialized classfile; the "template" can be used as an erased classfile as is, just by ignoring the specialization metadata attributes.) > > It also has an unpleasant property: the bytecode for an already loaded class is not available easily through its classloader or reflection, meaning that a runtime specialization mechanism would have to jump through hoops (e.g., retransform-classes) to get at the bytecode. Since specializing a class under this scheme requires, as input, the bytecode of the original class, this could become problematic for classes that are themselves generated (i.e., not findable with ClassLoader.getResource("Foo.class")). Maybe what you're after with classdynamic is (primarily) a ClassLoader feature rather than a VM feature? That is, maybe 'defineClass' should be parameterized by a pluggable class-generation system, and that's where the expansion should take place, intercepting the bytes and spitting out the special class. It's not totally clear to me how this would work, but I think it may be the right place for it. (I have consistently felt like what we really want with classdynamic is ClassLoaders 2.0.) ?Dan From david.r.chase at oracle.com Fri Jul 11 18:50:31 2014 From: david.r.chase at oracle.com (David Chase) Date: Fri, 11 Jul 2014 14:50:31 -0400 Subject: Classfile representation of specializable classes In-Reply-To: <02120BFE-B4A9-4CD0-9129-931FC836F2EB@oracle.com> References: <53C017B8.2090802@oracle.com> <02120BFE-B4A9-4CD0-9129-931FC836F2EB@oracle.com> Message-ID: <2A824A99-81E6-423C-A516-345D13B2A719@oracle.com> On 2014-07-11, at 1:21 PM, Dan Smith wrote: > Maybe what you're after with classdynamic is (primarily) a ClassLoader feature rather than a VM feature? That is, maybe 'defineClass' should be parameterized by a pluggable class-generation system, and that's where the expansion should take place, intercepting the bytes and spitting out the special class. It's not totally clear to me how this would work, but I think it may be the right place for it. (I have consistently felt like what we really want with classdynamic is ClassLoaders 2.0.) We played this game in the Fortress implementation, borrowing design from NextGen ( http://www.cs.rice.edu/~javaplt/nextgen/ ) 85% of it is straightforward. One tricky bit was the need to know whether the thing being substituted for a T was a class or an interface (invokeinterface vs invokevirtual), especially when that thing was itself the result of an instantiation. (Reified) generic methods were tricky. We could use invokedynamic to put lipstick on that pig, but under the lipstick is still a pig. I do not recall the precise mechanism that we used, but I think it involved tables indexed by (secure?) hashcodes of instantiation signatures, returning "closure" (Fortress-speak) objects. There's some trickiness involved in getting the type signatures right at both ends, as well as some trickiness in evaluating those secure hashcodes at template-instantiation time (the stamper-outer has a special case for such calculations). David From maurizio.cimadamore at oracle.com Fri Jul 11 21:03:48 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 11 Jul 2014 22:03:48 +0100 Subject: Classfile representation of specializable classes In-Reply-To: <02120BFE-B4A9-4CD0-9129-931FC836F2EB@oracle.com> References: <53C017B8.2090802@oracle.com> <02120BFE-B4A9-4CD0-9129-931FC836F2EB@oracle.com> Message-ID: <53C05134.4070600@oracle.com> On 11/07/14 18:21, Dan Smith wrote: > On Jul 11, 2014, at 10:58 AM, Brian Goetz wrote: > >> The example in the writeup has many pleasing properties (one artifact, so can't get out of sync; encode minimal additional metadata needed to efficiently transform an erased classfile to a specialized classfile; the "template" can be used as an erased classfile as is, just by ignoring the specialization metadata attributes.) >> >> It also has an unpleasant property: the bytecode for an already loaded class is not available easily through its classloader or reflection, meaning that a runtime specialization mechanism would have to jump through hoops (e.g., retransform-classes) to get at the bytecode. Since specializing a class under this scheme requires, as input, the bytecode of the original class, this could become problematic for classes that are themselves generated (i.e., not findable with ClassLoader.getResource("Foo.class")). > Maybe what you're after with classdynamic is (primarily) a ClassLoader feature rather than a VM feature? That is, maybe 'defineClass' should be parameterized by a pluggable class-generation system, and that's where the expansion should take place, intercepting the bytes and spitting out the special class. It's not totally clear to me how this would work, but I think it may be the right place for it. (I have consistently felt like what we really want with classdynamic is ClassLoaders 2.0.) I believe that classloader was also NextGen way to get there: http://dl.acm.org/citation.cfm?id=1141656 Maurizio > > ?Dan From daniel.smith at oracle.com Sat Jul 12 06:00:02 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Sat, 12 Jul 2014 00:00:02 -0600 Subject: Classfile representation of specializable classes In-Reply-To: <53C05134.4070600@oracle.com> References: <53C017B8.2090802@oracle.com> <02120BFE-B4A9-4CD0-9129-931FC836F2EB@oracle.com> <53C05134.4070600@oracle.com> Message-ID: <2CD75907-51C6-46C8-8961-1F9CED285111@oracle.com> On Jul 11, 2014, at 3:03 PM, Maurizio Cimadamore wrote: > > On 11/07/14 18:21, Dan Smith wrote: >> On Jul 11, 2014, at 10:58 AM, Brian Goetz wrote: >> >>> The example in the writeup has many pleasing properties (one artifact, so can't get out of sync; encode minimal additional metadata needed to efficiently transform an erased classfile to a specialized classfile; the "template" can be used as an erased classfile as is, just by ignoring the specialization metadata attributes.) >>> >>> It also has an unpleasant property: the bytecode for an already loaded class is not available easily through its classloader or reflection, meaning that a runtime specialization mechanism would have to jump through hoops (e.g., retransform-classes) to get at the bytecode. Since specializing a class under this scheme requires, as input, the bytecode of the original class, this could become problematic for classes that are themselves generated (i.e., not findable with ClassLoader.getResource("Foo.class")). >> Maybe what you're after with classdynamic is (primarily) a ClassLoader feature rather than a VM feature? That is, maybe 'defineClass' should be parameterized by a pluggable class-generation system, and that's where the expansion should take place, intercepting the bytes and spitting out the special class. It's not totally clear to me how this would work, but I think it may be the right place for it. (I have consistently felt like what we really want with classdynamic is ClassLoaders 2.0.) > I believe that classloader was also NextGen way to get there: > > http://dl.acm.org/citation.cfm?id=1141656 Right. To be clear, I'm not just suggesting that we use ClassLoaders and call it a day. There a good reasons to want something more. But perhaps that "something more" can take the form of a re-architected ClassLoader API -- specifically one that exposes a hook between the byte array and the generated class. ?Dan From maurizio.cimadamore at oracle.com Mon Jul 14 09:25:11 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Mon, 14 Jul 2014 09:25:11 +0000 Subject: hg: valhalla/valhalla/langtools: Add parser-support for type-specialization. Message-ID: <201407140925.s6E9PBXh010991@aojmv0008> Changeset: d9c7704baf6e Author: mcimadamore Date: 2014-07-11 17:05 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/d9c7704baf6e Add parser-support for type-specialization. * Added new 'valhalla' source flag used to enable valhalla-related features * Added parser support for context-dependent keyword 'any' in type-variable declarations * Generalized test infrastructure to check javac handling of 'lax' identifiers (assert, enum, underscore, any) ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/code/Source.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/parser/Tokens.java ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/com/sun/tools/javac/tree/Pretty.java ! src/share/classes/com/sun/tools/javac/tree/TreeCopier.java ! src/share/classes/com/sun/tools/javac/tree/TreeMaker.java - test/tools/javac/lambda/IdentifierTest.java + test/tools/javac/parser/laxIdentifiers/LaxIdentifierTemplate.java + test/tools/javac/parser/laxIdentifiers/LaxIdentifierTest.java + test/tools/javac/valhalla/typespec/Any.java From maurizio.cimadamore at oracle.com Mon Jul 14 09:42:08 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 14 Jul 2014 10:42:08 +0100 Subject: type-specialization prototype Message-ID: <53C3A5F0.5080404@oracle.com> Fellow vikings, as you probably have noticed, I've start hacking [1] on the type-specialization prototype; the current state of this feature is captured in [2]. The first patch I've pushed adds support for the 'any' type-variable 'modifier'. Aside from allowing it in the parser (and setting a corresponding flag on the AST), the rest of javac is still 'any' agnostic - I plan to extend the compiler support in the upcoming weeks, in order to add suitable semantics checks and bytecode representation. As part of this first changeset, I've also added a new source flag - 'valhalla' which is now being used as the default in the context of this project. Keep comments flowing, and enjoy the ride - I'm sure it'll be a fun one :-) Maurizio [1] - http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/d9c7704baf6e [2] - http://cr.openjdk.java.net/~briangoetz/valhalla/specialization.html From maurizio.cimadamore at oracle.com Tue Jul 15 17:42:38 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Tue, 15 Jul 2014 17:42:38 +0000 Subject: hg: valhalla/valhalla/langtools: Unify code paths for type-argument bound-checking. Message-ID: <201407151742.s6FHgceR025967@aojmv0008> Changeset: f0d0dd18b996 Author: mcimadamore Date: 2014-07-15 18:37 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/f0d0dd18b996 Unify code paths for type-argument bound-checking. * All bound-checking code is now done in Check - this includes generic type well-formedness AND explicit method type-argument checks * Completely overhauled logic for bound check. Code is now more general and reusable * Changed source/target version of bootstrap compiler to allow lambda support ! make/build.properties ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/util/List.java ! src/share/classes/com/sun/tools/javac/util/Pair.java ! test/tools/javac/generics/typevars/6968793/T6968793.out From fvheeswijk at outlook.com Wed Jul 16 10:18:01 2014 From: fvheeswijk at outlook.com (Frank van Heeswijk) Date: Wed, 16 Jul 2014 10:18:01 +0000 Subject: Early draft proposal for Value Arrays Message-ID: I have thought of a feature that would be very useful in practice and might actually be in the scope of the Valhalla project. The outlined description below is a very early draft about Value Arrays and I am looking for opinions. Let us start with a practical example, an high performance class that works with matrices stored as doubles. As example we can take the 4 by 4 variant, which is used a lot in graphics, in Java 8 there are two issues: 1) Mathematical operations are cumbersome; if you create a new copy on every operation, then a lot of objects will be created and it will lead to garbage collection. The only alternative would be updating the object as you go (without creating a new instance), but it is tricky to work with such a class. 2) You want to ideally store the objects in an float[] m or in a float[][] m for easy access, but this also costs another object per instance. I think that the first issue is fixed with the upcoming addition of Value Types. However the second issue is not so easily fixed, therefore I would like to introduce the idea of Value Arrays: @ValueArray private final double[][] m; The idea is that all array elements will be stored directly on the heap(?) and that no array object will be created at all. I am also wondering to what extent this is possible, if at all: 1) Value Array with constant size, known at compile time. 2) Value Array with an unknown size, dynamically known at runtime. So the expected behaviour would be that: @ValueArray private final double[][] m = new double[4][4]; would simply be equal to how matrices (4x4) are defined nowadays in practice: private final double m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; I think that the maintainability and readability of the code will be greatly improved with this feature and that the Valhalla project is the correct project to consider this feature. From albert.noll at oracle.com Wed Jul 16 10:59:03 2014 From: albert.noll at oracle.com (Albert) Date: Wed, 16 Jul 2014 12:59:03 +0200 Subject: Early draft proposal for Value Arrays In-Reply-To: References: Message-ID: <53C65AF7.5030505@oracle.com> Hi Frank, did you get a chance to look at Arrays 2.0? Best, Albert On 07/16/2014 12:18 PM, Frank van Heeswijk wrote: > I have thought of a feature that would be very useful in practice and might actually be in the scope of the Valhalla project. > The outlined description below is a very early draft about Value Arrays and I am looking for opinions. > > Let us start with a practical example, an high performance class that works with matrices stored as doubles. > As example we can take the 4 by 4 variant, which is used a lot in graphics, in Java 8 there are two issues: > 1) Mathematical operations are cumbersome; if you create a new copy on every operation, then a lot of objects will be created and it will lead to garbage collection. > The only alternative would be updating the object as you go (without creating a new instance), but it is tricky to work with such a class. > 2) You want to ideally store the objects in an float[] m or in a float[][] m for easy access, but this also costs another object per instance. > > I think that the first issue is fixed with the upcoming addition of Value Types. > However the second issue is not so easily fixed, therefore I would like to introduce the idea of Value Arrays: > > @ValueArray > private final double[][] m; > > The idea is that all array elements will be stored directly on the heap(?) and that no array object will be created at all. > > I am also wondering to what extent this is possible, if at all: > 1) Value Array with constant size, known at compile time. > 2) Value Array with an unknown size, dynamically known at runtime. > > So the expected behaviour would be that: > > @ValueArray > private final double[][] m = new double[4][4]; > > would simply be equal to how matrices (4x4) are defined nowadays in practice: > > private final double m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44; > > I think that the maintainability and readability of the code will be greatly improved with this feature and that the Valhalla project is the correct project to consider this feature. > From maurizio.cimadamore at oracle.com Thu Jul 17 10:03:55 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 17 Jul 2014 10:03:55 +0000 Subject: hg: valhalla/valhalla/langtools: Fix build problem with genstubs step trying to (incorrectly) mock a functional interface Message-ID: <201407171003.s6HA3tOU002867@aojmv0008> Changeset: a82e61eca30b Author: mcimadamore Date: 2014-07-17 11:00 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/a82e61eca30b Fix build problem with genstubs step trying to (incorrectly) mock a functional interface ! make/GenstubsLangtools.gmk From maurizio.cimadamore at oracle.com Fri Jul 18 16:44:50 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Fri, 18 Jul 2014 16:44:50 +0000 Subject: hg: valhalla/valhalla/langtools: Add type-checking support for 'any' type-variables Message-ID: <201407181644.s6IGio5I009200@aojmv0008> Changeset: b38cb9f5c2de Author: mcimadamore Date: 2014-07-18 17:44 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/b38cb9f5c2de Add type-checking support for 'any' type-variables *) Tweak generic well-formedness to accept primitive in generics *) Add support for 'any' in main typing assertions (subtyping, type-equality, cast, etc.) *) Add inference support for 'any' type-variables *) Add logic to detect type-specialization-related overload/override/hide clashes *) Add basic tests ! src/share/classes/com/sun/tools/javac/code/Symtab.java ! src/share/classes/com/sun/tools/javac/code/Type.java ! src/share/classes/com/sun/tools/javac/code/TypeTag.java ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/comp/Check.java ! src/share/classes/com/sun/tools/javac/comp/Infer.java ! src/share/classes/com/sun/tools/javac/comp/Resolve.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java + test/tools/javac/diags/examples/TypeVarCantBeDerefAny.java + test/tools/javac/generics/typevars/8026527/T8026527.java + test/tools/javac/generics/typevars/8026527/T8026527.out + test/tools/javac/valhalla/typespec/AnyReference.java + test/tools/javac/valhalla/typespec/AnyReference.out + test/tools/javac/valhalla/typespec/Cast01.java + test/tools/javac/valhalla/typespec/Cast01.out + test/tools/javac/valhalla/typespec/Clash.java + test/tools/javac/valhalla/typespec/Clash.out + test/tools/javac/valhalla/typespec/Inference01.java + test/tools/javac/valhalla/typespec/Inference01.out + test/tools/javac/valhalla/typespec/Inference02.java + test/tools/javac/valhalla/typespec/Inference02.out + test/tools/javac/valhalla/typespec/Subtyping01.java + test/tools/javac/valhalla/typespec/Subtyping01.out From maurizio.cimadamore at oracle.com Tue Jul 22 11:19:28 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Tue, 22 Jul 2014 11:19:28 +0000 Subject: hg: valhalla/valhalla/langtools: Add classfile support for 'any' type-variables Message-ID: <201407221119.s6MBJSRc006993@aojmv0008> Changeset: 84aad1e3da3b Author: mcimadamore Date: 2014-07-22 12:16 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/84aad1e3da3b Add classfile support for 'any' type-variables *) Addded TypeVariablesMap attribute to store extra type-variable flags in classfile *) Add ClassReader support for new attribute (to support separate compilation) *) Tweak cast rules to issue unchecked warning on Any -> Object cast *) Disallow explicit declared bounds on 'any' type-variables *) Remove redundant type-parameter well-formedness check in method call attribution *) Add basic separate compilation test ! src/share/classes/com/sun/tools/javac/code/Types.java ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties ! src/share/classes/com/sun/tools/javac/util/Names.java + test/tools/javac/diags/examples/AnyTypeVarMayNotDeclareExplicitBounds.java ! test/tools/javac/valhalla/typespec/Any.java + test/tools/javac/valhalla/typespec/Any.out ! test/tools/javac/valhalla/typespec/Cast01.java ! test/tools/javac/valhalla/typespec/Cast01.out + test/tools/javac/valhalla/typespec/separate/A.java + test/tools/javac/valhalla/typespec/separate/TestSeparate.java + test/tools/javac/valhalla/typespec/separate/TestSeparate.out From maurizio.cimadamore at oracle.com Thu Jul 24 11:26:00 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 24 Jul 2014 11:26:00 +0000 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes Message-ID: <201407241126.s6OBQ2Uc016678@aojmv0008> Changeset: bb57e20a33a4 Author: mcimadamore Date: 2014-07-24 12:22 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 Add support for tracking 'any'-related opcodes *) Overhauled Items hierarchy (now field/methods have their own classes) *) Add AnyItem to model a bytecode item associated with 'any' variables *) Add new BytecodeMapping attribute to map 'any'-related opcodes back to the original (unerased) signature ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java ! src/share/classes/com/sun/tools/javac/jvm/Code.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/jvm/Items.java ! src/share/classes/com/sun/tools/javac/util/Names.java From forax at univ-mlv.fr Thu Jul 24 12:25:12 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 14:25:12 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <201407241126.s6OBQ2Uc016678@aojmv0008> References: <201407241126.s6OBQ2Uc016678@aojmv0008> Message-ID: <53D0FB28.4020404@univ-mlv.fr> Hi Maurizio, I think you have miss several opcodes that also need to be marked as any, anewarray, areturn and i think dup, dup_x1, dup_x2 and pop (I suppose than Object.equals will be used instead of if_acmpeq, if_acmpne) Maybe you want to treat anewarray like opcodes getfield/invoke* but in that case, either you need invokedynamic or a new bytecode ? cheers, R?mi On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: > Changeset: bb57e20a33a4 > Author: mcimadamore > Date: 2014-07-24 12:22 +0100 > URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 > > Add support for tracking 'any'-related opcodes > *) Overhauled Items hierarchy (now field/methods have their own classes) > *) Add AnyItem to model a bytecode item associated with 'any' variables > *) Add new BytecodeMapping attribute to map 'any'-related opcodes back to the original (unerased) signature > > ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java > ! src/share/classes/com/sun/tools/javac/jvm/Code.java > ! src/share/classes/com/sun/tools/javac/jvm/Gen.java > ! src/share/classes/com/sun/tools/javac/jvm/Items.java > ! src/share/classes/com/sun/tools/javac/util/Names.java > From maurizio.cimadamore at oracle.com Thu Jul 24 13:21:26 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 24 Jul 2014 14:21:26 +0100 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D0FB28.4020404@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> Message-ID: <53D10856.60006@oracle.com> Hi Remi, thanks for the comments. This is an initial prototype to get things going and unblock the work on the specializer. The current support will be enough to compile simple classes such as Box (in Brian's document). Said that, opcodes such as dup/pop can easily be added in the current code by adding more 'cases' to the filtering switch. areturn is there - but it's generated in a different code path - see Gen.visitReturn. For opcodes such as new and newarray, we need to have unerased expression types being saved by javac somewhere, so that was a bit beyond the scope of this patch. Regarging comparisons - the first issue is that type-checking support for comparisons involving 'any' type-variable is not there yet - i.e. the compiler will reject it as of now. Once that's allowed, you will be able to compare T with T but not T with int (similarly as you cannot compare an ordinary type-variable with a string). In other words, I don't believe equals() will ever be generated - i.e. the compiler will always use if_acmpeq and the likes, which will be tagged, eventually, in the bytecode. Maurizio On 24/07/14 13:25, Remi Forax wrote: > Hi Maurizio, > I think you have miss several opcodes that also need to be marked as any, > anewarray, areturn and i think dup, dup_x1, dup_x2 and pop > (I suppose than Object.equals will be used instead of if_acmpeq, > if_acmpne) > > Maybe you want to treat anewarray like opcodes getfield/invoke* but > in that case, either you need invokedynamic or a new bytecode ? > > cheers, > R?mi > > On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: >> Changeset: bb57e20a33a4 >> Author: mcimadamore >> Date: 2014-07-24 12:22 +0100 >> URL: >> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >> >> Add support for tracking 'any'-related opcodes >> *) Overhauled Items hierarchy (now field/methods have their own classes) >> *) Add AnyItem to model a bytecode item associated with 'any' variables >> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >> back to the original (unerased) signature >> >> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >> ! src/share/classes/com/sun/tools/javac/util/Names.java >> > From brian.goetz at oracle.com Thu Jul 24 13:56:06 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 24 Jul 2014 09:56:06 -0400 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D10856.60006@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: <58741E6A-A21E-490B-B744-FBDB098B9308@oracle.com> I don?t think that polymorphic byte codes (dup, getfield, etc) need to be annotated; this attribute tells us which bytecodes have to be rewritten for specialization. Since dup is valid on all types, everything should just come out in the wash. On Jul 24, 2014, at 9:21 AM, Maurizio Cimadamore wrote: > Hi Remi, > thanks for the comments. This is an initial prototype to get things going and unblock the work on the specializer. The current support will be enough to compile simple classes such as Box (in Brian's document). > > Said that, opcodes such as dup/pop can easily be added in the current code by adding more 'cases' to the filtering switch. > > areturn is there - but it's generated in a different code path - see Gen.visitReturn. > > For opcodes such as new and newarray, we need to have unerased expression types being saved by javac somewhere, so that was a bit beyond the scope of this patch. > > Regarging comparisons - the first issue is that type-checking support for comparisons involving 'any' type-variable is not there yet - i.e. the compiler will reject it as of now. Once that's allowed, you will be able to compare T with T but not T with int (similarly as you cannot compare an ordinary type-variable with a string). In other words, I don't believe equals() will ever be generated - i.e. the compiler will always use if_acmpeq and the likes, which will be tagged, eventually, in the bytecode. > > Maurizio > > On 24/07/14 13:25, Remi Forax wrote: >> Hi Maurizio, >> I think you have miss several opcodes that also need to be marked as any, >> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >> (I suppose than Object.equals will be used instead of if_acmpeq, if_acmpne) >> >> Maybe you want to treat anewarray like opcodes getfield/invoke* but >> in that case, either you need invokedynamic or a new bytecode ? >> >> cheers, >> R?mi >> >> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: >>> Changeset: bb57e20a33a4 >>> Author: mcimadamore >>> Date: 2014-07-24 12:22 +0100 >>> URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>> >>> Add support for tracking 'any'-related opcodes >>> *) Overhauled Items hierarchy (now field/methods have their own classes) >>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes back to the original (unerased) signature >>> >>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>> >> > From forax at univ-mlv.fr Thu Jul 24 16:12:19 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 18:12:19 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <58741E6A-A21E-490B-B744-FBDB098B9308@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <58741E6A-A21E-490B-B744-FBDB098B9308@oracle.com> Message-ID: <53D13063.9010100@univ-mlv.fr> On 07/24/2014 03:56 PM, Brian Goetz wrote: > I don?t think that polymorphic byte codes (dup, getfield, etc) need to be annotated; this attribute tells us which bytecodes have to be rewritten for specialization. Since dup is valid on all types, everything should just come out in the wash. The problem of dup, is that int and double don't take the same space on stack, so if there is an any on top of the stack, after specialization it can be transformed either to a dup or to a dup2 depending if it's a specialization to int or to double. Also, I've forgotten 'swap' in my list, and there is no swap2. For getfield/method call, if you don't annotate them, you need to propagate the types of the values on the stack and the type of the local variables. If you propagate the type of the local variable, you don't need to annotate 'aload 2' because you already know that the local variable at slot 2 is any. So either you annotate aload and getfield, or you don't annotate any of them. R?mi > > On Jul 24, 2014, at 9:21 AM, Maurizio Cimadamore wrote: > >> Hi Remi, >> thanks for the comments. This is an initial prototype to get things going and unblock the work on the specializer. The current support will be enough to compile simple classes such as Box (in Brian's document). >> >> Said that, opcodes such as dup/pop can easily be added in the current code by adding more 'cases' to the filtering switch. >> >> areturn is there - but it's generated in a different code path - see Gen.visitReturn. >> >> For opcodes such as new and newarray, we need to have unerased expression types being saved by javac somewhere, so that was a bit beyond the scope of this patch. >> >> Regarging comparisons - the first issue is that type-checking support for comparisons involving 'any' type-variable is not there yet - i.e. the compiler will reject it as of now. Once that's allowed, you will be able to compare T with T but not T with int (similarly as you cannot compare an ordinary type-variable with a string). In other words, I don't believe equals() will ever be generated - i.e. the compiler will always use if_acmpeq and the likes, which will be tagged, eventually, in the bytecode. >> >> Maurizio >> >> On 24/07/14 13:25, Remi Forax wrote: >>> Hi Maurizio, >>> I think you have miss several opcodes that also need to be marked as any, >>> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >>> (I suppose than Object.equals will be used instead of if_acmpeq, if_acmpne) >>> >>> Maybe you want to treat anewarray like opcodes getfield/invoke* but >>> in that case, either you need invokedynamic or a new bytecode ? >>> >>> cheers, >>> R?mi >>> >>> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: >>>> Changeset: bb57e20a33a4 >>>> Author: mcimadamore >>>> Date: 2014-07-24 12:22 +0100 >>>> URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>>> >>>> Add support for tracking 'any'-related opcodes >>>> *) Overhauled Items hierarchy (now field/methods have their own classes) >>>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes back to the original (unerased) signature >>>> >>>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>>> From forax at univ-mlv.fr Thu Jul 24 16:19:00 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 18:19:00 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D10856.60006@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: <53D131F4.5080906@univ-mlv.fr> On 07/24/2014 03:21 PM, Maurizio Cimadamore wrote: > Hi Remi, > thanks for the comments. This is an initial prototype to get things > going and unblock the work on the specializer. The current support > will be enough to compile simple classes such as Box (in Brian's > document). > > Said that, opcodes such as dup/pop can easily be added in the current > code by adding more 'cases' to the filtering switch. > > areturn is there - but it's generated in a different code path - see > Gen.visitReturn. > > For opcodes such as new and newarray, we need to have unerased > expression types being saved by javac somewhere, so that was a bit > beyond the scope of this patch. new if different of anewarray, i don't think you can specialize new. anewarray is equivalent to getfield, the syntax use an internal name instead of a descriptor which is an historical glitch in my opinion but if you know how to specialize getfield, you know how to specialize anewarray. > > Regarging comparisons - the first issue is that type-checking support > for comparisons involving 'any' type-variable is not there yet - i.e. > the compiler will reject it as of now. Once that's allowed, you will > be able to compare T with T but not T with int (similarly as you > cannot compare an ordinary type-variable with a string). In other > words, I don't believe equals() will ever be generated - i.e. the > compiler will always use if_acmpeq and the likes, which will be > tagged, eventually, in the bytecode. I was thinking about the opposite, void m(T t1, t t2) { return t1.equals(t2); } does this code should use if_icmpeq if T is specialized with T=int. > > Maurizio R?mi > > On 24/07/14 13:25, Remi Forax wrote: >> Hi Maurizio, >> I think you have miss several opcodes that also need to be marked as >> any, >> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >> (I suppose than Object.equals will be used instead of if_acmpeq, >> if_acmpne) >> >> Maybe you want to treat anewarray like opcodes getfield/invoke* but >> in that case, either you need invokedynamic or a new bytecode ? >> >> cheers, >> R?mi >> >> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: >>> Changeset: bb57e20a33a4 >>> Author: mcimadamore >>> Date: 2014-07-24 12:22 +0100 >>> URL: >>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>> >>> Add support for tracking 'any'-related opcodes >>> *) Overhauled Items hierarchy (now field/methods have their own >>> classes) >>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >>> back to the original (unerased) signature >>> >>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>> >> > From maurizio.cimadamore at oracle.com Thu Jul 24 16:35:08 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 24 Jul 2014 17:35:08 +0100 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D131F4.5080906@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D131F4.5080906@univ-mlv.fr> Message-ID: <53D135BC.8010406@oracle.com> On 24/07/14 17:19, Remi Forax wrote: > > On 07/24/2014 03:21 PM, Maurizio Cimadamore wrote: >> Hi Remi, >> thanks for the comments. This is an initial prototype to get things >> going and unblock the work on the specializer. The current support >> will be enough to compile simple classes such as Box (in Brian's >> document). >> >> Said that, opcodes such as dup/pop can easily be added in the current >> code by adding more 'cases' to the filtering switch. >> >> areturn is there - but it's generated in a different code path - see >> Gen.visitReturn. >> >> For opcodes such as new and newarray, we need to have unerased >> expression types being saved by javac somewhere, so that was a bit >> beyond the scope of this patch. > > new if different of anewarray, i don't think you can specialize new. > anewarray is equivalent to getfield, the syntax use an internal name > instead of a descriptor which is an historical glitch in my opinion > but if you know how to specialize getfield, you know how to specialize > anewarray. I said new - because there will need to be something if you do new ArrayList in order to point back at the unerased info. This will become something else in the long run, but for now tagging 'new' will make sure that the specializer will have a chance to rewrite the name of the class to be instantiated. > >> >> Regarging comparisons - the first issue is that type-checking >> support for comparisons involving 'any' type-variable is not there >> yet - i.e. the compiler will reject it as of now. Once that's >> allowed, you will be able to compare T with T but not T with int >> (similarly as you cannot compare an ordinary type-variable with a >> string). In other words, I don't believe equals() will ever be >> generated - i.e. the compiler will always use if_acmpeq and the >> likes, which will be tagged, eventually, in the bytecode. > > I was thinking about the opposite, > void m(T t1, t t2) { > return t1.equals(t2); > } > > does this code should use if_icmpeq if T is specialized with T=int. The code above doesn't compile. It doesn't make sense (at least for now) to speak about members of an 'any' type-variable, so there's no equals in T. Maurizio > >> >> Maurizio > > R?mi > >> >> On 24/07/14 13:25, Remi Forax wrote: >>> Hi Maurizio, >>> I think you have miss several opcodes that also need to be marked as >>> any, >>> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >>> (I suppose than Object.equals will be used instead of if_acmpeq, >>> if_acmpne) >>> >>> Maybe you want to treat anewarray like opcodes getfield/invoke* but >>> in that case, either you need invokedynamic or a new bytecode ? >>> >>> cheers, >>> R?mi >>> >>> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: >>>> Changeset: bb57e20a33a4 >>>> Author: mcimadamore >>>> Date: 2014-07-24 12:22 +0100 >>>> URL: >>>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>>> >>>> >>>> Add support for tracking 'any'-related opcodes >>>> *) Overhauled Items hierarchy (now field/methods have their own >>>> classes) >>>> *) Add AnyItem to model a bytecode item associated with 'any' >>>> variables >>>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >>>> back to the original (unerased) signature >>>> >>>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>>> >>> >> > From maurizio.cimadamore at oracle.com Thu Jul 24 16:38:04 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 24 Jul 2014 17:38:04 +0100 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D13063.9010100@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <58741E6A-A21E-490B-B744-FBDB098B9308@oracle.com> <53D13063.9010100@univ-mlv.fr> Message-ID: <53D1366C.8030907@oracle.com> On 24/07/14 17:12, Remi Forax wrote: > Also, I've forgotten 'swap' in my list, and there is no swap2. Seems like javac never generates swap. Maurizio From forax at univ-mlv.fr Thu Jul 24 16:46:13 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 18:46:13 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D1366C.8030907@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <58741E6A-A21E-490B-B744-FBDB098B9308@oracle.com> <53D13063.9010100@univ-mlv.fr> <53D1366C.8030907@oracle.com> Message-ID: <53D13855.8050502@univ-mlv.fr> On 07/24/2014 06:38 PM, Maurizio Cimadamore wrote: > > On 24/07/14 17:12, Remi Forax wrote: >> Also, I've forgotten 'swap' in my list, and there is no swap2. > Seems like javac never generates swap. yes, it's dubious for a compiler to use swap when you can just swap the two lines that generate the code, but it's very useful when you do rewriting at runtime :) > > Maurizio R?mi From forax at univ-mlv.fr Thu Jul 24 17:00:38 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 19:00:38 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D135BC.8010406@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D131F4.5080906@univ-mlv.fr> <53D135BC.8010406@oracle.com> Message-ID: <53D13BB6.2040404@univ-mlv.fr> On 07/24/2014 06:35 PM, Maurizio Cimadamore wrote: > > On 24/07/14 17:19, Remi Forax wrote: >> >> On 07/24/2014 03:21 PM, Maurizio Cimadamore wrote: >>> Hi Remi, >>> thanks for the comments. This is an initial prototype to get things >>> going and unblock the work on the specializer. The current support >>> will be enough to compile simple classes such as Box (in Brian's >>> document). >>> >>> Said that, opcodes such as dup/pop can easily be added in the >>> current code by adding more 'cases' to the filtering switch. >>> >>> areturn is there - but it's generated in a different code path - see >>> Gen.visitReturn. >>> >>> For opcodes such as new and newarray, we need to have unerased >>> expression types being saved by javac somewhere, so that was a bit >>> beyond the scope of this patch. >> >> new if different of anewarray, i don't think you can specialize new. >> anewarray is equivalent to getfield, the syntax use an internal name >> instead of a descriptor which is an historical glitch in my opinion >> but if you know how to specialize getfield, you know how to >> specialize anewarray. > I said new - because there will need to be something if you do > > new ArrayList > > in order to point back at the unerased info. This will become > something else in the long run, but for now tagging 'new' will make > sure that the specializer will have a chance to rewrite the name of > the class to be instantiated. I see, but this code is not specializable. In my opinion, new ArrayList should be rewritten to use invokedynamic, here is why. I think the specializer as you call it should work at runtime, otherwise we will run in exactly the same trouble we have with inner classes, binary compatibility being the biggest issue. So there is an issue if you generate ArrayList at runtime, it doesn't exit at compile time :) so you can not have a name to insert in the bytecode. For me, ArrayList or ArrayList should be erased as Object (exactly like the supertype of int[] and double[] is Object), and the type argument should be sent as a bootstrap argument to a special invokedynamic. basically new ArrayList can be trasformed to invokedynamic ()Ljava/lang/Object; [ int.class ] likewise, any method call on ArrayList should be an invokedynamic. With that, at runtime, in the bootstrap method, you can ask the specializer to generate specialized class only when needed, i.e the first time a constructor is called. >> >>> >>> Regarging comparisons - the first issue is that type-checking >>> support for comparisons involving 'any' type-variable is not there >>> yet - i.e. the compiler will reject it as of now. Once that's >>> allowed, you will be able to compare T with T but not T with int >>> (similarly as you cannot compare an ordinary type-variable with a >>> string). In other words, I don't believe equals() will ever be >>> generated - i.e. the compiler will always use if_acmpeq and the >>> likes, which will be tagged, eventually, in the bytecode. >> >> I was thinking about the opposite, >> void m(T t1, t t2) { >> return t1.equals(t2); >> } >> >> does this code should use if_icmpeq if T is specialized with T=int. > > The code above doesn't compile. It doesn't make sense (at least for > now) to speak about members of an 'any' type-variable, so there's no > equals in T. so practically there will be at least two codes by method, the one that takes an Object because you can do equals on it and the one that takes any that will use ==. > > Maurizio R?mi From forax at univ-mlv.fr Thu Jul 24 17:05:13 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 19:05:13 +0200 Subject: Special ASM branches named valhalla Message-ID: <53D13CC9.3000002@univ-mlv.fr> I've started to hack a version of ASM in order to be able to do the specialization at runtime. http://websvn.ow2.org/listing.php?repname=asm&path=%2Fbranches%2FVALHALLA%2F Currently, it only supports the TypeVariableMap attribute (reader and writer) and is fully backward compatible with ASM5 :) cheers, R?mi From maurizio.cimadamore at oracle.com Thu Jul 24 17:33:04 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 24 Jul 2014 18:33:04 +0100 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D13BB6.2040404@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D131F4.5080906@univ-mlv.fr> <53D135BC.8010406@oracle.com> <53D13BB6.2040404@univ-mlv.fr> Message-ID: <53D14350.7060204@oracle.com> On 24/07/14 18:00, Remi Forax wrote: > > On 07/24/2014 06:35 PM, Maurizio Cimadamore wrote: >> >> On 24/07/14 17:19, Remi Forax wrote: >>> >>> On 07/24/2014 03:21 PM, Maurizio Cimadamore wrote: >>>> Hi Remi, >>>> thanks for the comments. This is an initial prototype to get things >>>> going and unblock the work on the specializer. The current support >>>> will be enough to compile simple classes such as Box (in Brian's >>>> document). >>>> >>>> Said that, opcodes such as dup/pop can easily be added in the >>>> current code by adding more 'cases' to the filtering switch. >>>> >>>> areturn is there - but it's generated in a different code path - >>>> see Gen.visitReturn. >>>> >>>> For opcodes such as new and newarray, we need to have unerased >>>> expression types being saved by javac somewhere, so that was a bit >>>> beyond the scope of this patch. >>> >>> new if different of anewarray, i don't think you can specialize new. >>> anewarray is equivalent to getfield, the syntax use an internal name >>> instead of a descriptor which is an historical glitch in my opinion >>> but if you know how to specialize getfield, you know how to >>> specialize anewarray. >> I said new - because there will need to be something if you do >> >> new ArrayList >> >> in order to point back at the unerased info. This will become >> something else in the long run, but for now tagging 'new' will make >> sure that the specializer will have a chance to rewrite the name of >> the class to be instantiated. > > I see, but this code is not specializable. > In my opinion, new ArrayList should be rewritten to use > invokedynamic, here is why. > > I think the specializer as you call it should work at runtime, > otherwise we will run in exactly the same trouble we have with inner > classes, > binary compatibility being the biggest issue. > So there is an issue if you generate ArrayList at runtime, it > doesn't exit at compile time :) > so you can not have a name to insert in the bytecode. > > For me, ArrayList or ArrayList should be erased as Object > (exactly like the supertype of int[] and double[] is Object), > and the type argument should be sent as a bootstrap argument to a > special invokedynamic. > > basically > new ArrayList > can be trasformed to > invokedynamic ()Ljava/lang/Object; [ int.class ] > > likewise, any method call on ArrayList should be an invokedynamic. > > With that, at runtime, in the bootstrap method, you can ask the > specializer to generate specialized class only when needed, > i.e the first time a constructor is called. In time, an approach similar to the one you describe will be used - in the meantime, we'd like to get more experience with these features by using an offline specializer that goes through the bytecode and spits specialized versions of the classfiles. > > >>> >>>> >>>> Regarging comparisons - the first issue is that type-checking >>>> support for comparisons involving 'any' type-variable is not there >>>> yet - i.e. the compiler will reject it as of now. Once that's >>>> allowed, you will be able to compare T with T but not T with int >>>> (similarly as you cannot compare an ordinary type-variable with a >>>> string). In other words, I don't believe equals() will ever be >>>> generated - i.e. the compiler will always use if_acmpeq and the >>>> likes, which will be tagged, eventually, in the bytecode. >>> >>> I was thinking about the opposite, >>> void m(T t1, t t2) { >>> return t1.equals(t2); >>> } >>> >>> does this code should use if_icmpeq if T is specialized with T=int. >> >> The code above doesn't compile. It doesn't make sense (at least for >> now) to speak about members of an 'any' type-variable, so there's no >> equals in T. > > so practically there will be at least two codes by method, the one > that takes an Object because you can do equals on it > and the one that takes any that will use ==. That's the status of the current (very early) prototype. Nothing is set in stone at this point - but it seems like a stable design choice. Maurizio > >> >> Maurizio > > R?mi > From maurizio.cimadamore at oracle.com Thu Jul 24 17:36:04 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Thu, 24 Jul 2014 18:36:04 +0100 Subject: Special ASM branches named valhalla In-Reply-To: <53D13CC9.3000002@univ-mlv.fr> References: <53D13CC9.3000002@univ-mlv.fr> Message-ID: <53D14404.10502@oracle.com> On 24/07/14 18:05, Remi Forax wrote: > I've started to hack a version of ASM in order to be able to do the > specialization at runtime. > http://websvn.ow2.org/listing.php?repname=asm&path=%2Fbranches%2FVALHALLA%2F > > > Currently, it only supports the TypeVariableMap attribute (reader and > writer) > and is fully backward compatible with ASM5 :) Cool! Very much appreciated :-) Maurizio > > cheers, > R?mi > From maurizio.cimadamore at oracle.com Thu Jul 24 17:39:11 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Thu, 24 Jul 2014 17:39:11 +0000 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes - take two Message-ID: <201407241739.s6OHdBbu013898@aojmv0008> Changeset: edd2f1c5bfb9 Author: mcimadamore Date: 2014-07-24 18:28 +0100 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/edd2f1c5bfb9 Add support for tracking 'any'-related opcodes - take two *) Add support for dup/if_acmpne/if_acmpeq opcodes *) Add type-checking support for 'any' type-variable comparison *) Add basic test for 'any' type-variable comparison ! src/share/classes/com/sun/tools/javac/comp/Attr.java ! src/share/classes/com/sun/tools/javac/jvm/Code.java ! src/share/classes/com/sun/tools/javac/jvm/Gen.java ! src/share/classes/com/sun/tools/javac/jvm/Items.java + test/tools/javac/valhalla/typespec/TestComparisons.java + test/tools/javac/valhalla/typespec/TestComparisons.out From forax at univ-mlv.fr Thu Jul 24 18:38:03 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 24 Jul 2014 20:38:03 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D14350.7060204@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D131F4.5080906@univ-mlv.fr> <53D135BC.8010406@oracle.com> <53D13BB6.2040404@univ-mlv.fr> <53D14350.7060204@oracle.com> Message-ID: <53D1528B.8050103@univ-mlv.fr> On 07/24/2014 07:33 PM, Maurizio Cimadamore wrote: > > On 24/07/14 18:00, Remi Forax wrote: >> >> On 07/24/2014 06:35 PM, Maurizio Cimadamore wrote: >>> >>> On 24/07/14 17:19, Remi Forax wrote: >>>> >>>> On 07/24/2014 03:21 PM, Maurizio Cimadamore wrote: >>>>> Hi Remi, >>>>> thanks for the comments. This is an initial prototype to get >>>>> things going and unblock the work on the specializer. The current >>>>> support will be enough to compile simple classes such as Box (in >>>>> Brian's document). >>>>> >>>>> Said that, opcodes such as dup/pop can easily be added in the >>>>> current code by adding more 'cases' to the filtering switch. >>>>> >>>>> areturn is there - but it's generated in a different code path - >>>>> see Gen.visitReturn. >>>>> >>>>> For opcodes such as new and newarray, we need to have unerased >>>>> expression types being saved by javac somewhere, so that was a bit >>>>> beyond the scope of this patch. >>>> >>>> new if different of anewarray, i don't think you can specialize new. >>>> anewarray is equivalent to getfield, the syntax use an internal >>>> name instead of a descriptor which is an historical glitch in my >>>> opinion >>>> but if you know how to specialize getfield, you know how to >>>> specialize anewarray. >>> I said new - because there will need to be something if you do >>> >>> new ArrayList >>> >>> in order to point back at the unerased info. This will become >>> something else in the long run, but for now tagging 'new' will make >>> sure that the specializer will have a chance to rewrite the name of >>> the class to be instantiated. >> >> I see, but this code is not specializable. >> In my opinion, new ArrayList should be rewritten to use >> invokedynamic, here is why. >> >> I think the specializer as you call it should work at runtime, >> otherwise we will run in exactly the same trouble we have with inner >> classes, >> binary compatibility being the biggest issue. >> So there is an issue if you generate ArrayList at runtime, it >> doesn't exit at compile time :) >> so you can not have a name to insert in the bytecode. >> >> For me, ArrayList or ArrayList should be erased as >> Object (exactly like the supertype of int[] and double[] is Object), >> and the type argument should be sent as a bootstrap argument to a >> special invokedynamic. >> >> basically >> new ArrayList >> can be trasformed to >> invokedynamic ()Ljava/lang/Object; [ int.class ] >> >> likewise, any method call on ArrayList should be an invokedynamic. >> >> With that, at runtime, in the bootstrap method, you can ask the >> specializer to generate specialized class only when needed, >> i.e the first time a constructor is called. > In time, an approach similar to the one you describe will be used - in > the meantime, we'd like to get more experience with these features by > using an offline specializer that goes through the bytecode and spits > specialized versions of the classfiles. while I understand that you want to find the best class file format and how to verify it, how from that to specialize a class, etc, i think that wrestling with the Java classloading monster is as important and should be done sooner than later. >> >> >>>> >>>>> >>>>> Regarging comparisons - the first issue is that type-checking >>>>> support for comparisons involving 'any' type-variable is not there >>>>> yet - i.e. the compiler will reject it as of now. Once that's >>>>> allowed, you will be able to compare T with T but not T with int >>>>> (similarly as you cannot compare an ordinary type-variable with a >>>>> string). In other words, I don't believe equals() will ever be >>>>> generated - i.e. the compiler will always use if_acmpeq and the >>>>> likes, which will be tagged, eventually, in the bytecode. >>>> >>>> I was thinking about the opposite, >>>> void m(T t1, t t2) { >>>> return t1.equals(t2); >>>> } >>>> >>>> does this code should use if_icmpeq if T is specialized with T=int. >>> >>> The code above doesn't compile. It doesn't make sense (at least for >>> now) to speak about members of an 'any' type-variable, so there's no >>> equals in T. >> >> so practically there will be at least two codes by method, the one >> that takes an Object because you can do equals on it >> and the one that takes any that will use ==. > That's the status of the current (very early) prototype. Nothing is > set in stone at this point - but it seems like a stable design choice. I'm not saying it's bad, i think it's better than what i was thinking :) > > Maurizio R?mi From brian.goetz at oracle.com Thu Jul 24 19:05:14 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 24 Jul 2014 15:05:14 -0400 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D1528B.8050103@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D131F4.5080906@univ-mlv.fr> <53D135BC.8010406@oracle.com> <53D13BB6.2040404@univ-mlv.fr> <53D14350.7060204@oracle.com> <53D1528B.8050103@univ-mlv.fr> Message-ID: <21115752-335A-4737-A59D-4E9FAD7E2256@oracle.com> >>> >> In time, an approach similar to the one you describe will be used - in the meantime, we'd like to get more experience with these features by using an offline specializer that goes through the bytecode and spits specialized versions of the classfiles. > > while I understand that you want to find the best class file format and how to verify it, how from that to specialize a class, etc, > i think that wrestling with the Java classloading monster is as important and should be done sooner than later. Yes, it is on the list of monsters to wrestle with :) It?s a long list. Our approach will be iterative. We spent quite a bit of time at the whiteboard, now its time to code a little bit, and then we?ll iterate ? many more times! From john.r.rose at oracle.com Thu Jul 24 20:33:48 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 24 Jul 2014 13:33:48 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D10856.60006@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: On Jul 24, 2014, at 6:21 AM, Maurizio Cimadamore wrote: > In other words, I don't believe equals() will ever be generated - i.e. the compiler will always use if_acmpeq and the likes, which will be tagged, eventually, in the bytecode. For value types (according to the current "Infant Edition") we will be implementing a strong correspondence between the methods of a value type and the methods of its box type: > The automatically created box class will properly implement the interface, > bridging to the given `compareTo` method. A `vinvoke` instruction can also > directly invoke the `compareTo` method as written. I think it would be reasonable and useful to extend this correspondence to all of 'any' (and 'any & Comparable' etc). We can do this by fiat, saying that if a primitive (at least, a primitive type argument in a specialization instance) gets a method invocation against it, that invocation is performed on a boxed version of the primitive. Allowing .equals and .compareTo on 'any' will allow us to build container types (List, TreeMap) with 'any' keys. For now the designated box for a primitive (e.g., int) can be a wrapper (java.lang.Integer). In the real system, we have discussed building new box types for this purpose (java.lang.'int', etc.). (...Waving target type magic at it, of course, to dispel compatibility bogies.) ? John From john.r.rose at oracle.com Thu Jul 24 20:44:09 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 24 Jul 2014 13:44:09 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D131F4.5080906@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D131F4.5080906@univ-mlv.fr> Message-ID: On Jul 24, 2014, at 9:19 AM, Remi Forax wrote: > new if different of anewarray, i don't think you can specialize new. > anewarray is equivalent to getfield, the syntax use an internal name instead of a descriptor which is an historical glitch in my opinion FTR, here's a standing proposal to patch over that historical glitch (break glass in case of emergency): - If the string foo is a valid class name, then Lfoo; is a valid descriptor (existing rule) - If the string bar is a valid descriptor, then .bar is a valid class name (new rule) - But, L.foo; is never a valid descriptor (normality condition, excluding '.' from descriptors) If (which is not necessarily true) the dot only ever needs to appear in the leading position of a CONSTANT_Class string, then we can also consider (equivalently) introducing a new type CONSTANT_Signature and allow it to occur in some places CONSTANT_Class is valid today. In that case, the "leading dot" notation could still be useful when rendering descriptors as class name strings. ? John From john.r.rose at oracle.com Thu Jul 24 20:51:12 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 24 Jul 2014 13:51:12 -0700 Subject: Special ASM branches named valhalla In-Reply-To: <53D13CC9.3000002@univ-mlv.fr> References: <53D13CC9.3000002@univ-mlv.fr> Message-ID: On Jul 24, 2014, at 10:05 AM, Remi Forax wrote: > I've started to hack a version of ASM in order to be able to do the specialization at runtime. > http://websvn.ow2.org/listing.php?repname=asm&path=%2Fbranches%2FVALHALLA%2F > > Currently, it only supports the TypeVariableMap attribute (reader and writer) > and is fully backward compatible with ASM5 :) Here's a big cut I think we need in ASM: Structured names (CONSTANT_Signature?). The use of String to encode class names and method descriptors will not scale to unerased types. I suggest amending or repurposing asm.Type to carry tuples of constants (plus template string as "(L#;I)Q#;" to control top-level structure). The hardest part will be deprecating String as a carrier for descriptors and type names in the visitor APIs. ? John :-} From pbenedict at apache.org Thu Jul 24 20:55:56 2014 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 24 Jul 2014 15:55:56 -0500 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: On Thu, Jul 24, 2014 at 3:33 PM, John Rose wrote: > On Jul 24, 2014, at 6:21 AM, Maurizio Cimadamore < > maurizio.cimadamore at oracle.com> wrote: > > For now the designated box for a primitive (e.g., int) can be a wrapper > (java.lang.Integer). In the real system, we have discussed building new > box types for this purpose (java.lang.'int', etc.). (...Waving target type > magic at it, of course, to dispel compatibility bogies.) > > John, I'd like to hear more about that, if you're so inclined to share. It peeks my interest because new box types were part of my poor-man proposal on the platform-jep-discuss list. I was thinking the new types would be pure singletons while the current wrappers would continue to be prototypes. Additionally, if desired, both sets of wrappers could share a common interface for programming ease too. Is that at all similar to what you're internally discussing? Paul From john.r.rose at oracle.com Thu Jul 24 21:18:26 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 24 Jul 2014 14:18:26 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: On Jul 24, 2014, at 1:55 PM, Paul Benedict wrote: > I was thinking the new types would be pure singletons Absolutely pure singletons ( https://blogs.oracle.com/jrose/entry/fixnums_in_the_vm ) are tricky to implement, since you will need either uniquification logic or else pervasive type testing. I prefer to think in terms of normal object references with restricted "value safe" semantics and/or usage ( https://blogs.oracle.com/jrose/entry/value_types_in_the_vm "The Rules" ). You can have a good-enough set of rules, even where, by working hard enough, you can discover that two occurrences of '42' are in distinct boxes. It's "good-enough" if you'd have to break some rules of hygiene to observe the distinction. Absolutely hiding such distinctions has performance costs. FTR, my most recent discussion of values is here: https://blogs.oracle.com/jrose/entry/value_types_in_the_vm1 As you can see, in order to clarify the design and implementation of value types relative to the existing JVM, we are positing pairs of types, boxed and unboxed, with different bytecodes and verification rules. The unboxed form is indistinguishable from a pure singleton. The boxed form is compatible with java.lang.Object (and arbitrary interfaces), and for that reason has a few caveats about purity. ? John From brian.goetz at oracle.com Thu Jul 24 21:26:58 2014 From: brian.goetz at oracle.com (Brian Goetz) Date: Thu, 24 Jul 2014 17:26:58 -0400 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: One of the open questions is whether we can, and should, try to stretch things so the existing wrapper classes can be the box types for the primitives (or, alternately, how much contortion would be required to enable this, and how much we give up.) My personal gut feeling all along is that at some point, we?ll conclude that the existing wrappers are too hopelessly polluted, but I remain open-minded. When we know more we?ll share :) On Jul 24, 2014, at 4:55 PM, Paul Benedict wrote: > On Thu, Jul 24, 2014 at 3:33 PM, John Rose wrote: > >> On Jul 24, 2014, at 6:21 AM, Maurizio Cimadamore < >> maurizio.cimadamore at oracle.com> wrote: >> >> For now the designated box for a primitive (e.g., int) can be a wrapper >> (java.lang.Integer). In the real system, we have discussed building new >> box types for this purpose (java.lang.'int', etc.). (...Waving target type >> magic at it, of course, to dispel compatibility bogies.) >> >> > John, I'd like to hear more about that, if you're so inclined to share. It > peeks my interest because new box types were part of my poor-man proposal > on the platform-jep-discuss list. I was thinking the new types would be > pure singletons while the current wrappers would continue to be prototypes. > Additionally, if desired, both sets of wrappers could share a common > interface for programming ease too. Is that at all similar to what you're > internally discussing? > > Paul From forax at univ-mlv.fr Thu Jul 24 22:23:13 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 25 Jul 2014 00:23:13 +0200 Subject: Special ASM branches named valhalla In-Reply-To: References: <53D13CC9.3000002@univ-mlv.fr> Message-ID: <53D18751.9030203@univ-mlv.fr> On 07/24/2014 10:51 PM, John Rose wrote: > On Jul 24, 2014, at 10:05 AM, Remi Forax wrote: > >> I've started to hack a version of ASM in order to be able to do the specialization at runtime. >> http://websvn.ow2.org/listing.php?repname=asm&path=%2Fbranches%2FVALHALLA%2F >> >> Currently, it only supports the TypeVariableMap attribute (reader and writer) >> and is fully backward compatible with ASM5 :) > Here's a big cut I think we need in ASM: Structured names (CONSTANT_Signature?). > The use of String to encode class names and method descriptors will not scale to unerased types. I disagree with you that String will not scale because inside a class file, unerased types are just String inside a side table and by example if I want to change the name of a method, I should not need to fold and unfold an unerased type. I think, we should represent unerased class and unerased descriptor, as one unerased signature, the concatenation of the type argument of the class and the unerased descriptor. by example, class Foo { T t; void m() { this.t } } here this.t is translated to getfield Foo t Ljava/lang/Object; with an unerased signature T ( because this is typed Foo and T because the unerased type of t is T) > I suggest amending or repurposing asm.Type to carry tuples of constants (plus template string as "(L#;I)Q#;" to control top-level structure). > The hardest part will be deprecating String as a carrier for descriptors and type names in the visitor APIs. I think adding a supplementary String being either the unerased signature or null with a way to fold/unfold that signature should be enough. > > ? John :-} R?mi :) From john.r.rose at oracle.com Thu Jul 24 22:28:27 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 24 Jul 2014 15:28:27 -0700 Subject: Special ASM branches named valhalla In-Reply-To: <53D18751.9030203@univ-mlv.fr> References: <53D13CC9.3000002@univ-mlv.fr> <53D18751.9030203@univ-mlv.fr> Message-ID: <19DBA951-C947-4DE1-B521-9AB5BF86B74F@oracle.com> On Jul 24, 2014, at 3:23 PM, Remi Forax wrote: > I want to change the name of a method, > I should not need to fold and unfold an unerased type. I agree, which is why I think we should replace CONSTANT_Utf8 and/or CONSTANT_Class constants by structured CONSTANT_Signature constants. They can remain opaque and "all folded up" to most visitors. The net impact on constant pool parsing is probably positive, since the overall byte-size of the CP will go down due to structure sharing. ? John From forax at univ-mlv.fr Thu Jul 24 22:43:31 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 25 Jul 2014 00:43:31 +0200 Subject: Special ASM branches named valhalla In-Reply-To: <19DBA951-C947-4DE1-B521-9AB5BF86B74F@oracle.com> References: <53D13CC9.3000002@univ-mlv.fr> <53D18751.9030203@univ-mlv.fr> <19DBA951-C947-4DE1-B521-9AB5BF86B74F@oracle.com> Message-ID: <53D18C13.30500@univ-mlv.fr> On 07/25/2014 12:28 AM, John Rose wrote: > On Jul 24, 2014, at 3:23 PM, Remi Forax > wrote: > >> I want to change the name of a method, >> I should not need to fold and unfold an unerased type. > > I agree, which is why I think we should replace CONSTANT_Utf8 and/or > CONSTANT_Class constants by structured CONSTANT_Signature constants. > They can remain opaque and "all folded up" to most visitors. Ok, got it, you don't want any side table for the unerased signature, in that case I think that only the descriptor should be a CONSTANT_Signature. > The net impact on constant pool parsing is probably positive, since > the overall byte-size of the CP will go down due to structure sharing. yes. > > ? John R?mi From maurizio.cimadamore at oracle.com Thu Jul 24 23:48:28 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Fri, 25 Jul 2014 00:48:28 +0100 Subject: Special ASM branches named valhalla In-Reply-To: <53D18C13.30500@univ-mlv.fr> References: <53D13CC9.3000002@univ-mlv.fr> <53D18751.9030203@univ-mlv.fr> <19DBA951-C947-4DE1-B521-9AB5BF86B74F@oracle.com> <53D18C13.30500@univ-mlv.fr> Message-ID: <53D19B4C.4090401@oracle.com> On 24/07/14 23:43, Remi Forax wrote: > > On 07/25/2014 12:28 AM, John Rose wrote: >> On Jul 24, 2014, at 3:23 PM, Remi Forax > > wrote: >> >>> I want to change the name of a method, >>> I should not need to fold and unfold an unerased type. >> >> I agree, which is why I think we should replace CONSTANT_Utf8 and/or >> CONSTANT_Class constants by structured CONSTANT_Signature constants. >> They can remain opaque and "all folded up" to most visitors. > > Ok, got it, you don't want any side table for the unerased signature, > in that case I think that only the descriptor should be a > CONSTANT_Signature. > >> The net impact on constant pool parsing is probably positive, since >> the overall byte-size of the CP will go down due to structure sharing. > > yes. +1 When I worked on my reified JVM prototype, I used custom attributes to map unerased signatures in a structural way (see section 4.2.1 in [1]). The reuse is very good indeed - think of multiple instantiation of same generic type i.e. List, List - here you have that base type for List can be reused and both String and Integer are probably in the CP already, so that encoding both could, in most cases be done through in two very small entries consisting of 2 CP indexes each (one for the base type, one for the type parameter). If you then need List> and the likes, savings start be pile up considerably - i.e. only two indexes for that one too (given that both base type List and type-argument List already exist). [1] - http://amsdottorato.unibo.it/2476/ Maurizio > >> >> ? John > > R?mi > From forax at univ-mlv.fr Fri Jul 25 19:33:27 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Fri, 25 Jul 2014 21:33:27 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: <53D2B107.6090705@univ-mlv.fr> On 07/24/2014 10:33 PM, John Rose wrote: > On Jul 24, 2014, at 6:21 AM, Maurizio Cimadamore > > wrote: > >> In other words, I don't believe equals() will ever be generated - >> i.e. the compiler will always use if_acmpeq and the likes, which will >> be tagged, eventually, in the bytecode. > > For value types (according to the current "Infant Edition") we will be > implementing a strong correspondence between the methods of a value > type and the methods of its box type: Does it mean that the value type version can be seen as a specialization of the boxed type ? R?mi From john.r.rose at oracle.com Fri Jul 25 19:45:55 2014 From: john.r.rose at oracle.com (John Rose) Date: Fri, 25 Jul 2014 12:45:55 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D2B107.6090705@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <53D2B107.6090705@univ-mlv.fr> Message-ID: <31336086-C284-4BC4-85F5-42DBFBF3013B@oracle.com> On Jul 25, 2014, at 12:33 PM, Remi Forax wrote: > On 07/24/2014 10:33 PM, John Rose wrote: >> On Jul 24, 2014, at 6:21 AM, Maurizio Cimadamore wrote: >> >>> In other words, I don't believe equals() will ever be generated - i.e. the compiler will always use if_acmpeq and the likes, which will be tagged, eventually, in the bytecode. >> >> For value types (according to the current "Infant Edition") we will be implementing a strong correspondence between the methods of a value type and the methods of its box type: > > Does it mean that the value type version can be seen as a specialization of the boxed type ? I don't think so, because the boxed type is not more general than the value type. It is simply the canonical Object-compatible representation for the JVM. ? John P.S. Fun fact: Values, because they are not aliasable, can have varying representations in memory, subject only to fidelity (enough bits). This is one reason values (like primitives) are helpful for native-data integration; you can talk about tuples, complex numbers, etc., without caring how they are ordered, packed, etc., as long as the unique access path for their container knows how to break them out into registers. From maurizio.cimadamore at oracle.com Mon Jul 28 02:13:55 2014 From: maurizio.cimadamore at oracle.com (maurizio.cimadamore at oracle.com) Date: Mon, 28 Jul 2014 02:13:55 +0000 Subject: hg: valhalla/valhalla/langtools: Add support for missing opcodes in Code.codeWidth leading to javac crashes Message-ID: <201407280213.s6S2Duo2001693@aojmv0008> Changeset: 41bafbc4fe24 Author: mcimadamore Date: 2014-07-27 19:13 -0700 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/41bafbc4fe24 Add support for missing opcodes in Code.codeWidth leading to javac crashes ! src/share/classes/com/sun/tools/javac/jvm/Code.java From paul.govereau at oracle.com Mon Jul 28 10:03:58 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Mon, 28 Jul 2014 10:03:58 +0000 Subject: hg: valhalla/valhalla/langtools: Parser support for value-types. Message-ID: <201407281003.s6SA3wN5010665@aojmv0008> Changeset: 3e3c18441013 Author: pgovereau Date: 2014-07-28 06:01 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/3e3c18441013 Parser support for value-types. ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/comp/Check.java + src/share/classes/com/sun/tools/javac/comp/TransValues.java ! src/share/classes/com/sun/tools/javac/main/JavaCompiler.java ! src/share/classes/com/sun/tools/javac/parser/JavacParser.java ! src/share/classes/com/sun/tools/javac/parser/Tokens.java ! src/share/classes/com/sun/tools/javac/tree/JCTree.java ! src/share/classes/javax/lang/model/element/Modifier.java + test/tools/javac/valhalla/values/Point.java From paul.govereau at oracle.com Mon Jul 28 18:05:42 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Mon, 28 Jul 2014 18:05:42 +0000 Subject: hg: valhalla/valhalla/langtools: Classfile changes for value types. Message-ID: <201407281805.s6SI5i0Q026120@aojmv0008> Changeset: 6595bd6fbb7b Author: pgovereau Date: 2014-07-28 14:03 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/6595bd6fbb7b Classfile changes for value types. Values are marked with flag 0x100, note this is overloaded with the "native method" flag. ! src/share/classes/com/sun/tools/classfile/AccessFlags.java ! src/share/classes/com/sun/tools/javac/code/Flags.java ! src/share/classes/com/sun/tools/javac/jvm/ClassReader.java ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java + test/tools/javac/valhalla/values/CheckFlags.java From daniel.smith at oracle.com Mon Jul 28 19:53:03 2014 From: daniel.smith at oracle.com (Dan Smith) Date: Mon, 28 Jul 2014 13:53:03 -0600 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D10856.60006@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: FYI, I put together this table a few months ago when we were exploring the idea of specializing instructions. (I tried the with an inline table, and the mailing list didn't like that, so I'm re-sending with a URL.) http://cr.openjdk.java.net/~dlsmith/instructions.png Each column represents an abstract "specialize load (etc.) for variable i" instruction (encoded in the class file as the reference version (aload, etc.) with an accompanying "asterisk" that provides i). The rows provide the specialization output for the given specialization type. The comparison and array instructions are especially interesting. Note on byte widths: I've listed the max width of the specialized instructions, and padded the others to match. Exception: value type instructions would require 2 extra bytes for a pointer to the type name, barring some clever encoding tricks (except vnewarray, which already has room for this). If the t instructions were literally bytecodes, they would also need 1 extra byte (or more?) to encode the type parameter index, 'i'. If in the distant future we introduced another row to this table, we would be constrained by the amount of bytes we'd already reserved... Things I don't know much about that might change this analysis: 'wide', 'fcmpg'. (Final note: it probably goes without saying, but there are other things besides bytecodes that need to be specialized, too, and eventually we'll want to come up with a comprehensive list of those things.) ?Dan On Jul 24, 2014, at 7:21 AM, Maurizio Cimadamore wrote: > Hi Remi, > thanks for the comments. This is an initial prototype to get things going and unblock the work on the specializer. The current support will be enough to compile simple classes such as Box (in Brian's document). > > Said that, opcodes such as dup/pop can easily be added in the current code by adding more 'cases' to the filtering switch. > > areturn is there - but it's generated in a different code path - see Gen.visitReturn. > > For opcodes such as new and newarray, we need to have unerased expression types being saved by javac somewhere, so that was a bit beyond the scope of this patch. > > Regarging comparisons - the first issue is that type-checking support for comparisons involving 'any' type-variable is not there yet - i.e. the compiler will reject it as of now. Once that's allowed, you will be able to compare T with T but not T with int (similarly as you cannot compare an ordinary type-variable with a string). In other words, I don't believe equals() will ever be generated - i.e. the compiler will always use if_acmpeq and the likes, which will be tagged, eventually, in the bytecode. > > Maurizio > > On 24/07/14 13:25, Remi Forax wrote: >> Hi Maurizio, >> I think you have miss several opcodes that also need to be marked as any, >> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >> (I suppose than Object.equals will be used instead of if_acmpeq, if_acmpne) >> >> Maybe you want to treat anewarray like opcodes getfield/invoke* but >> in that case, either you need invokedynamic or a new bytecode ? >> >> cheers, >> R?mi >> >> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com wrote: >>> Changeset: bb57e20a33a4 >>> Author: mcimadamore >>> Date: 2014-07-24 12:22 +0100 >>> URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>> >>> Add support for tracking 'any'-related opcodes >>> *) Overhauled Items hierarchy (now field/methods have their own classes) >>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes back to the original (unerased) signature >>> >>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>> >> > From john.r.rose at oracle.com Mon Jul 28 21:10:59 2014 From: john.r.rose at oracle.com (John Rose) Date: Mon, 28 Jul 2014 14:10:59 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> On Jul 28, 2014, at 12:53 PM, Dan Smith wrote: > (Final note: it probably goes without saying, but there are other things besides bytecodes that need to be specialized, too, and eventually we'll want to come up with a comprehensive list of those things.) The 'J' and 'D' types are a pain point, since they require slot pairs. In the spirit of your 'nop' technique, I suggest allocating a slot-pair to each value of a specializable type. Treat the extra slot, if unused, as padding or a nop. In the case of method parameters you cannot preallocate padding, but it's simple to work around: Copy the incoming parameter to a local slot-pair. The JIT will make that stuff go away, just like nops. ? John From forax at univ-mlv.fr Mon Jul 28 21:33:53 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 28 Jul 2014 23:33:53 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <5F25B265-F568-47A0-B228-F56C3978CDFE@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5F25B265-F568-47A0-B228-F56C3978CDFE@oracle.com> Message-ID: <53D6C1C1.3040909@univ-mlv.fr> There is also something fun. You don't need to specialize for all primtive types but only one 32bits and one 64bits if the specializable code contains only bytecodes of the first 5 categories. R?mi On 07/28/2014 09:44 PM, Dan Smith wrote: > FYI, I put together this table a few months ago when we were exploring > the idea of specializing instructions. (Don't know if the mailing > list preserves formatting; if not, let me know and I'll try to > reproduce the table as text-only.) > > Each column represents an abstract "specialize load (etc.) for > variable i" instruction (encoded in the class file as the reference > version (aload, etc.) with an accompanying "asterisk" that provides > i). The rows provide the specialization output for the given > specialization type. The comparison and array instructions are > especially interesting. > > > > *tload* > > *t_load_* > > *tstore* > > *tstore_* > > *treturn* > > *if_tcmpeq* > > *if_tcmpneq* > > *tnewarray* > > *taload* > > *tastore* > > > *2 bytes* > > *1 bytes* > > *2 bytes* > > *1 byte* > > *1 byte* > > *4 bytes* > > *4 bytes* > > *3 bytes* > > *1 byte* > > *1 byte* > *reference* > > *aload* > > *aload_* > > *astore* > > *astore_* > > *areturn* > > *nop* > *if_acmpeq* > > *nop* > *if_acmpneq* > > *anewarray* > > *aaload* > > *aastore* > *value* > > *vload* > > *vload_* > > *vstore* > > *vstore_* > > *vreturn* > > *vcmp* > *ifeq* > > *vcmp* > *ifeq* > > *vnewarray* > > *vaload* > > *vastore* > *boolean* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 4* > *nop* > > *baload* > > *bastore* > *char* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 5* > *nop* > > *caload* > > *castore* > *byte* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 8* > *nop* > > *baload* > > *bastore* > *short* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 9* > *nop* > > *saload* > > *sastore* > *int* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 10* > *nop* > > *iaload* > > *iastore* > *long* > > *lload* > > *lload_* > > *lstore* > > *lstore_* > > *lreturn* > > *lcmp* > *ifeq* > > *lcmp* > *ifneq* > > *newarray 11* > *nop* > > *laload* > > *lastore* > *float* > > *fload* > > *fload_* > > *fstore* > > *fstore_* > > *freturn* > > *fcmpl* > *ifeq* > > *fcmpl* > *ifneq* > > *newarray 6* > *nop* > > *faload* > > *fastore* > *double* > > *dload* > > *dload_* > > *dstore* > > *dstore_* > > *dreturn* > > *dcmpl* > *ifeq* > > *dcmpl* > *ifneq* > > *newarray 7* > *nop* > > *daload* > > *dastore* > * > * > > > Note on byte widths: I've listed the max width of the specialized > instructions, and padded the others to match. Exception: value type > instructions would require 2 extra bytes for a pointer to the type > name, barring some clever encoding tricks (except vnewarray, which > already has room for this). If the t instructions were literally > bytecodes, they would also need 1 extra byte (or more?) to encode the > type parameter index, 'i'. If in the distant future we introduced > another row to this table, we would be constrained by the amount of > bytes we'd already reserved... > > Things I don't know much about that might change this analysis: > 'wide', 'fcmpg'. > > (Final note: it probably goes without saying, but there are other > things besides bytecodes that need to be specialized, too, and > eventually we'll want to come up with a comprehensive list of those > things.) > > ?Dan > > On Jul 24, 2014, at 7:21 AM, Maurizio Cimadamore > > wrote: > >> Hi Remi, >> thanks for the comments. This is an initial prototype to get things >> going and unblock the work on the specializer. The current support >> will be enough to compile simple classes such as Box (in Brian's >> document). >> >> Said that, opcodes such as dup/pop can easily be added in the current >> code by adding more 'cases' to the filtering switch. >> >> areturn is there - but it's generated in a different code path - see >> Gen.visitReturn. >> >> For opcodes such as new and newarray, we need to have unerased >> expression types being saved by javac somewhere, so that was a bit >> beyond the scope of this patch. >> >> Regarging comparisons - the first issue is that type-checking >> support for comparisons involving 'any' type-variable is not there >> yet - i.e. the compiler will reject it as of now. Once that's >> allowed, you will be able to compare T with T but not T with int >> (similarly as you cannot compare an ordinary type-variable with a >> string). In other words, I don't believe equals() will ever be >> generated - i.e. the compiler will always use if_acmpeq and >> the likes, which will be tagged, eventually, in the bytecode. >> >> Maurizio >> >> On 24/07/14 13:25, Remi Forax wrote: >>> Hi Maurizio, >>> I think you have miss several opcodes that also need to be marked as >>> any, >>> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >>> (I suppose than Object.equals will be used instead of if_acmpeq, >>> if_acmpne) >>> >>> Maybe you want to treat anewarray like opcodes getfield/invoke* but >>> in that case, either you need invokedynamic or a new bytecode ? >>> >>> cheers, >>> R?mi >>> >>> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com >>> wrote: >>>> Changeset: bb57e20a33a4 >>>> Author: mcimadamore >>>> Date: 2014-07-24 12:22 +0100 >>>> URL: >>>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>>> >>>> Add support for tracking 'any'-related opcodes >>>> *) Overhauled Items hierarchy (now field/methods have their own >>>> classes) >>>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >>>> back to the original (unerased) signature >>>> >>>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>>> >>> >> > From forax at univ-mlv.fr Mon Jul 28 21:39:57 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 28 Jul 2014 23:39:57 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <5F25B265-F568-47A0-B228-F56C3978CDFE@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5F25B265-F568-47A0-B228-F56C3978CDFE@oracle.com> Message-ID: <53D6C32D.6060807@univ-mlv.fr> Dan, nice table, better than the one I've on my backboard :) in your table, the nops for padding are sometimes inserted before the instruction and sometimes after the instruction, I think it should be always inserted after the instruction. About the array instructions (the t instructions), I agree that they should be encoded the same way than a getfield or a method call. R?mi On 07/28/2014 09:44 PM, Dan Smith wrote: > FYI, I put together this table a few months ago when we were exploring > the idea of specializing instructions. (Don't know if the mailing > list preserves formatting; if not, let me know and I'll try to > reproduce the table as text-only.) > > Each column represents an abstract "specialize load (etc.) for > variable i" instruction (encoded in the class file as the reference > version (aload, etc.) with an accompanying "asterisk" that provides > i). The rows provide the specialization output for the given > specialization type. The comparison and array instructions are > especially interesting. > > > > *tload* > > *t_load_* > > *tstore* > > *tstore_* > > *treturn* > > *if_tcmpeq* > > *if_tcmpneq* > > *tnewarray* > > *taload* > > *tastore* > > > *2 bytes* > > *1 bytes* > > *2 bytes* > > *1 byte* > > *1 byte* > > *4 bytes* > > *4 bytes* > > *3 bytes* > > *1 byte* > > *1 byte* > *reference* > > *aload* > > *aload_* > > *astore* > > *astore_* > > *areturn* > > *nop* > *if_acmpeq* > > *nop* > *if_acmpneq* > > *anewarray* > > *aaload* > > *aastore* > *value* > > *vload* > > *vload_* > > *vstore* > > *vstore_* > > *vreturn* > > *vcmp* > *ifeq* > > *vcmp* > *ifeq* > > *vnewarray* > > *vaload* > > *vastore* > *boolean* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 4* > *nop* > > *baload* > > *bastore* > *char* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 5* > *nop* > > *caload* > > *castore* > *byte* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 8* > *nop* > > *baload* > > *bastore* > *short* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 9* > *nop* > > *saload* > > *sastore* > *int* > > *iload* > > *iload_* > > *istore* > > *istore_* > > *ireturn* > > *nop* > *if_icmpeq* > > *nop* > *if_icmpneq* > > *newarray 10* > *nop* > > *iaload* > > *iastore* > *long* > > *lload* > > *lload_* > > *lstore* > > *lstore_* > > *lreturn* > > *lcmp* > *ifeq* > > *lcmp* > *ifneq* > > *newarray 11* > *nop* > > *laload* > > *lastore* > *float* > > *fload* > > *fload_* > > *fstore* > > *fstore_* > > *freturn* > > *fcmpl* > *ifeq* > > *fcmpl* > *ifneq* > > *newarray 6* > *nop* > > *faload* > > *fastore* > *double* > > *dload* > > *dload_* > > *dstore* > > *dstore_* > > *dreturn* > > *dcmpl* > *ifeq* > > *dcmpl* > *ifneq* > > *newarray 7* > *nop* > > *daload* > > *dastore* > * > * > > > Note on byte widths: I've listed the max width of the specialized > instructions, and padded the others to match. Exception: value type > instructions would require 2 extra bytes for a pointer to the type > name, barring some clever encoding tricks (except vnewarray, which > already has room for this). If the t instructions were literally > bytecodes, they would also need 1 extra byte (or more?) to encode the > type parameter index, 'i'. If in the distant future we introduced > another row to this table, we would be constrained by the amount of > bytes we'd already reserved... > > Things I don't know much about that might change this analysis: > 'wide', 'fcmpg'. > > (Final note: it probably goes without saying, but there are other > things besides bytecodes that need to be specialized, too, and > eventually we'll want to come up with a comprehensive list of those > things.) > > ?Dan > > On Jul 24, 2014, at 7:21 AM, Maurizio Cimadamore > > wrote: > >> Hi Remi, >> thanks for the comments. This is an initial prototype to get things >> going and unblock the work on the specializer. The current support >> will be enough to compile simple classes such as Box (in Brian's >> document). >> >> Said that, opcodes such as dup/pop can easily be added in the current >> code by adding more 'cases' to the filtering switch. >> >> areturn is there - but it's generated in a different code path - see >> Gen.visitReturn. >> >> For opcodes such as new and newarray, we need to have unerased >> expression types being saved by javac somewhere, so that was a bit >> beyond the scope of this patch. >> >> Regarging comparisons - the first issue is that type-checking >> support for comparisons involving 'any' type-variable is not there >> yet - i.e. the compiler will reject it as of now. Once that's >> allowed, you will be able to compare T with T but not T with int >> (similarly as you cannot compare an ordinary type-variable with a >> string). In other words, I don't believe equals() will ever be >> generated - i.e. the compiler will always use if_acmpeq and >> the likes, which will be tagged, eventually, in the bytecode. >> >> Maurizio >> >> On 24/07/14 13:25, Remi Forax wrote: >>> Hi Maurizio, >>> I think you have miss several opcodes that also need to be marked as >>> any, >>> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >>> (I suppose than Object.equals will be used instead of if_acmpeq, >>> if_acmpne) >>> >>> Maybe you want to treat anewarray like opcodes getfield/invoke* but >>> in that case, either you need invokedynamic or a new bytecode ? >>> >>> cheers, >>> R?mi >>> >>> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com >>> wrote: >>>> Changeset: bb57e20a33a4 >>>> Author: mcimadamore >>>> Date: 2014-07-24 12:22 +0100 >>>> URL: >>>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>>> >>>> Add support for tracking 'any'-related opcodes >>>> *) Overhauled Items hierarchy (now field/methods have their own >>>> classes) >>>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >>>> back to the original (unerased) signature >>>> >>>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>>> >>> >> > From forax at univ-mlv.fr Mon Jul 28 21:41:53 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 28 Jul 2014 23:41:53 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: <53D6C3A1.9010205@univ-mlv.fr> There is also something fun. You don't need to specialize for all primitive types but only one 32bits and one 64bits if the specializable code contains only bytecodes of the first 5 categories. R?mi On 07/28/2014 09:53 PM, Dan Smith wrote: > FYI, I put together this table a few months ago when we were exploring > the idea of specializing instructions. (I tried the with an inline > table, and the mailing list didn't like that, so I'm re-sending with a > URL.) > > http://cr.openjdk.java.net/~dlsmith/instructions.png > > > Each column represents an abstract "specialize load (etc.) for > variable i" instruction (encoded in the class file as the reference > version (aload, etc.) with an accompanying "asterisk" that provides > i). The rows provide the specialization output for the given > specialization type. The comparison and array instructions are > especially interesting. > > Note on byte widths: I've listed the max width of the specialized > instructions, and padded the others to match. Exception: value type > instructions would require 2 extra bytes for a pointer to the type > name, barring some clever encoding tricks (except vnewarray, which > already has room for this). If the t instructions were literally > bytecodes, they would also need 1 extra byte (or more?) to encode the > type parameter index, 'i'. If in the distant future we introduced > another row to this table, we would be constrained by the amount of > bytes we'd already reserved... > > Things I don't know much about that might change this analysis: > 'wide', 'fcmpg'. > > (Final note: it probably goes without saying, but there are other > things besides bytecodes that need to be specialized, too, and > eventually we'll want to come up with a comprehensive list of those > things.) > > ?Dan > > On Jul 24, 2014, at 7:21 AM, Maurizio Cimadamore > > wrote: > >> Hi Remi, >> thanks for the comments. This is an initial prototype to get things >> going and unblock the work on the specializer. The current support >> will be enough to compile simple classes such as Box (in Brian's >> document). >> >> Said that, opcodes such as dup/pop can easily be added in the current >> code by adding more 'cases' to the filtering switch. >> >> areturn is there - but it's generated in a different code path - see >> Gen.visitReturn. >> >> For opcodes such as new and newarray, we need to have unerased >> expression types being saved by javac somewhere, so that was a bit >> beyond the scope of this patch. >> >> Regarging comparisons - the first issue is that type-checking >> support for comparisons involving 'any' type-variable is not there >> yet - i.e. the compiler will reject it as of now. Once that's >> allowed, you will be able to compare T with T but not T with int >> (similarly as you cannot compare an ordinary type-variable with a >> string). In other words, I don't believe equals() will ever be >> generated - i.e. the compiler will always use if_acmpeq and >> the likes, which will be tagged, eventually, in the bytecode. >> >> Maurizio >> >> On 24/07/14 13:25, Remi Forax wrote: >>> Hi Maurizio, >>> I think you have miss several opcodes that also need to be marked as >>> any, >>> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >>> (I suppose than Object.equals will be used instead of if_acmpeq, >>> if_acmpne) >>> >>> Maybe you want to treat anewarray like opcodes getfield/invoke* but >>> in that case, either you need invokedynamic or a new bytecode ? >>> >>> cheers, >>> R?mi >>> >>> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com >>> wrote: >>>> Changeset: bb57e20a33a4 >>>> Author: mcimadamore >>>> Date: 2014-07-24 12:22 +0100 >>>> URL: >>>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>>> >>>> Add support for tracking 'any'-related opcodes >>>> *) Overhauled Items hierarchy (now field/methods have their own >>>> classes) >>>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >>>> back to the original (unerased) signature >>>> >>>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>>> >>> >> > From forax at univ-mlv.fr Mon Jul 28 21:42:27 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Mon, 28 Jul 2014 23:42:27 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> Message-ID: <53D6C3C3.5010806@univ-mlv.fr> Dan, nice table, better than the one I've on my backboard :) in your table, the nops for padding are sometimes inserted before the instruction and sometimes after the instruction, I think it should be always inserted after the instruction. About the array instructions (the t instructions), I agree that they should be encoded the same way than a getfield or a method call. R?mi On 07/28/2014 09:53 PM, Dan Smith wrote: > FYI, I put together this table a few months ago when we were exploring > the idea of specializing instructions. (I tried the with an inline > table, and the mailing list didn't like that, so I'm re-sending with a > URL.) > > http://cr.openjdk.java.net/~dlsmith/instructions.png > > > Each column represents an abstract "specialize load (etc.) for > variable i" instruction (encoded in the class file as the reference > version (aload, etc.) with an accompanying "asterisk" that provides > i). The rows provide the specialization output for the given > specialization type. The comparison and array instructions are > especially interesting. > > Note on byte widths: I've listed the max width of the specialized > instructions, and padded the others to match. Exception: value type > instructions would require 2 extra bytes for a pointer to the type > name, barring some clever encoding tricks (except vnewarray, which > already has room for this). If the t instructions were literally > bytecodes, they would also need 1 extra byte (or more?) to encode the > type parameter index, 'i'. If in the distant future we introduced > another row to this table, we would be constrained by the amount of > bytes we'd already reserved... > > Things I don't know much about that might change this analysis: > 'wide', 'fcmpg'. > > (Final note: it probably goes without saying, but there are other > things besides bytecodes that need to be specialized, too, and > eventually we'll want to come up with a comprehensive list of those > things.) > > ?Dan > > On Jul 24, 2014, at 7:21 AM, Maurizio Cimadamore > > wrote: > >> Hi Remi, >> thanks for the comments. This is an initial prototype to get things >> going and unblock the work on the specializer. The current support >> will be enough to compile simple classes such as Box (in Brian's >> document). >> >> Said that, opcodes such as dup/pop can easily be added in the current >> code by adding more 'cases' to the filtering switch. >> >> areturn is there - but it's generated in a different code path - see >> Gen.visitReturn. >> >> For opcodes such as new and newarray, we need to have unerased >> expression types being saved by javac somewhere, so that was a bit >> beyond the scope of this patch. >> >> Regarging comparisons - the first issue is that type-checking >> support for comparisons involving 'any' type-variable is not there >> yet - i.e. the compiler will reject it as of now. Once that's >> allowed, you will be able to compare T with T but not T with int >> (similarly as you cannot compare an ordinary type-variable with a >> string). In other words, I don't believe equals() will ever be >> generated - i.e. the compiler will always use if_acmpeq and >> the likes, which will be tagged, eventually, in the bytecode. >> >> Maurizio >> >> On 24/07/14 13:25, Remi Forax wrote: >>> Hi Maurizio, >>> I think you have miss several opcodes that also need to be marked as >>> any, >>> anewarray, areturn and i think dup, dup_x1, dup_x2 and pop >>> (I suppose than Object.equals will be used instead of if_acmpeq, >>> if_acmpne) >>> >>> Maybe you want to treat anewarray like opcodes getfield/invoke* but >>> in that case, either you need invokedynamic or a new bytecode ? >>> >>> cheers, >>> R?mi >>> >>> On 07/24/2014 01:26 PM, maurizio.cimadamore at oracle.com >>> wrote: >>>> Changeset: bb57e20a33a4 >>>> Author: mcimadamore >>>> Date: 2014-07-24 12:22 +0100 >>>> URL: >>>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/bb57e20a33a4 >>>> >>>> Add support for tracking 'any'-related opcodes >>>> *) Overhauled Items hierarchy (now field/methods have their own >>>> classes) >>>> *) Add AnyItem to model a bytecode item associated with 'any' variables >>>> *) Add new BytecodeMapping attribute to map 'any'-related opcodes >>>> back to the original (unerased) signature >>>> >>>> ! src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Code.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Gen.java >>>> ! src/share/classes/com/sun/tools/javac/jvm/Items.java >>>> ! src/share/classes/com/sun/tools/javac/util/Names.java >>>> >>> >> > From forax at univ-mlv.fr Mon Jul 28 22:09:56 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 29 Jul 2014 00:09:56 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> Message-ID: <53D6CA34.5010704@univ-mlv.fr> On 07/28/2014 11:10 PM, John Rose wrote: > On Jul 28, 2014, at 12:53 PM, Dan Smith wrote: > >> (Final note: it probably goes without saying, but there are other things besides bytecodes that need to be specialized, too, and eventually we'll want to come up with a comprehensive list of those things.) > The 'J' and 'D' types are a pain point, since they require slot pairs. > > In the spirit of your 'nop' technique, I suggest allocating a slot-pair to each value of a specializable type. Treat the extra slot, if unused, as padding or a nop. yes, very good idea, so maxlocals will be always the same value for the specializable code and all the specialized versions. I suppose that value types will not use several slots, otherwise if you change a value type to add a field, you will need to recompile all codes that use that value type. So either the interpreter will treat value type as objects or it will use a double indirection ? (the stack will contains an index to a stack location inside the current stack frame containing all the values of the value type). > > In the case of method parameters you cannot preallocate padding, but it's simple to work around: Copy the incoming parameter to a local slot-pair. > > The JIT will make that stuff go away, just like nops. > > ? John R?mi From john.r.rose at oracle.com Mon Jul 28 23:02:50 2014 From: john.r.rose at oracle.com (John Rose) Date: Mon, 28 Jul 2014 16:02:50 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D6CA34.5010704@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> Message-ID: <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> On Jul 28, 2014, at 3:09 PM, Remi Forax wrote: > I suppose that value types will not use several slots, otherwise if you change a value type to add a field, > you will need to recompile all codes that use that value type. > So either the interpreter will treat value type as objects or it will use a double indirection ? > (the stack will contains an index to a stack location inside the current stack frame containing all the values of the value type). It would be unworkable to have values occupy a variable amount of interpreter (JVM state) space. The only reasonable choice is 1 slot, which means (yes) some amount of slop and/or extra indirections. It also means that we ought to consider deprecating and removing the double-slot pattern in a suitable version of the JVM. ? John From forax at univ-mlv.fr Mon Jul 28 23:09:08 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 29 Jul 2014 01:09:08 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> Message-ID: <53D6D814.2020203@univ-mlv.fr> On 07/29/2014 01:02 AM, John Rose wrote: > On Jul 28, 2014, at 3:09 PM, Remi Forax > wrote: > >> I suppose that value types will not use several slots, otherwise if >> you change a value type to add a field, >> you will need to recompile all codes that use that value type. >> So either the interpreter will treat value type as objects or it will >> use a double indirection ? >> (the stack will contains an index to a stack location inside the >> current stack frame containing all the values of the value type). > > It would be unworkable to have values occupy a variable amount of > interpreter (JVM state) space. The only reasonable choice is 1 slot, > which means (yes) some amount of slop and/or extra indirections. > > It also means that we ought to consider deprecating and removing the > double-slot pattern in a suitable version of the JVM. yes, if you do local var slot renaming for value type when parsing the bytecode, you can use the same mechanism for double. > > ? John R?mi From john.r.rose at oracle.com Mon Jul 28 23:26:30 2014 From: john.r.rose at oracle.com (John Rose) Date: Mon, 28 Jul 2014 16:26:30 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D6D814.2020203@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> Message-ID: <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> On Jul 28, 2014, at 4:09 PM, Remi Forax wrote: > yes, if you do local var slot renaming for value type when parsing the bytecode, > you can use the same mechanism for double. Here is a concrete suggestion, to get rid of double slots completely in the setting of value types: Deprecate and remove [ld][a]?load* and [ld][a]?store* opcodes. In generated bytecodes, replace them by the corresponding v* opcodes (which would apply to long and double primitive values, as well as non-primitive, non-reference values). A few other opcodes (d2i, etc.) are kept as-is, but the slot-pair semantics are removed for them also. Later, repurpose those opcode points for other things. (This will free the d* or l* series of instructions for later use.) For compatibility, old class file versions would continue to use slot-pairs (and will not recognize v* bytecodes). New class file versions would refuse (at least some of) the [dl]* bytecodes. ? John From maurizio.cimadamore at oracle.com Mon Jul 28 23:40:21 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Mon, 28 Jul 2014 16:40:21 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> Message-ID: <53D6DF65.7030700@oracle.com> This looks promising - are you envisioning some kind of 'inference' in the VM in order to figure out the 'width' of the v* opcodes? That might be non-trivial as it would probably mean propagate type info from the local var table attribute? An alternative perhaps could be to accept an extra operand containing the 'width' (i.e. 1 for int, 2 for double/long, n for value types). Maurizio On 28/07/14 16:26, John Rose wrote: > On Jul 28, 2014, at 4:09 PM, Remi Forax wrote: > >> yes, if you do local var slot renaming for value type when parsing the bytecode, >> you can use the same mechanism for double. > Here is a concrete suggestion, to get rid of double slots completely in the setting of value types: > > Deprecate and remove [ld][a]?load* and [ld][a]?store* opcodes. > > In generated bytecodes, replace them by the corresponding v* opcodes (which would apply to long and double primitive values, as well as non-primitive, non-reference values). > > A few other opcodes (d2i, etc.) are kept as-is, but the slot-pair semantics are removed for them also. > > Later, repurpose those opcode points for other things. (This will free the d* or l* series of instructions for later use.) > > For compatibility, old class file versions would continue to use slot-pairs (and will not recognize v* bytecodes). > New class file versions would refuse (at least some of) the [dl]* bytecodes. > > ? John From john.r.rose at oracle.com Tue Jul 29 00:20:43 2014 From: john.r.rose at oracle.com (John Rose) Date: Mon, 28 Jul 2014 17:20:43 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D6DF65.7030700@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> <53D6DF65.7030700@oracle.com> Message-ID: On Jul 28, 2014, at 4:40 PM, Maurizio Cimadamore wrote: > This looks promising - are you envisioning some kind of 'inference' in the VM in order to figure out the 'width' of the v* opcodes? That might be non-trivial as it would probably mean propagate type info from the local var table attribute? An alternative perhaps could be to accept an extra operand containing the 'width' (i.e. 1 for int, 2 for double/long, n for value types). Which opcode would have an ambiguous input? Can't you always tell whether it is I, J, or some specific value type? ...Or any other type: Seems to me that, for correctness, we only need v* and none of the [ailfd]*, if we do very simple forward-only inference, like that supported by FrameMaps already. ? John From forax at univ-mlv.fr Tue Jul 29 00:26:58 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 29 Jul 2014 02:26:58 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D6DF65.7030700@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> <53D6DF65.7030700@oracle.com> Message-ID: <53D6EA52.3030106@univ-mlv.fr> On 07/29/2014 01:40 AM, Maurizio Cimadamore wrote: > This looks promising - are you envisioning some kind of 'inference' in > the VM in order to figure out the 'width' of the v* opcodes? That > might be non-trivial as it would probably mean propagate type info > from the local var table attribute? An alternative perhaps could be to > accept an extra operand containing the 'width' (i.e. 1 for int, 2 for > double/long, n for value types). > > Maurizio Hi Maurizio, you don't need a real inference for long/double etc or value type because there is no subtyping rule, you just have to calculate the type of all the local variables and the stack slots. The verifier must already do that in order to verify stackmap attribute (that are mandated since 1.7), so during the verification, we alreadly have all the information, you just need to tag the opcode with the type information. The drawback is that it will make the verifier code a little more complex so more prone to error that may lead to a security issue. R?mi > > On 28/07/14 16:26, John Rose wrote: >> On Jul 28, 2014, at 4:09 PM, Remi Forax wrote: >> >>> yes, if you do local var slot renaming for value type when parsing >>> the bytecode, >>> you can use the same mechanism for double. >> Here is a concrete suggestion, to get rid of double slots completely >> in the setting of value types: >> >> Deprecate and remove [ld][a]?load* and [ld][a]?store* opcodes. >> >> In generated bytecodes, replace them by the corresponding v* opcodes >> (which would apply to long and double primitive values, as well as >> non-primitive, non-reference values). >> >> A few other opcodes (d2i, etc.) are kept as-is, but the slot-pair >> semantics are removed for them also. >> >> Later, repurpose those opcode points for other things. (This will >> free the d* or l* series of instructions for later use.) >> >> For compatibility, old class file versions would continue to use >> slot-pairs (and will not recognize v* bytecodes). >> New class file versions would refuse (at least some of) the [dl]* >> bytecodes. >> >> ? John > From forax at univ-mlv.fr Tue Jul 29 00:28:12 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 29 Jul 2014 02:28:12 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> <53D6DF65.7030700@oracle.com> Message-ID: <53D6EA9C.5090407@univ-mlv.fr> On 07/29/2014 02:20 AM, John Rose wrote: > On Jul 28, 2014, at 4:40 PM, Maurizio Cimadamore > > wrote: > >> This looks promising - are you envisioning some kind of 'inference' >> in the VM in order to figure out the 'width' of the v* opcodes? That >> might be non-trivial as it would probably mean propagate type info >> from the local var table attribute? An alternative perhaps could be >> to accept an extra operand containing the 'width' (i.e. 1 for int, 2 >> for double/long, n for value types). > > Which opcode would have an ambiguous input? Can't you always tell > whether it is I, J, or some specific value type? > > ...Or any other type: Seems to me that, for correctness, we only need > v* and none of the [ailfd]*, if we do very simple forward-only > inference, like that supported by FrameMaps already. > > ? John yes. R?mi From forax at univ-mlv.fr Tue Jul 29 00:30:03 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Tue, 29 Jul 2014 02:30:03 +0200 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> Message-ID: <53D6EB0B.4000309@univ-mlv.fr> On 07/29/2014 01:26 AM, John Rose wrote: > On Jul 28, 2014, at 4:09 PM, Remi Forax > wrote: > >> yes, if you do local var slot renaming for value type when parsing >> the bytecode, >> you can use the same mechanism for double. > > Here is a concrete suggestion, to get rid of double slots completely > in the setting of value types: > > Deprecate and remove [ld][a]?load* and [ld][a]?store* opcodes. > > In generated bytecodes, replace them by the corresponding v* opcodes > (which would apply to long and double primitive values, as well as > non-primitive, non-reference values). > > A few other opcodes (d2i, etc.) are kept as-is, but the slot-pair > semantics are removed for them also. > > Later, repurpose those opcode points for other things. (This will > free the d* or l* series of instructions for later use.) > > For compatibility, old class file versions would continue to use > slot-pairs (and will not recognize v* bytecodes). > New class file versions would refuse (at least some of) the [dl]* > bytecodes. > > ? John I like this, it will make the specialization far easier :) R?mi From david.r.chase at oracle.com Tue Jul 29 08:06:20 2014 From: david.r.chase at oracle.com (David Chase) Date: Tue, 29 Jul 2014 04:06:20 -0400 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> <53D6DF65.7030700@oracle.com> Message-ID: On Jul 28, 2014, at 8:20 PM, John Rose wrote: > On Jul 28, 2014, at 4:40 PM, Maurizio Cimadamore wrote: > >> This looks promising - are you envisioning some kind of 'inference' in the VM in order to figure out the 'width' of the v* opcodes? That might be non-trivial as it would probably mean propagate type info from the local var table attribute? An alternative perhaps could be to accept an extra operand containing the 'width' (i.e. 1 for int, 2 for double/long, n for value types). > > Which opcode would have an ambiguous input? Can't you always tell whether it is I, J, or some specific value type? > > ...Or any other type: Seems to me that, for correctness, we only need v* and none of the [ailfd]*, if we do very simple forward-only inference, like that supported by FrameMaps already. Do you have any plans to get rid of the invokevirtual/invokeinterface distinction? Is it ever the case that both are legal but yield different results? I recall that the Fortress specializer had its own stupid little special case for dealing with this for different flavors of T?s replacement. David From maurizio.cimadamore at oracle.com Tue Jul 29 13:15:16 2014 From: maurizio.cimadamore at oracle.com (Maurizio Cimadamore) Date: Tue, 29 Jul 2014 06:15:16 -0700 Subject: hg: valhalla/valhalla/langtools: Add support for tracking 'any'-related opcodes In-Reply-To: <53D6EA52.3030106@univ-mlv.fr> References: <201407241126.s6OBQ2Uc016678@aojmv0008> <53D0FB28.4020404@univ-mlv.fr> <53D10856.60006@oracle.com> <5D4B14E2-8223-47C0-ADD9-C7AF1C563B08@oracle.com> <53D6CA34.5010704@univ-mlv.fr> <82E0D812-BA64-4A5F-8663-3E6B99BB4C36@oracle.com> <53D6D814.2020203@univ-mlv.fr> <7D12D2D5-ED35-4CCA-AFD4-B6B5C58153EB@oracle.com> <53D6DF65.7030700@oracle.com> <53D6EA52.3030106@univ-mlv.fr> Message-ID: <53D79E64.4030109@oracle.com> On 28/07/14 17:26, Remi Forax wrote: > > On 07/29/2014 01:40 AM, Maurizio Cimadamore wrote: >> This looks promising - are you envisioning some kind of 'inference' >> in the VM in order to figure out the 'width' of the v* opcodes? That >> might be non-trivial as it would probably mean propagate type info >> from the local var table attribute? An alternative perhaps could be >> to accept an extra operand containing the 'width' (i.e. 1 for int, 2 >> for double/long, n for value types). >> >> Maurizio > > Hi Maurizio, > you don't need a real inference for long/double etc or value type > because there is no subtyping rule, > you just have to calculate the type of all the local variables and the > stack slots. That is what I meant by 'inference' (sorry for the loose terminology here) > > The verifier must already do that in order to verify stackmap > attribute (that are mandated since 1.7), > so during the verification, we alreadly have all the information, you > just need to tag the opcode > with the type information. Yep - I agree that's the case. Maurizio > The drawback is that it will make the verifier code a little more > complex so more prone to error > that may lead to a security issue. > > R?mi > >> >> On 28/07/14 16:26, John Rose wrote: >>> On Jul 28, 2014, at 4:09 PM, Remi Forax wrote: >>> >>>> yes, if you do local var slot renaming for value type when parsing >>>> the bytecode, >>>> you can use the same mechanism for double. >>> Here is a concrete suggestion, to get rid of double slots completely >>> in the setting of value types: >>> >>> Deprecate and remove [ld][a]?load* and [ld][a]?store* opcodes. >>> >>> In generated bytecodes, replace them by the corresponding v* opcodes >>> (which would apply to long and double primitive values, as well as >>> non-primitive, non-reference values). >>> >>> A few other opcodes (d2i, etc.) are kept as-is, but the slot-pair >>> semantics are removed for them also. >>> >>> Later, repurpose those opcode points for other things. (This will >>> free the d* or l* series of instructions for later use.) >>> >>> For compatibility, old class file versions would continue to use >>> slot-pairs (and will not recognize v* bytecodes). >>> New class file versions would refuse (at least some of) the [dl]* >>> bytecodes. >>> >>> ? John >> > From paul.govereau at oracle.com Tue Jul 29 16:00:29 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Tue, 29 Jul 2014 16:00:29 +0000 Subject: hg: valhalla/valhalla/langtools: Values may not be declared as extending any other type. Message-ID: <201407291600.s6TG0TcK010462@aojmv0008> Changeset: e93623f99db8 Author: pgovereau Date: 2014-07-29 11:58 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/e93623f99db8 Values may not be declared as extending any other type. For the prototype, all values have supertype javax.lang.Value. ! make/build.properties ! src/share/classes/com/sun/tools/javac/comp/TransValues.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties + src/share/classes/javax/lang/Value.java + test/tools/javac/diags/examples/ValueExtends.java + test/tools/javac/valhalla/values/CheckExtends.java + test/tools/javac/valhalla/values/CheckExtends.out + test/tools/javac/valhalla/values/CheckSuper.java ! test/tools/javac/valhalla/values/Point.java From paul.govereau at oracle.com Tue Jul 29 16:03:15 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Tue, 29 Jul 2014 16:03:15 +0000 Subject: hg: valhalla/valhalla/langtools: minor fix to test case Message-ID: <201407291603.s6TG3GIW011262@aojmv0008> Changeset: d82f4e2e45aa Author: pgovereau Date: 2014-07-29 12:01 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/d82f4e2e45aa minor fix to test case ! test/tools/javac/valhalla/values/CheckSuper.java From paul.govereau at oracle.com Wed Jul 30 15:30:13 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Wed, 30 Jul 2014 15:30:13 +0000 Subject: hg: valhalla/valhalla/langtools: Check for synchronization methods called on values. Message-ID: <201407301530.s6UFUEa2009335@aojmv0008> Changeset: 20fb607c68ff Author: pgovereau Date: 2014-07-30 11:28 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/20fb607c68ff Check for synchronization methods called on values. ! src/share/classes/com/sun/tools/javac/comp/TransValues.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties + test/tools/javac/diags/examples/ValueSync.java + test/tools/javac/valhalla/values/CheckSync.java + test/tools/javac/valhalla/values/CheckSync.out From paul.govereau at oracle.com Wed Jul 30 21:07:38 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Wed, 30 Jul 2014 21:07:38 +0000 Subject: hg: valhalla/valhalla/langtools: Values types must be "all final". Message-ID: <201407302107.s6UL7cJe002161@aojmv0008> Changeset: ecff516ac894 Author: pgovereau Date: 2014-07-30 17:05 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/ecff516ac894 Values types must be "all final". ! src/share/classes/com/sun/tools/javac/comp/TransValues.java ! src/share/classes/com/sun/tools/javac/resources/compiler.properties + test/tools/javac/diags/examples/ValueFinal.java + test/tools/javac/valhalla/values/CheckFInal.out + test/tools/javac/valhalla/values/CheckFinal.java + test/tools/javac/valhalla/values/CheckFinal.out From pbenedict at apache.org Thu Jul 31 03:31:14 2014 From: pbenedict at apache.org (Paul Benedict) Date: Wed, 30 Jul 2014 22:31:14 -0500 Subject: hg: valhalla/valhalla/langtools: Values types must be "all final". In-Reply-To: <201407302107.s6UL7cJe002161@aojmv0008> References: <201407302107.s6UL7cJe002161@aojmv0008> Message-ID: I've been thinking about this. When it comes to how enums were speced, they didn't need "final" or "class" specifiers (yes, an enum literal can be a subclass but ignore that for now). So I am not sure all these explicit qualifiers are helpful for writing value classes too. Granted, this is the straw man implementation, but I would like to hear anyone's thoughts on just making it "public value ClassName". On Jul 30, 2014 5:08 PM, wrote: > Changeset: ecff516ac894 > Author: pgovereau > Date: 2014-07-30 17:05 -0400 > URL: > http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/ecff516ac894 > > Values types must be "all final". > > ! src/share/classes/com/sun/tools/javac/comp/TransValues.java > ! src/share/classes/com/sun/tools/javac/resources/compiler.properties > + test/tools/javac/diags/examples/ValueFinal.java > + test/tools/javac/valhalla/values/CheckFInal.out > + test/tools/javac/valhalla/values/CheckFinal.java > + test/tools/javac/valhalla/values/CheckFinal.out > > From rsteiger at ensemblesoft.net Thu Jul 31 04:19:33 2014 From: rsteiger at ensemblesoft.net (Richard Steiger) Date: Wed, 30 Jul 2014 21:19:33 -0700 Subject: hg: valhalla/valhalla/langtools: Values types must be "all final". In-Reply-To: References: <201407302107.s6UL7cJe002161@aojmv0008> Message-ID: <53D9C3D5.7070402@ensemblesoft.net> I'm new to this list, so may well have missed previous discussions about the rationale for the "Value types must be all final" pronouncement. While I'm not at all sure that value-type-finality is relevant to the following, I'd like to go on record stating that one of the more irritating aspects of the current enum semantics is the inability to extend an existing enum type with additional values. I appreciate that there might be numerous subtleties that would need to be addressed in making enums "not quite final", i.e. extensible in a limited way (no overrides, etc.), the boon to application developers and others seems to me to justify at least thinking-through the issues. On 7/30/2014 8:31 PM, Paul Benedict wrote: > I've been thinking about this. When it comes to how enums were speced, they > didn't need "final" or "class" specifiers (yes, an enum literal can be a > subclass but ignore that for now). So I am not sure all these explicit > qualifiers are helpful for writing value classes too. Granted, this is the > straw man implementation, but I would like to hear anyone's thoughts on > just making it "public value ClassName". > On Jul 30, 2014 5:08 PM, wrote: > >> Changeset: ecff516ac894 >> Author: pgovereau >> Date: 2014-07-30 17:05 -0400 >> URL: >> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/ecff516ac894 >> >> Values types must be "all final". >> >> ! src/share/classes/com/sun/tools/javac/comp/TransValues.java >> ! src/share/classes/com/sun/tools/javac/resources/compiler.properties >> + test/tools/javac/diags/examples/ValueFinal.java >> + test/tools/javac/valhalla/values/CheckFInal.out >> + test/tools/javac/valhalla/values/CheckFinal.java >> + test/tools/javac/valhalla/values/CheckFinal.out >> >> From pbenedict at apache.org Thu Jul 31 07:21:15 2014 From: pbenedict at apache.org (Paul Benedict) Date: Thu, 31 Jul 2014 02:21:15 -0500 Subject: hg: valhalla/valhalla/langtools: Values types must be "all final". In-Reply-To: <53D9C3D5.7070402@ensemblesoft.net> References: <201407302107.s6UL7cJe002161@aojmv0008> <53D9C3D5.7070402@ensemblesoft.net> Message-ID: Richard, it's off-topic but I'll say extending an enum makes no sense with polymorphism. An enum defines the world (so to speak) of values. You then can't allow subclasses to sneak in and change the world by introducing new values. On Jul 31, 2014 12:20 AM, "Richard Steiger" wrote: > I'm new to this list, so may well have missed previous discussions about > the rationale for the "Value types must be all final" pronouncement. > > While I'm not at all sure that value-type-finality is relevant to the > following, I'd like to go on record stating that one of the more irritating > aspects of the current enum semantics is the inability to extend an > existing enum type with additional values. I appreciate that there might > be numerous subtleties that would need to be addressed in making enums "not > quite final", i.e. extensible in a limited way (no overrides, etc.), the > boon to application developers and others seems to me to justify at least > thinking-through the issues. > > On 7/30/2014 8:31 PM, Paul Benedict wrote: > >> I've been thinking about this. When it comes to how enums were speced, >> they >> didn't need "final" or "class" specifiers (yes, an enum literal can be a >> subclass but ignore that for now). So I am not sure all these explicit >> qualifiers are helpful for writing value classes too. Granted, this is the >> straw man implementation, but I would like to hear anyone's thoughts on >> just making it "public value ClassName". >> On Jul 30, 2014 5:08 PM, wrote: >> >> Changeset: ecff516ac894 >>> Author: pgovereau >>> Date: 2014-07-30 17:05 -0400 >>> URL: >>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/ecff516ac894 >>> >>> Values types must be "all final". >>> >>> ! src/share/classes/com/sun/tools/javac/comp/TransValues.java >>> ! src/share/classes/com/sun/tools/javac/resources/compiler.properties >>> + test/tools/javac/diags/examples/ValueFinal.java >>> + test/tools/javac/valhalla/values/CheckFInal.out >>> + test/tools/javac/valhalla/values/CheckFinal.java >>> + test/tools/javac/valhalla/values/CheckFinal.out >>> >>> >>> > From paul.govereau at oracle.com Thu Jul 31 17:59:30 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Thu, 31 Jul 2014 17:59:30 +0000 Subject: hg: valhalla/valhalla/langtools: Values do not support identityHashCode. Message-ID: <201407311759.s6VHxUGv003970@aojmv0008> Changeset: 5aadec9243e1 Author: pgovereau Date: 2014-07-31 13:57 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/5aadec9243e1 Values do not support identityHashCode. ! src/share/classes/com/sun/tools/javac/comp/TransValues.java + test/tools/javac/valhalla/values/CheckIdentityHash.java + test/tools/javac/valhalla/values/CheckIdentityHash.out From paul.govereau at oracle.com Thu Jul 31 18:20:48 2014 From: paul.govereau at oracle.com (paul.govereau at oracle.com) Date: Thu, 31 Jul 2014 18:20:48 +0000 Subject: hg: valhalla/valhalla/langtools: May not define finalize or clone on value types. Message-ID: <201407311820.s6VIKmxT007846@aojmv0008> Changeset: e8328efaffed Author: pgovereau Date: 2014-07-31 14:18 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/e8328efaffed May not define finalize or clone on value types. ! src/share/classes/com/sun/tools/javac/comp/TransValues.java + test/tools/javac/valhalla/values/CheckClone.java + test/tools/javac/valhalla/values/CheckClone.out + test/tools/javac/valhalla/values/CheckFinalize.java + test/tools/javac/valhalla/values/CheckFinalize.out From timeroot.alex at gmail.com Thu Jul 31 19:43:09 2014 From: timeroot.alex at gmail.com (Alex M) Date: Thu, 31 Jul 2014 12:43:09 -0700 Subject: Difficulty of compareTo on floats/doubles Message-ID: Hi, this is my first time posting to any OpenJDK list, so if I'm doing something inappropriately let me know. :) I saw it being suggested that "any" could perhaps support .equals() and .compareTo(). equals() seems to make sense -- using "==" would compare identity on Objects and bits on primitives, while .equals() would become == for primitives and make the call on Objects. I'm not sure how plausibly the compareTo() idea will happen (given that would not make sense on Objects that don't implement Comparable, or on booleans), but one more potential problem with it is that floats/doubles have an undefined return value when comparing NaN's; they're neither less than, equal, not greater than any others. Unfortunately, or at least confusingly, the Float and Double classes offer a compareTo method which defines an order on NaNs based on their int bits (and which allows them to be equal to one another). This is also reflected in their equals() methods, such that various comparisons end up different. Float h=Float.NaN; float i=Float.NaN; System.out.println(h==i); //False System.out.println(h.equals(i));//True float inf=Float.POSITIVE_INFINITY; System.out.println(h Changeset: 532af9586535 Author: pgovereau Date: 2014-07-31 16:16 -0400 URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/532af9586535 values do not support == or != ! src/share/classes/com/sun/tools/javac/comp/TransValues.java ! test/tools/javac/valhalla/values/CheckClone.java + test/tools/javac/valhalla/values/CheckEquals.java + test/tools/javac/valhalla/values/CheckEquals.out From joe.darcy at oracle.com Thu Jul 31 20:29:10 2014 From: joe.darcy at oracle.com (Joe Darcy) Date: Thu, 31 Jul 2014 13:29:10 -0700 Subject: Difficulty of compareTo on floats/doubles In-Reply-To: References: Message-ID: <53DAA716.1060903@oracle.com> Hello, On 07/31/2014 12:43 PM, Alex M wrote: > Hi, this is my first time posting to any OpenJDK list, so if I'm doing > something inappropriately let me know. :) > > I saw it being suggested that "any" could perhaps support .equals() and > .compareTo(). equals() seems to make sense -- using "==" would compare > identity on Objects and bits on primitives, while .equals() would become == > for primitives and make the call on Objects. I'm not sure how plausibly the > compareTo() idea will happen (given that would not make sense on Objects > that don't implement Comparable, or on booleans), but one more potential > problem with it is that floats/doubles have an undefined return value when > comparing NaN's; they're neither less than, equal, not greater than any > others. While it may be surprising, the behavior is question is *not* undefined. The true / false behavior of ==, >, >=, <=, !=, is perfectly well defined by the IEEE 754 floating-point standard, behavior which is also found in the Java Language Specification. Nan is *unordered* with respect to other floating-point values. > > Unfortunately, or at least confusingly, the Float and Double classes offer > a compareTo method which defines an order on NaNs based on their int bits > (and which allows them to be equal to one another). This is also reflected > in their equals() methods, such that various comparisons end up different. The IEEE 754 == operation does not define a mathematical equivalence relation and the IEEE 754 < operation does not define a total order (besides NaN, there are signed zeros). The compareTo methods in Float and Double do impose an order on floating-point values where all NaN values are in the same equivalence class. -Joe > > > Float h=Float.NaN; > float i=Float.NaN; > > System.out.println(h==i); //False > System.out.println(h.equals(i));//True > > float inf=Float.POSITIVE_INFINITY; > > System.out.println(h System.out.println(h.compareTo(inf));//1 ("greater") > > These situations would need to be dealt with, even in the question of just > allowing equality comparison -- some situations, especially with an > implicit unboxing from a Float, will cause very strange problems. > > ~6 out of 5 statisticians say that the > number of statistics that either make > no sense or use ridiculous timescales > at all has dropped over 164% in the > last 5.62474396842 years. From john.r.rose at oracle.com Thu Jul 31 20:56:51 2014 From: john.r.rose at oracle.com (John Rose) Date: Thu, 31 Jul 2014 13:56:51 -0700 Subject: Difficulty of compareTo on floats/doubles In-Reply-To: References: Message-ID: <41A55225-89B2-4295-9679-44FA08CDBF31@oracle.com> On Jul 31, 2014, at 12:43 PM, Alex M wrote: > strange problems The essential point here is discussed in passing (see "simple relationals") in the value type prospectus. http://cr.openjdk.java.net/~jrose/values/values.html Yes, there are a lot of these strange problems that arise from forcing both primitives and objects under one type bound. More generally, the semantic oddities of "==" for float, double, and references make it very tricky indeed to apply "==" (and other operators, notably "+") to extremely polymorphic variables bounded by "any". Although it may not be practical in the end, my personal preference would be to deprecate or disallow operators on polymorphic variables, and express everything with method invocation. Method invocation on a non-reference value can be uniformly and simply defined by delegation to a boxed version of the value. If we define new box types (not impossible though difficult) we can take extra care to have the ad hoc polymorphism be as consistent as possible across the expanded range of types. We provide for such consistency already in the documentation of interfaces like Comparable and (as Joe explained) methods like Double.compareTo. Pre-existing boxes are probably not adequate to this. Null references may also require a "boxing" rule of some sort. See also the "vcmp" instruction in the value types prospectus. For value types we think we can make a compatible story of how to cope with "==" and ".equals": "==" is bitwise and ".equals" is a method call (possibly boxed, but the user cannot observe whether that happens). Bottom lines: Consistent ad hoc polymorphism is hard, especially when unifying legacy types. And see "vcmp" for bitwise semantics and extend it if necessary to primitives. But try hard to do most things in terms of methods, which is more flexible and explicit. ? John From forax at univ-mlv.fr Thu Jul 31 21:16:36 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 31 Jul 2014 23:16:36 +0200 Subject: hg: valhalla/valhalla/langtools: values do not support == or != In-Reply-To: <201407312018.s6VKIefh025127@aojmv0008> References: <201407312018.s6VKIefh025127@aojmv0008> Message-ID: <53DAB234.9040001@univ-mlv.fr> On 07/31/2014 10:18 PM, paul.govereau at oracle.com wrote: > Changeset: 532af9586535 > Author: pgovereau > Date: 2014-07-31 16:16 -0400 > URL: http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/532af9586535 > > values do not support == or != > > ! src/share/classes/com/sun/tools/javac/comp/TransValues.java > ! test/tools/javac/valhalla/values/CheckClone.java > + test/tools/javac/valhalla/values/CheckEquals.java > + test/tools/javac/valhalla/values/CheckEquals.out > Hi Paul, Are you sure about this one ? for me a == on a value type is allowed and emit a vcmp. R?mi From forax at univ-mlv.fr Thu Jul 31 21:40:33 2014 From: forax at univ-mlv.fr (Remi Forax) Date: Thu, 31 Jul 2014 23:40:33 +0200 Subject: hg: valhalla/valhalla/langtools: Values types must be "all final". In-Reply-To: <53D9C3D5.7070402@ensemblesoft.net> References: <201407302107.s6UL7cJe002161@aojmv0008> <53D9C3D5.7070402@ensemblesoft.net> Message-ID: <53DAB7D1.6040500@univ-mlv.fr> On 07/31/2014 06:19 AM, Richard Steiger wrote: > I'm new to this list, so may well have missed previous discussions > about the rationale for the "Value types must be all final" > pronouncement. > > While I'm not at all sure that value-type-finality is relevant to the > following, I'd like to go on record stating that one of the more > irritating aspects of the current enum semantics is the inability to > extend an existing enum type with additional values. I appreciate > that there might be numerous subtleties that would need to be > addressed in making enums "not quite final", i.e. extensible in a > limited way (no overrides, etc.), the boon to application developers > and others seems to me to justify at least thinking-through the issues. An enum enumerate all possible values thus you can not add a supplementary value by inheritance, unlike an interface which let you provide the implementation you want an enum is a not an open type but a closed type. From the design point of view, your problem is not to allow inheritance on enum but why you (or any of our fellow dev) have chosen to use an enum to represent something you want to extend i.e. an open type. In term of implementation having open enums is really hard, imagine that you have an enum Foo and two enums Bar and Baz that inherits from Foo, how the compiler is suppose to provide the ordinal value in that case (don't forget that Bar and Baz can be compiled separately) ? Trying to implement values() on an open enum is fun too. regards, R?mi > > On 7/30/2014 8:31 PM, Paul Benedict wrote: >> I've been thinking about this. When it comes to how enums were >> speced, they >> didn't need "final" or "class" specifiers (yes, an enum literal can be a >> subclass but ignore that for now). So I am not sure all these explicit >> qualifiers are helpful for writing value classes too. Granted, this >> is the >> straw man implementation, but I would like to hear anyone's thoughts on >> just making it "public value ClassName". >> On Jul 30, 2014 5:08 PM, wrote: >> >>> Changeset: ecff516ac894 >>> Author: pgovereau >>> Date: 2014-07-30 17:05 -0400 >>> URL: >>> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/ecff516ac894 >>> >>> Values types must be "all final". >>> >>> ! src/share/classes/com/sun/tools/javac/comp/TransValues.java >>> ! src/share/classes/com/sun/tools/javac/resources/compiler.properties >>> + test/tools/javac/diags/examples/ValueFinal.java >>> + test/tools/javac/valhalla/values/CheckFInal.out >>> + test/tools/javac/valhalla/values/CheckFinal.java >>> + test/tools/javac/valhalla/values/CheckFinal.out >>> >>> > From timeroot.alex at gmail.com Thu Jul 31 22:25:30 2014 From: timeroot.alex at gmail.com (Alex Meiburg) Date: Thu, 31 Jul 2014 15:25:30 -0700 Subject: Difficulty of compareTo on floats/doubles In-Reply-To: <41A55225-89B2-4295-9679-44FA08CDBF31@oracle.com> References: <41A55225-89B2-4295-9679-44FA08CDBF31@oracle.com> Message-ID: So the current state is that for... primitives: == and != performs bitwise comparison equals() doesn't exist Objects: == and != perform identity testing equals() is a method that can be overriden With regards to equality on value types, it sounds like the main proposals are... values, option 1: == performs elementwise testing, via "vcmp" equals() defaults to vcmp, but can be overridden values, option 2: == and equals() perform elementwise testing, via "vcmp". equals() is final. values, option 3: == doesn't exist on the unboxed values. equals() defaults to vcmp, but can be overridden And then on polymorphic generics that could be primitive, value, or Object, there are generics, option 1: == will perform just as == would on the corresponding Object/primitive/value equals() will call the method on the Object/value, and Float.equals()/Integer.equals()/etc. on primitives generics, option 2: == is an identity check on Objects, and equals() on primitive/value equals() will call the method on the Object/value, and Float.equals()/Integer.equals()/etc. on primitives generics, option 3: == doesn't exist on polymorphic variables equals() will call the method on the Object/value, and Float.equals()/Integer.equals()/etc. on primitives and the situation you're describing is option 1 for values, and option 3 for generics. (The numbering is arbitrary, of course). Would allowing equals to be overridden be worth it, on value types? Although certainly mostly a lack of imagination, I feel like the use cases to redefine it would be limited -- and there is one other thing to consider, of how the equality check should recurse onto objects members of the value type. For instance, given a situation like class Bar { int f; public Bar(int f){ this.f = f; } public boolean equals(Object that){ return (that instanceof Bar) && ((Bar)that).f == f; } } final __ByValue class Foo { int x; Bar y; } Foo a = __MakeValue(5, new Bar(10)); Foo b = __MakeValue(5, new Bar(10)); System.out.println(a == b); System.our.println(a.equals(b)); Then my first expectation would be for them to print "false" and "true", respectively. That is, if "==" were a vcmp, it would check x's for integer bitwise equality, and the reference y the same way. The "equals" method I would intuitively expect to do similar bitwise comparison on x, but a call to y.equals(). This follows along with the general thought process that when I'm treating it like an int I want a quick and "dumb" equality check, whereas the more class-seeming equals() call is something I can expect to be a "deep" check. I may be alone in expecting this. :) But if others agree that it would be a logical behavior, then I would support defining == to be recursive == on reference fields, and equals() to be a (probably final) method doing the above. -- Alexander Meiburg 2014-07-31 13:56 GMT-07:00 John Rose : > On Jul 31, 2014, at 12:43 PM, Alex M wrote: > > > strange problems > > The essential point here is discussed in passing (see "simple > relationals") in the value type prospectus. > http://cr.openjdk.java.net/~jrose/values/values.html > > Yes, there are a lot of these strange problems that arise from forcing > both primitives and objects under one type bound. > > More generally, the semantic oddities of "==" for float, double, and > references make it very tricky indeed to apply "==" (and other operators, > notably "+") to extremely polymorphic variables bounded by "any". > > Although it may not be practical in the end, my personal preference would > be to deprecate or disallow operators on polymorphic variables, and express > everything with method invocation. > > Method invocation on a non-reference value can be uniformly and simply > defined by delegation to a boxed version of the value. If we define new box > types (not impossible though difficult) we can take extra care to have the > ad hoc polymorphism be as consistent as possible across the expanded range > of types. We provide for such consistency already in the documentation of > interfaces like Comparable and (as Joe explained) methods like > Double.compareTo. > > Pre-existing boxes are probably not adequate to this. Null references may > also require a "boxing" rule of some sort. > > See also the "vcmp" instruction in the value types prospectus. For value > types we think we can make a compatible story of how to cope with "==" and > ".equals": "==" is bitwise and ".equals" is a method call (possibly boxed, > but the user cannot observe whether that happens). > > Bottom lines: Consistent ad hoc polymorphism is hard, especially when > unifying legacy types. And see "vcmp" for bitwise semantics and extend it > if necessary to primitives. But try hard to do most things in terms of > methods, which is more flexible and explicit. > > ? John From paul.govereau at oracle.com Thu Jul 31 23:23:40 2014 From: paul.govereau at oracle.com (Paul Govereau) Date: Thu, 31 Jul 2014 19:23:40 -0400 Subject: hg: valhalla/valhalla/langtools: values do not support == or != In-Reply-To: <53DAB234.9040001@univ-mlv.fr> References: <201407312018.s6VKIefh025127@aojmv0008> <53DAB234.9040001@univ-mlv.fr> Message-ID: <53DACFFC.50603@oracle.com> You are right, the prototype is almost certainly wrong on this count. My interpretation of the specification: http://cr.openjdk.java.net/~jrose/values/values-0.html is that, either: v1 == v2 ==> v1.equals(v2) or v1 == v2 ==> forall (f1,f2) in fields of (v1,v2), f1 == f2 The first one could be implemented trivially in javac, but it raises some questions about when the programmer/compiler is required to implement equals. The second one could also be implemented in javac, or at the JVM level by expanding the definition, or perhaps with vcmp. We don't have a vcmp yet, so this last option will have to wait a bit. At the moment, == would generate an acmp, which will work fine, but is hiding a compatibility issue. I thought making == illegal was a better choice until we decide what should happen. Of course, it is easy to change if we prefer an acmp for now. Paul On 07/31/2014 05:16 PM, Remi Forax wrote: > > On 07/31/2014 10:18 PM, paul.govereau at oracle.com wrote: >> Changeset: 532af9586535 >> Author: pgovereau >> Date: 2014-07-31 16:16 -0400 >> URL: >> http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/532af9586535 >> >> values do not support == or != >> >> ! src/share/classes/com/sun/tools/javac/comp/TransValues.java >> ! test/tools/javac/valhalla/values/CheckClone.java >> + test/tools/javac/valhalla/values/CheckEquals.java >> + test/tools/javac/valhalla/values/CheckEquals.out >> > > Hi Paul, > Are you sure about this one ? > for me a == on a value type is allowed and emit a vcmp. > > R?mi >