Constable interface should die

Brian Goetz brian.goetz at oracle.com
Fri Jan 12 17:22:34 UTC 2018


And the next iteration of the loop I think lands in a more comfortable 
place.

Constable did indeed die, to be renamed to SymbolicRef.  A SymbolicRef, 
is, well, a symbolic reference for some classfile or platform entity, 
including constants, but also possibly including annotations, classfile 
attributes, indy bootstrap specifiers, or other constructs.

Most symbolic references have a live object analogue; ClassRef 
corresponds to a Class, MethodTypeRef corresponds to a MethodType.

Some symbolic references are their own live object; this is true for 
String, Integer, Float, Long, and Double.

Constable was then reborn to mean something else -- something that is 
constant-able -- i.e., a live object that can be naturally represented 
in the constant pool.  This includes String and friends from above, as 
well as Class, MethodType, and MethodHandle -- as well as anything that 
knows how to represent itself in the constant pool with condy, like var 
handles or enum constants.

So:
  - Constable -- represents a live object that also knows how to 
construct a symbolic reference for itself.  Constructing a symbolic 
reference is a partial function; not all method handles can be 
represented in the constant pool directly, just the direct kind (for now).
  - SymbolicRef -- a symbolic (purely nominal) descriptor for some 
object.  These can be resolved reflectively or can be intrinsified into 
the constant pool.  Symbolic references also implement Constable, so you 
can explicitly store a symbolic ref in the CP (with condy).
  - SymbolicRef.OfSelf -- for the types that act as their own symbolic ref.




On 9/22/2017 11:14 AM, Brian Goetz wrote:
> So, to close the loop here ...
>
> Based on these comments, we went through three more rounds of API 
> design, and ... ended up in a pretty similar place to where we 
> started.  First we tried a more formal separation between "Constable" 
> and "ConstantPoolEntry."  Then we tried a CP-entry-centric approach.  
> And what that brought us back to was, that the central abstraction 
> here is the symbolic references -- that this isn't only about 
> intrinsification.  (If it were, then the comments regarding 
> macro-systems would be spot-on.)  So the current draft brings the 
> symbolic references front and center -- and leaves intrinsification 
> and constant pool entries deliberately in the background.
>
> On 9/2/2017 10:51 AM, Remi Forax wrote:
>> Brian ask me to explain my concerns about the Constable interface.
>>
>> The whole constant folding story is like a macro system, it's a 
>> limited macro system, but still a macro system.
>> I've developed several macro systems, all have limitations, some 
>> limitation that i have introduced voluntarily, some that have appear 
>> after being being used, all the macro systems have always evolved 
>> after the first release.
>> So the first lesson of designing a macro system seems to be, because 
>> it will evolve, it should provide the minimal API so it can be 
>> refactored easily.
>>
>> In the case of constant-folding mechanism, it's not a mechanism that 
>> target end users but JDK maintainers, so end users should not be able 
>> to see the implementation of such mecanism.
>> It's my main concern with the Constable interface, it's a public 
>> visible type with a public visible API.
>>
>> We have already introduced in the past a mechanism that requires a 
>> specific interaction between the user code, the JDK and the compiler, 
>> it's the polymorphic methods signature and it was solved by using a 
>> private annotation.
>>
>> I think constant folding should use the same trick. Mark constant 
>> foldable type with a hidden annotation (@Constable ?) and mark 
>> methods (private) that can be called by the compiler with another 
>> hidden annotation (@TrackableConstant ?) and i will be happy.
>>
>> Compared to using an interface, there is a loss of discover-ability 
>> from the end user, but their is no loss of compiler checking because 
>> the compiler can check if a type is annotated by an annotation the 
>> same way it can check if it implements an interface.
>>
>> Now, we can discuss if @Constable should be a public annotation or 
>> not because once a type can be constant folded, removing the 
>> annotation is a non backward compatible change. So having the 
>> @Constable public is perhaps better than having to have a sentence in 
>> the middle of the javadoc saying that this is a constant foladable type.
>>
>> Note that constant folding things is also a form of serialization, 
>> the first Java serialization API have made that mistake to make the 
>> implementation of the part that serialize each object too visible. I 
>> think we can do better here.
>> You can also think that like Serializable, Constable could be an 
>> empty interface and ldc will take a Constable. But int 
>> constant-foldable and i do not see why it should be boxed to an 
>> Integer to becomes Constable (The full implication of that is that 
>> ldc should be a method with a polymorphic signature but we are moving 
>> in that direction anyway).
>>
>> Long live to @Constable !
>>
>> regards,
>> Rémi
>>
>



More information about the amber-spec-experts mailing list