From e425df51f395b0d46e5086ff562866befc553cc9 Mon Sep 17 00:00:00 2001 From: tqchen Date: Sat, 11 May 2024 16:53:55 -0400 Subject: [PATCH] [JVM] Automatic Compatibility of JVM AttachCurrentThread Different JDK may have different signature for AttachCurrentThread. This can cause issues for example between code for android and normal java. This PR uses a helper class to enable compact with both. --- .../native/org_apache_tvm_native_c_api.cc | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/jvm/native/src/main/native/org_apache_tvm_native_c_api.cc b/jvm/native/src/main/native/org_apache_tvm_native_c_api.cc index f86191d45bbc..09522381f181 100644 --- a/jvm/native/src/main/native/org_apache_tvm_native_c_api.cc +++ b/jvm/native/src/main/native/org_apache_tvm_native_c_api.cc @@ -222,17 +222,30 @@ JNIEXPORT jint JNICALL Java_org_apache_tvm_LibInfo_tvmFuncCall(JNIEnv* env, jobj return ret; } +// A helper object to take in JNIEnv ptr +// and allow automatic casting to both JNIEnv** and void** +// Background: different version of JDK may choose to have one signature +// or another for the case of AttachCurrentThread +// we use this universal helper object to enable compatibility with both +class JNIEnvPtrHelper { + public: + explicit JNIEnvPtrHelper(JNIEnv** penv) : penv_(penv) {} + + operator JNIEnv**() { return penv_; } + + operator void**() { return reinterpret_cast(penv_); } + + private: + JNIEnv** penv_; +}; + // Callback function extern "C" int funcInvokeCallback(TVMValue* args, int* typeCodes, int numArgs, TVMRetValueHandle ret, void* resourceHandle) { JNIEnv* env; int jniStatus = _jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); if (jniStatus == JNI_EDETACHED) { -#ifdef TVM4J_ANDROID - _jvm->AttachCurrentThread(&env, nullptr); -#else - _jvm->AttachCurrentThread(reinterpret_cast(&env), nullptr); -#endif + _jvm->AttachCurrentThread(JNIEnvPtrHelper(&env), nullptr); } else { CHECK(jniStatus == JNI_OK); } @@ -305,11 +318,7 @@ extern "C" void funcFreeCallback(void* resourceHandle) { JNIEnv* env; int jniStatus = _jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); if (jniStatus == JNI_EDETACHED) { -#ifdef TVM4J_ANDROID - _jvm->AttachCurrentThread(&env, nullptr); -#else - _jvm->AttachCurrentThread(reinterpret_cast(&env), nullptr); -#endif + _jvm->AttachCurrentThread(JNIEnvPtrHelper(&env), nullptr); } else { CHECK(jniStatus == JNI_OK); }