New draft JEP: intrinsics for String::format and Objects::hash (among others)

Jorn Vernee jbvernee at xs4all.nl
Mon Oct 22 22:38:50 UTC 2018


This is an interesting step! It's something I have been thinking about 
lately to solve a similar problem. The problem being that a call site of 
a method might have additional information and I'd like to be able to 
pass on that information to a bootstrap to create and then use a 
specialization for that particular call site. A 'per call site 
specialization' if you will.

I'm interested to know what else you have to say about this subject.

One of the ideas I'd arrived at myself was to have some kind of 
annotation that specifies some bootstrap method for the specialization 
e.g.:

```
@Specializable(boostrap="myBootstrap") // you get the idea
int countDigits(String maybeConstant) {...}

static Callsite myBootstrap(Lookup l, String name, MethodType 
callsiteType, ArgInfo args) {
     if(args.isConstant(0)) {
         String s = (String) args.getConstantValue(0);
         return <specialization>
     }

     return <fallback>
}
```

Which I hope is also more friendly to user-space since the behavior of 
the bootstrap method is deterministic, you could say that whatever the 
bootstrap method returns is part of the intended behavior, but I haven't 
really thought about the spec implications that much there.

One other notion is that invokedynamic is just _one_ way to do the 
specialization. Maybe specialization could also be (re-)done after 
inlining/profiling, which could help when the annotated method is 
'hiding' behind an interface:

```
interface MyInterface {
     int countDigits(String maybeConstant);
}

class MyClass implements MyInterface {
     @Override
     @Specializable(...)
     int countDigits(String s) {...}
}
```

Where after inlining/profiling you might determine a certain call site 
always uses `MyClass`, and while the static type of the receiver is 
`MyInterface`, you could still do the specialization for the monomorphic 
callsite.

The use case I'm thinking of is generating a unique implementation for a 
user-defined interface, where we're currently re-computing varargs calls 
as fixed-arity for every invocation [1]. It would be nice to be able to 
specify some kind of per call site specialization mechanism in the 
generated backing implementation, so that eventually the varargs call 
will fall-over to a specialized version that only has to be re-computed 
as fixed-arity once.

Jorn

[1] : 
http://hg.openjdk.java.net/panama/dev/file/a43735f1fe86/src/java.base/share/classes/jdk/internal/foreign/invokers/VarargsInvoker.java#l62

Brian Goetz schreef op 2018-10-22 21:45:
> For those of you following the saga of improved constant folding,
> which includes JEPs 334 and 303 (see
> https://www.youtube.com/watch?v=iSEjlLFCS3E), another installment of
> the story ...
> 
>     https://bugs.openjdk.java.net/browse/JDK-8205637
> 
> While JEP 303 provides intrinsics for pseudo-methods (ldc,
> invokedynamic) whose semantics will be spelled out in the JLS, this
> JEP provides for more ad-hoc transformation of method invocations to
> LDC/indy, and outlines the initial candidate for this treatment
> String::format and Objects::hash.  (It does not rely on the constant
> folding and propagation that JEP 303 relies on, and so can be
> delivered before those are.)  The initial scope is deliberately
> limited; it can be expanded later.
> 
> We're working on some performance numbers that will provide the
> context on why we chose these particular methods -- these will be
> added to the JEP when ready.


More information about the amber-dev mailing list