From attila at hontvari.net Thu May 4 18:16:08 2017 From: attila at hontvari.net (=?UTF-8?Q?Hontv=c3=a1ri_Attila?=) Date: Thu, 04 May 2017 18:16:08 -0000 Subject: Fwd: JEP 303: Intrinsics for the LDC and INVOKEDYNAMIC Instructions In-Reply-To: References: Message-ID: <85aa86a0-f606-6ee3-9836-d8f70da1ec0f@hontvari.net> And using the const modifier will indicate clearly that the variable is a compile time constant, not requiring people to check the right side of the assignment to see if it is a constant expression. But as I can understand this, these "constants" don't really have to be constants at compile-time. By using ConstantDynamic, they only have to be constant at runtime. javac could generate condy bootstrap methods for each 'const' variable, it would eliminate the need for Constable types. So people can use the well-known, shorter, more readable Class/MethodHandle/etc. instead of the Constable objects. So this class: public class A { public void m() { const MethodType mtype = methodType(void.class); const MethodHandle mh = MethodHandles.lookup().findVirtual(A.class, "m", mtype); mh.invoke(new A()); } } Could be compiled to something like this: public class A { Constant Pool: #11: ConstantDynamic // the constant for variable "mtype" BootstrapMethod: A::$bsm0 #12: ConstantDynamic // the constant for variable "mh" BootstrapMethod: A::$bsm1 public void m() { (#12).invoke(new A()); // the reference to 'mh' is replaced with ldc of constant #12 } private static MethodType $bsm0(Lookup lookup, String name, Class type) { return methodType(void.class); } private static MethodHandle $bsm1(Lookup lookup, String name, Class type) { return MethodHandles.lookup().findVirtual(A.class, "m", (#11)); // the reference to 'mtype' is replaced with ldc of constant #11 } } In this example, the compiler: 1. creates two condy CP-item for the const variables (#11 for 'mtype', #12 for 'mh') 2. creates the bootstrap methods for them ('$bsm0' for 'mtype', '$bsm1' for 'mh') 3. replaces all references to the const variables with a simple ldc of the referred variable's CP-item (replace loading 'mh' variable with loading constant #12 in the last line of the 'm' method, and replace loading 'mtype' variable with loading constant #11 in the end of the newly generated $bsm1) The two CP-items/BSMs may be collapsed a single CP-item/BSM because the first variable is only used in the value expression of the constant variable 'mh', but I don't see a big benefit from it. 2017-04-26 23:46 keltez?ssel, Brian Goetz ?rta: > The following was received through the valhalla-spec-comments mailbox. > > > -------- Forwarded Message -------- > Subject: JEP 303: Intrinsics for the LDC and INVOKEDYNAMIC > Instructions > Date: Wed, 26 Apr 2017 23:24:40 +0200 > From: Jeremy Barrow > To: valhalla-spec-comments at openjdk.java.net > > > > I'll preface this with: > I know that making a language construct for this has already been set > as an > explicit non-goal. > If you're 100% set on that, then you can probably skip this email, but if > you're interested in the opinions of some random who had a free > afternoon, > then read on. > > For the same reason that collection literals are a bad idea within the > language; compiler intrinsics are a bad idea within the library. > > Assuming a class gets added to the standard library, how would other > languages react to that? > Are they going to have to implement some support for it, or instead > explain > to their userbase that some portion of the library is redundant, more > so if > the language already supports language level intrinsics. > > This would be the perfect time to finally use "const". > > const MethodType type = ...; > > (Side-note: this might start dipping into ConstantDynamic (condyn) > territory, but bear with me.) > > The idea would allow the programmer to declare a field or a local > variable > with the const modifier. > When the programmer does this, it should be treated as a compile time > constant. > > As such, it doesn't make sense to be able to be able to declare a const > field, as a static final const field. > This might affect readability, and should probably be reviewed, but > semantically, it makes sense. > If the field/variable is used in a non-const context, then it should be > treated as if it was written there. (Excluding some types, such as > strings, > classes, etc) > > Because it's a compile time constant, it raises some questions: > > > Should the source code contain something that won't be present in the > final > runtime class? > > I think it makes sense, as it's not the only thing that java can omit > from > the runtime class. > Annotations can have a non-runtime retention, so I don't think the > concept > is a shock to java programmers, and arguably, a field/local variable with > const is easier to spot than a non-runtime annotation (because you > have to > inspect the annotation's class). > > I was originally going to also suggest maybe having support for const > methods as well, and variables and parameters can only be const, etc, > but I > think that's far too much for this simple API, and would play very well > into condyn's implementation. > > > Should the compiler be intrinsically aware of the type, or be able to be > made aware? (Intrinsic types or some way to communicate to the > compiler how > to convert a type into a constant) > > This is dangerously close to condyn, but I felt the need to bring it up > just to show how well the two could go together. > > With this API, I think, initially, intrinsic types are perfect. > Higher level types that can be known to the compiler, such as MethodType, > Class, String, are more or less perfect for it. > > > Now, the main problem: > You can't declare a method with those constants without an intrinsic > type, > or if you could, it might not be too readable. > That being said, I may have overlooked a nice way to declare methods with > constants. > > The first solution that came to mind was representing MethodHandle as a > const. > Currently, there's no explicit creation mechanism, outside of the Lookup > system itself, for obvious reasons. > > Should there be a const factory method for MethodHandles, that can only > accept const parameters? > > We have method references, could we use them? > > I spent some time thinking about this, and it almost always boiled > down to > an intrinsic class. > As even if we can define a MethodHandle in a const manner, we still > have to > deal with the compiler needing to be aware of the point where it needs to > emit the invokedynamic instruction. > > In effect, const is a way to define the constants, not the instructions. > > I think that was the shortcoming, and having something at the language > level for bytecode specific instructions is a potentially toxic idea. > > Now, all that being said, and the final result is in more or less the > exact > same position as before, I have suggested using const. > Which means we can declare new semantics. > > What if we could define classes that _have_ to be entirely constant? > What if we could attach a @Retention to it, or define a > RetentionPolicy for > it? > This means the JVM could toss the class, much like it does annotations. > > This could make the way for a whole section of programmable constants > later > on with condyn. > > I will admit, this got much bigger than I originally planned, but > hopefully, I got across my point, if I failed, I at least hope that I > gave > someone a good idea to work it. > > Thanks for reading this wall of text. > >