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

Brian Goetz brian.goetz at
Tue Oct 23 00:24:07 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.

There are several tricks / sources sources of information one might use to select an alternate translation (which can be combined arbitrarily):

 - Type information.  Here, you use information about the shape of the call to “sharpen” the call site.  This applies most readily with varargs methods, like … String::format.  At every call site, the “descriptor” of the call is constant; translations can take advantage of this.  (The work on indifying string concatenation is an example of this, though (at least in Java) the plus operator is not strictly a “method call”.)

 - Constancy information.  Here, you take advantage of knowing that some of the arguments (including the receiver) are compile-time constants.  JEP 303 pushes at the extreme end of this, where it has both a richer notion of constant, and applies its treatment only to calls where _all_ arguments are constant.  However, sometimes partial constancy is still highly effective; in most calls to String::format, the format string is a constant, and we can mine quite a lot of that.  (More generally, we could attempt to do partial application of code to constant arguments.)  

 - Strength reduction.  Here, you observe that the user is calling a “more powerful” method than is needed.  For example, suppose you have two methods:

    Object eval(String program) { return eval(compile(program)); }
    Object eval(CompiledProgram p) { … }

We can intrinsify calls to the former, when the input string is a constant, by linking to an indy site that does the compile() step at link time and binds the resulting CompiledProgram to eval, and links to that.  (This game can be played for the String methods that take regexes encoded as strings, rather than Pattern, to avoid the redundant recomputation of the Pattern.)  

So there’s lots of fruit that can be picked just in common JDK methods.  In fact, the hardest thing to do is not go overboard with a cool new hammer like this.  

> One other notion is that invokedynamic is just _one_ way to do the specialization.

Yes; simple alternates include reducing to a constant (replacing with LDC) or redirecting to another method (say with some permutation of the arguments.)  But there’s a slippery slope here, labeled “But I Just Want Compiler Macros”.  Not going there. 

> 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.

Varargs is a good example of “today’s problems come from yesterday’s solutions.”  In 2002, the array encoding for varargs seemed clever; now it is recognized as a persistent source of performance and security bugs.  Targeted intrinsics should help for the worst offenders (e.g., String::format.)  But yes, this mechanism should be able to match to specialized implementations quite easily. 

A more interesting direction is methods that _have no actual body_, but for which calls are redirected to an indy bootstrap.  This would allow libraries to expose method-like APIs, but with the ability to generate at runtime only the code that is actually needed.  I think that’s really what you’re looking for.  Its not something we’re planning to do as part of this JEP, but it’s not too far afield.

More information about the amber-dev mailing list