Provide the `Lookup::defineHiddenClassWithClassData` API that allows live objects be shared between a hidden class and other classes. A hidden class can load these live objects as dynamically-computed constants via this API.
Specdiff http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8230501/specdiff/overview-summary.html With this class data support and hidden classes, `sun.misc.Unsafe::defineAnonymousClass` will be deprecated for removal. Existing libraries should replace their calls to `sun.misc.Unsafe::defineAnonymousClass` with `Lookup::defineHiddenClass` or `Lookup::defineHiddenClassWithClassData`. This patch also updates the implementation of lambda meta factory and `MemoryAccessVarHandleGenerator` to use class data. No performance difference observed in the jdk.incubator.foreign microbenchmarks. A side note: `MemoryAccessVarHandleGenerator` is removed in the upcoming integration of JDK-8254162 but it helps validating the class data support. Background ---------- This is an enhancement following up JEP 371: Hidden Classes w.r.t. "Constant-pool patching" in the "Risks and Assumption" section. A VM-anonymous class can be defined with its constant-pool entries already resolved to concrete values. This allows critical constants to be shared between a VM-anonymous class and the language runtime that defines it, and between multiple VM-anonymous classes. For example, a language runtime will often have `MethodHandle` objects in its address space that would be useful to newly-defined VM-anonymous classes. Instead of the runtime serializing the objects to constant-pool entries in VM-anonymous classes and then generating bytecode in those classes to laboriously `ldc` the entries, the runtime can simply supply `Unsafe::defineAnonymousClass` with references to its live objects. The relevant constant-pool entries in the newly-defined VM-anonymous class are pre-linked to those objects, improving performance and reducing footprint. In addition, this allows VM-anonymous classes to refer to each other: Constant-pool entries in a class file are based on names. They thus cannot refer to nameless VM-anonymous classes. A language runtime can, however, easily track the live Class objects for its VM-anonymous classes and supply them to `Unsafe::defineAnonymousClass`, thus pre-linking the new class's constant pool entries to other VM-anonymous classes. This extends the hidden classes to allow live objects to be injected in a hidden class and loaded them via condy. Details ------- A new `Lookup::defineHiddenClassWithClassData` API takes additional `classData` argument compared to `Lookup::defineHiddenClass`. Class data can be method handles, lookup objects, arbitrary user objects or collections of all of the above. This method behaves as if calling `Lookup::defineHiddenClass` to define a hidden class with a private static unnamed field that is initialized with `classData` at the first instruction of the class initializer. `MethodHandles::classData(Lookup lookup, String name, Class<?> type)` is a bootstrap method to load the class data of the given lookup's lookup class. The hidden class will be initialized when `classData` method is called if the hidden class has not been initialized. For a class data containing more than one single element, libraries can create their convenience method to load a single live object via condy. We can reconsider if such a convenience method is needed in the future. Frameworks sometimes want to dynamically create a hidden class (HC) and add it it the lookup class nest and have HC to carry secrets hidden from that nest. In this case, frameworks should not to use private static finals (in the HCs they spin) to hold secrets because a nestmate of HC may obtain access to such a private static final and observe the framework's secret. It should use condy. In addition, we need to differentiate if a lookup object is created from the original lookup class or created from teleporting e.g. `Lookup::in` and `MethodHandles::privateLookupIn`. This proposes to add a new `ORIGINAL` bit that is only set if the lookup object is created by `MethodHandles::lookup` or by bootstrap method invocation. The operations only apply to a Lookup object with original access are: - create method handles for caller-sensitve methods - obtain class data associated with the lookup class No change to `Lookup::hasFullPrivilegeAccess` and `Lookup::toString` which ignores the ORIGINAL bit. Compatibility Risks ------------------- `Lookup::lookupModes` includes a new `ORIGINAL` bit. Most lookup operations ignore this original bit except creating method handles for caller-sensitive methods that expects the lookup from the original lookup class. Existing code compares the return value of `lookupModes` to be a fixed value may be impacted. However existing client has no need to expect a fixed value of lookup modes. The incompatibility risk of this spec change is low. ------------- Commit messages: - fix incorrect merge - more clean up - merge - Keep classDataAt package-private - Merge branch 'master' of https://github.com/openjdk/jdk into class-data - MethodHandles::hasFullPrivilegeAccess and Lookup::toString ignores ORIGINAL bit - revert some test changes - Merge branch 'master' of https://github.com/openjdk/jdk into class-data - Add ORIGINAL access - Merge branch 'master' of https://github.com/openjdk/jdk into class-data - ... and 5 more: https://git.openjdk.java.net/jdk/compare/2e19026d...5a3e29ba Changes: https://git.openjdk.java.net/jdk/pull/1171/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1171&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8230501 Stats: 970 lines in 16 files changed: 778 ins; 80 del; 112 mod Patch: https://git.openjdk.java.net/jdk/pull/1171.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1171/head:pull/1171 PR: https://git.openjdk.java.net/jdk/pull/1171