JEP 303 and ConstantDynamic

Hontvári Attila attila at
Thu Aug 3 12:57:10 UTC 2017

(I wrote this idea to valhalla-spec-comments some months ago, but that 
list doesn't seems to handle e-mails, so I'm trying now valhalla-dev as 
the JEP states that it is the discussion list. )

The JEP proposes the many new intrinsic types (XYConstant, 
BootstrapSpecifier, etc.), but I don't see any advantages over the 
standard (Class/MethodHandle/etc. ) classes, instead they have many 
disadvantages: not very readable, these new classes will be here 
forever, and the compiler needs to be aware of them and evaluate the 
Constable factory methods at compile-time. So I assume the JEP only 
proposes intrinsic types because we can't use the standard existing 
classes, because they hold the lookup information that is not available 
at compile-time.

But as I understand this, the data of the instances of the intrinsic 
types don't have to be known at compile-time; they only have to be known 
and constant at run-time. So the evaluation of the constant expressions 
can be delayed until the first use, using CONSTANT_Dynamic. In my 
proposal, the user can define explicit constant expressions, which the 
javac extracts to a condy BSM. In addition, any class could be used in 
the expressions, not only the predefined Constables.

My proposal:

 1. The user should be able to mark an expression with some keyword like
    Example: MethodHandle mh = __CONDY
    MethodHandles.lookup().findVirtual(X.class, etc.);
 2. Javac would extract the marked expression into an ad-hoc condy BSM.
 3. In the original place of the that expression, javac puts an LDC.
 4. For an Instrinsics.* method, the user must use a __CONDY expression.
 5. The programmer can use such __CONDY expressions for any other
    purposes too (see my example at the end of the email).
 6. An alternative proposal for the first point is to pass a lambda
    expression to __CONDY:
    Example: MethodHandle mh = __CONDY((lookup) ->
    lookup.findVirtual(Y.class, etc.));

For example, here is a thread-safe counter using the JEP 303 compiler 
public class Counter303 {

     private int i;

     public void increment() {
VarHandle VH = Intrinsics.ldc(VarHandleConstant.ofField(
                 ClassConstant.of("LCounter303;"), "i", 
         VH.getAndAdd(this, i);

In this class, the compiler behaves specially with Intrinsics::ldc, 
VarHandleConstant, ClassConstant: that is many complications in the 
language for such a small feature. Also, a programmer needs to check for 
@TrackableConstant for all methods that he wants to use as an argument 
for an Intrinsics.* method.

According to my proposal, this class would be written as:
public class CounterCondy {

     private int i;

     public void increment() {
         VarHandle VH = __CONDY 
MethodHandles.lookup().findVarHandle(CounterCondy.class, "i", int.class);
         VH.getAndAdd(this, i);

And the compiler would translate it to:
public class CounterCondy {

     private int i;

     public void increment() {
         [ldc CONSTANT_Dynamic CounterCondy.$bsm1].getAndAdd(this, i);

     private static VarHandle $bsm1(Lookup lookup, String name, Class 
type) {
         return MethodHandles.lookup().findVarHandle(CounterCondy.class, 
"i", int.class)

Another negative about the 'Constable' approach is that the list of the 
javac-supported Constable subclasses is not extensible. But with my 
proposal, this feature can be applied to any type.
For example, compiling a regex pattern is slow. So sometimes people 
cache the Pattern objects using static final fields:
     private static final Pattern DIGITS = Pattern.compile("[0-9]");
     public String[] m(String in) {
         return DIGITS.split(in);

But this could be expressible using an __CONDY expression according to 
my proposal, which is shorter, lazy, and makes the intention more clear:
     public String[] m(String in) {
         return (__CONDY Pattern.compile("[0-9]")).split(in);


More information about the valhalla-dev mailing list