JDK-8203252 : JEP 334: JVM Constants API
  • Type: JEP
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Priority: P3
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 12
  • Submitted: 2018-05-15
  • Updated: 2019-02-06
  • Resolved: 2019-01-26
Related Reports
Blocks :  
CSR :  
Relates :  
Sub Tasks
JDK-8202030 :  
JDK-8210031 :  
JDK-8214723 :  
JDK-8215300 :  
JDK-8215360 :  
JDK-8215510 :  

Introduce an API to model nominal descriptions of key class-file and run-time artifacts, in particular constants that are loadable from the constant pool.


Every Java class file has a [constant pool](https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-4.html#jvms-4.4) which stores the operands for bytecode instructions in the class. Broadly speaking, entries in the constant pool describe either run-time artifacts such as classes and methods, or simple values such as strings and integers. All these entries are known as _loadable constants_ because they may serve as operands for the `ldc` instruction ("[load constant](https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-6.html#jvms-6.5.ldc)"). They may also appear in the static argument list of a bootstrap method for the `invokedynamic` instruction. Executing an `ldc` or `invokedynamic` instruction causes the loadable constant to be resolved into a ���live��� value of a standard Java type such as `Class`, `String`, or `int`.

Programs which manipulate `class` files need to model bytecode instructions, and in turn loadable constants. However, using the standard Java types to model loadable constants is inadequate. It may be acceptable for a loadable constant that describes a string (a `CONSTANT_String_info` entry), since producing a "live" `String` object is straightforward, but it is problematic for a loadable constant that describes a class (a `CONSTANT_Class_info` entry), because producing a "live" `Class` object relies on the correctness and consistency of class loading. Unfortunately, class loading has many environmental dependencies and failure modes: the desired class does not exist or may not be accessible to the requester; the result of class loading varies with context; loading classes has side-effects; and sometimes class loading may not be possible at all (such as when the classes being described do not yet exist or are otherwise not loadable, as in during compilation of those same classes, or during `jlink`-time transformation).

Consequently, programs which deal with loadable constants would be simpler if they could manipulate classes and methods, and less well-known artifacts such as method handles and dynamically-computed constants, in a purely nominal, symbolic form:

- Bytecode parsing and generation libraries must describe classes and method handles in symbolic form. Without a standard mechanism, they must resort to ad-hoc mechanisms, whether descriptor types such as ASM's `Handle`, or tuples of strings (method owner, method name, method descriptor), or ad-hoc (and error-prone) encodings of these into a single string.

- Bootstraps for `invokedynamic` that operate by spinning bytecode (such as `LambdaMetafactory`) would be simpler if they could work in a symbolic domain rather than with "live" classes and method handles.

- Compilers and offline transformers (such as `jlink` plugins) need to describe classes and members for classes that cannot be loaded into the running VM. Compiler plugins (such as annotation processors) similarly need to describe program elements in symbolic terms.

These kinds of libraries and tools would all benefit from having a single, standard way to describe loadable constants.


We define a family of value-based symbolic reference (JVMS 5.1) types, in the new package `java.lang.invoke.constant`, capable of describing each kind of loadable constant. A symbolic reference describes a loadable constant in purely nominal form, separate from class loading or accessibility context. Some classes can act as their own symbolic references (e.g., `String`); for linkable constants we define a family of symbolic reference types (`ClassDesc`, `MethodTypeDesc`, `MethodHandleDesc`, and `DynamicConstantDesc`) that contain the nominal information to describe these constants.

A draft snapshot of the API specification can be found [here](http://cr.openjdk.java.net/~vromero/8210031/javadoc.21/overview-summary.html), and more information on its relationship with the features in [JEP 303][303] can be found in this [companion document](http://cr.openjdk.java.net/~briangoetz/amber/constables.html).


This JEP was originally a sub-feature of [JEP 303 (Intrinsics for the LDC and INVOKEDYNAMIC Instructions)][303].  JEP 303 now depends upon this JEP.

[303]: http://openjdk.java.net/jeps/303

References webrev: http://cr.openjdk.java.net/~vromero/8210031/webrev.14/ javadoc: http://cr.openjdk.java.net/~vromero/8210031/javadoc.21/overview-summary.html specdiff: http://cr.openjdk.java.net/~vromero/8210031/specdiff.11/overview-summary.html

Note: several review comments from CSR still outstanding, will address those soon.

Follow on work, currently blocked by symbolic-mode BSMs

link to the current webrev: http://cr.openjdk.java.net/~vromero/constant.api/webrev.04/constants.api.patch

[~mr]: added.

Given that this work is already pretty far along, please add links to the draft Javadoc and to your ���constables��� note.