On Mon, 23 Jun 2025 12:17:08 GMT, Coleen Phillimore <cole...@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

Reply via email to