JDK-8229959 : Convert proxy class to use constant dynamic
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang:reflect
  • Affected Version: 14
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-08-21
  • Updated: 2024-06-13
  • Resolved: 2024-06-05
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 23
23 b26Fixed
Related Reports
Relates :  
Relates :  
Description
Remi's suggestion: (see https://mail.openjdk.java.net/pipermail/core-libs-dev/2019-August/061923.html )

Proxy class computes all declared methods and stores them as static final fields.  It can replace these static field initialization with constant dynamic.

The idea is that a ldc on a constant dynamic with bootstrap method that takes a MethodHandle as parameter (as boostrap argument) can return the corresponding Method by using Lookup.revealDirect + reflectAs.
Comments
Changeset: d85b0ca5 Author: Adam Sotona <asotona@openjdk.org> Date: 2024-06-05 15:33:03 +0000 URL: https://git.openjdk.org/jdk/commit/d85b0ca5cdc1820a886c46bf555b2051fed7f167
05-06-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/19410 Date: 2024-05-27 09:01:36 +0000
28-05-2024

Now, reading through proxy code again, a few remarks: 1. Currently, the proxy builder determines module and package in two passes. Imo we should merge it into the module pass, and make it return a record (pojo) of module, package, and the full-privileged anchor lookup (obtained from the package-private interface class or the injected anchor class) 2. To obtain lookup to the package-private interface, we may expand JavaLangInvokeAccess for such functionality (makes sense, as we've expanded Reflect Access for calling Proxy.invokeDefault to fix MethodHandleProxies.asInterfaceInstance in 8280377) 3. The proxy cache will store both Constructor and the full-privileged lookup of the proxy class, obtained when spinning the hidden proxy class with the full-privileged anchor lookup. The proxy's lookup will be used to invoke default methods, and the Lookup accessor from 8159746 may be nuked as well. 4. Since we are now declaring the proxy as a hidden class, we can pass the method objects as class data like in your patch. Thoughts on this plan?
17-04-2022

You can. See my prototype. https://gist.github.com/DasBrain/37855876743fed7828c7690603aa3039#file-proxygenerator-java-L571
16-04-2022

Hmm, can you have a bootstrap method with the class of the constant itself? I doubt it, for I tried such an implementation and apparently it's an invalid bootstrap method.
16-04-2022

I once created a prototype - it uses a private method inside the generated proxy as bootstrap method. Discussion on core-libs here: https://mail.openjdk.java.net/pipermail/core-libs-dev/2019-November/063595.html There were 2 problems with that approach: * As you did discover, the SecurityManager can break stuff. (Good riddance once it is gone). The most likely candidate to break because of this is `MethodHandleProxies.asInterfaceInstance`. I left some info about this here: https://mail.openjdk.java.net/pipermail/core-libs-dev/2020-June/066938.html * It did not really improve performance. The next thing I did try was to use hidden classes for proxies. See also JDK-8242888. Discussion for that here: https://mail.openjdk.java.net/pipermail/core-libs-dev/2020-December/072678.html Now that reflection is implemented using MethodHandles, using hidden classes may work.
16-04-2022

Dynamic constants can call MethodHandles.reflectAs with ConstantBootstraps.invoke to obtain a Method, but MethodHandles.reflectAs is confined by a security manager permission check, making it unsuitable sometimes. In my attempt to move method fetching to condy, the security manager blocks the attempts to call reflectAs, https://github.com/liachmodded/jdk/commit/f716947d2ee4c6f208f0bf6305bd777d080f390c or for proxy implementations to call an exported internal API https://github.com/liachmodded/jdk/compare/9f97f5de684588be6caf0f0ababe5fe773b13d77..c993993b9a626d8733499673d2b069bc06e0c62f Hence, I wonder about the feasibility of a standalone API in ConstantBootstraps, something like ```java public static <T extends Member> T reflectAs(MethodHandles.Lookup lookup, String name, Class<? extends T> type, MethodHandle handle) { // check not null return lookup.revealDirect(handle).reflectAs(type, handle); } ``` Or should I spin another super class for all proxies just to provide this bootstrap method?
16-04-2022