Convert dynamic proxies to hidden classes. Modifies the serialization of
proxies (requires change in "Java Object Serialization Specification"). Makes
the proxies hidden in stack traces. Removes duplicate logic in proxy building.
The main compatibility changes and their rationales are:
1. Modification to the serialization specification: In the "An instance of the
class is allocated... The contents restored appropriately" section, I propose
explicitly state that handling of proxies are unspecified as to allow
implementation freedom, though I've seen deliberate attempts for proxies to
implement interfaces with `readResolve` in order to control their serialization
behavior.
- This is for the existing generated constructor accessor is bytecode-based,
which cannot refer to hidden classes.
- An alternative is to preserve the behavior, where the serialization
constructor calls `invokespecial` on the closest serializable superclass'
no-arg constructor, like in #1830 by @DasBrain.
- My rationale against preservation is such super calls are unsafe and
should be discouraged in the long term. Calling the existing constructor with a
dummy argument, as in my implementation, would be more safe.
2. The disappearance of proxies in stack traces.
- Same behavior exists in lambda expressions: For instance, in `((Runnable)
() -> { throw new Error(); }).run();`, the `run` method, implemented by the
lambda, will not appear in the stack trace, and isn't too problematic.
A summary of the rest of the changes:
1. Merged the two passes of determining module and package of the proxy into
one. This reduced a lot of code and allowed anchor class (for hidden class
creation) selection be done together as well.
2. Exposed internal API for obtaining a full-privileged lookup to the rest of
`java.base`. This API is intended for implementation of legacy (pre
`MethodHandles.Lookup`) caller sensitive public APIs so they don't need more
complex tricks to obtain proper permissions as lookups.
3. Implements [8229959](https://bugs.openjdk.java.net/browse/JDK-8229959):
passes methods computed by proxy generator as class data to the hidden proxy
class to reduce generated proxy class size and improve performance.
In addition, since this change is somewhat large, should we keep the old proxy
generator as well and have it toggled through a command-line flag (like the old
v49 proxy generator or the old reflection implementation)?
Please feel free to comment or review. This change definitely requires a CSR,
but I have yet to determine what specifications should be changed.
-------------
Commit messages:
- Change proxy serialization to work with hidden classes (require spec update)
- Formatting
- Move to hidden class and methods in class data
- Implement anchors and remove proxyClassLookup factory
Changes: https://git.openjdk.java.net/jdk/pull/8278/files
Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=8278&range=00
Issue: https://bugs.openjdk.java.net/browse/JDK-8242888
Stats: 400 lines in 6 files changed: 122 ins; 222 del; 56 mod
Patch: https://git.openjdk.java.net/jdk/pull/8278.diff
Fetch: git fetch https://git.openjdk.java.net/jdk pull/8278/head:pull/8278
PR: https://git.openjdk.java.net/jdk/pull/8278