RFR: 8268406: Deallocate jmethodID native memory [v10]

David Holmes dholmes at openjdk.org
Tue Jun 24 02:38:31 UTC 2025


On Mon, 23 Jun 2025 12:17:08 GMT, Coleen Phillimore <coleenp at openjdk.org> wrote:

> I'm not sure but I think in this instance, the native caller has the mirror for the class where it gets the jmethodID from, so can't unload the Method.
> 
> ```
> JNI_ENTRY(ResultType, \
>           jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
> \
> ```

@coleenp Take a look a the complete code:

JNI_ENTRY(ResultType, \
          jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
\
  EntryProbe; \
  ResultType ret{}; \
  DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
                     (const ResultType&)ret);\
\
  va_list args; \
  va_start(args, methodID); \
  JavaValue jvalue(Tag); \
  JNI_ArgumentPusherVaArg ap(methodID, args); \
  jni_invoke_static(env, &jvalue, nullptr, JNI_STATIC, methodID, &ap, CHECK_(ResultType{})); \
  va_end(args); \
  ret = jvalue.get_##ResultType(); \
  return ret;\
JNI_END

the `cls` parameter is never actually used. So while it is supposed to refer to the class you have the static method jMethodID for, there is no requirement that it actually does, and could even be null.

> Once Method::resolve_jmethod_id(method_id) returns to the caller, how can the class be unreferenced?

@dcubed-ojdk  because the caller does not hold a reference to it initially, and resolving the jMethodID does not create a new reference to it. So once we have resolved, at the next safepoint the class could be seen as "not alive" and at the safepoint after that it can be unloaded. Hence we are relying on there being no safepoint checks in the upcall code, after the resolution,  to ensure this can't happen.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/25267#issuecomment-2998571489


More information about the hotspot-dev mailing list