RFR: 8335638: Calling VarHandle.{access-mode} methods reflectively throws wrong exception
Chen Liang
liach at openjdk.org
Wed Jul 3 20:36:22 UTC 2024
On Wed, 3 Jul 2024 19:43:05 GMT, Hannes Greule <hgreule at openjdk.org> wrote:
> Similar to how `MethodHandle#invoke(Exact)` methods are already handled, this change adds special casing for `VarHandle.{access-mode}` methods.
>
> The exception message is less exact, but I think that's acceptable.
Great work!
src/hotspot/share/prims/methodHandles.cpp line 1372:
> 1370: */
> 1371: JVM_ENTRY(jobject, VH_UOE(JNIEnv* env, jobject mh, jobjectArray args)) {
> 1372: THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "VarHandle access mode method a cannot be invoked reflectively");
Suggestion:
THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "VarHandle access mode methods cannot be invoked reflectively");
Looks like a typo to me.
src/hotspot/share/prims/methodHandles.cpp line 1419:
> 1417: static JNINativeMethod VH_methods[] = {
> 1418: // UnsupportedOperationException throwers
> 1419: {CC "compareAndExchange", CC "([" OBJ ")" OBJ, FN_PTR(VH_UOE)},
I recommend ordering these by the order in `AccessMode`, which is also the declaration order in `VarHandle`; that way, if we add a new access mode, it's easier for us to maintain this list.
src/hotspot/share/prims/methodHandles.cpp line 1457:
> 1455: JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
> 1456: assert(!MethodHandles::enabled(), "must not be enabled");
> 1457: assert(vmClasses::MethodHandle_klass() != nullptr, "should be present");
Should we duplicate this assert for `vmClasses::VarHandle_klass()` too?
test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java line 1:
> 1: /*
The copyright header's year needs an update.
test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java line 69:
> 67: VarHandle v = handle();
> 68:
> 69: // Try a reflective invoke using a Method, with an array of 0 arguments
Suggestion:
// Try a reflective invoke using a Method, with the minimal required argument
test/jdk/java/lang/invoke/VarHandles/VarHandleTestReflection.java line 72:
> 70:
> 71: Method vhm = VarHandle.class.getMethod(accessMode.methodName(), Object[].class);
> 72: Object args = new Object[0];
I recommend naming this `arg`, as this is the single arg to the reflected method. Had you inlined this, you would have called `vhm.invoke(v, (Object) new Object[0]);`
-------------
PR Review: https://git.openjdk.org/jdk/pull/20015#pullrequestreview-2157341254
PR Review Comment: https://git.openjdk.org/jdk/pull/20015#discussion_r1664744641
PR Review Comment: https://git.openjdk.org/jdk/pull/20015#discussion_r1664741601
PR Review Comment: https://git.openjdk.org/jdk/pull/20015#discussion_r1664737631
PR Review Comment: https://git.openjdk.org/jdk/pull/20015#discussion_r1664753008
PR Review Comment: https://git.openjdk.org/jdk/pull/20015#discussion_r1664751627
PR Review Comment: https://git.openjdk.org/jdk/pull/20015#discussion_r1664751688
More information about the core-libs-dev
mailing list