Constable interface should die
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
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.
- 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 !
More information about the amber-spec-observers