Skip to content

Commit

Permalink
Remove locks around method and field ID retrieval (#1036)
Browse files Browse the repository at this point in the history
  • Loading branch information
HosseinYousefi authored Mar 21, 2024
1 parent 4ec23cd commit b52b5d1
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 332 deletions.
18 changes: 0 additions & 18 deletions pkgs/jni/lib/src/third_party/jni_bindings_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -110,24 +110,6 @@ class JniBindings {
late final _SpawnJvm =
_SpawnJvmPtr.asFunction<int Function(ffi.Pointer<JavaVMInitArgs>)>();

/// Load class through platform-specific mechanism.
///
/// Currently uses application classloader on android,
/// and JNIEnv->FindClass on other platforms.
JClassPtr FindClass(
ffi.Pointer<ffi.Char> name,
) {
return _FindClass(
name,
);
}

late final _FindClassPtr =
_lookup<ffi.NativeFunction<JClassPtr Function(ffi.Pointer<ffi.Char>)>>(
'FindClass');
late final _FindClass =
_FindClassPtr.asFunction<JClassPtr Function(ffi.Pointer<ffi.Char>)>();

/// Returns Application classLoader (on Android),
/// which can be used to load application and platform classes.
///
Expand Down
24 changes: 14 additions & 10 deletions pkgs/jni/src/dartjni.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,22 @@

void initAllLocks(JniLocks* locks) {
init_lock(&locks->classLoadingLock);
init_lock(&locks->fieldLoadingLock);
init_lock(&locks->methodLoadingLock);
}

/// Load class through platform-specific mechanism.
///
/// Currently uses application classloader on android,
/// and JNIEnv->FindClass on other platforms.
jclass FindClass(const char* name) {
attach_thread();
jclass cls;
load_class_platform(&cls, name);
if (!(*jniEnv)->ExceptionCheck(jniEnv)) {
cls = to_global_ref(cls);
}
return cls;
};

/// Stores class and method references for obtaining exception details
typedef struct JniExceptionMethods {
jclass objectClass, exceptionClass, printStreamClass;
Expand Down Expand Up @@ -62,14 +74,6 @@ JavaVM* GetJavaVM() {
return jni_context.jvm;
}

FFI_PLUGIN_EXPORT
jclass FindClass(const char* name) {
jclass cls = NULL;
attach_thread();
load_class_global_ref(&cls, name);
return cls;
};

// Android specifics

FFI_PLUGIN_EXPORT
Expand Down
42 changes: 4 additions & 38 deletions pkgs/jni/src/dartjni.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ typedef struct CallbackResult {

typedef struct JniLocks {
MutexLock classLoadingLock;
MutexLock methodLoadingLock;
MutexLock fieldLoadingLock;
} JniLocks;

/// Represents the error when dart-jni layer has already spawned singleton VM.
Expand Down Expand Up @@ -248,12 +246,6 @@ FFI_PLUGIN_EXPORT JNIEnv* GetJniEnv(void);
/// JVMs is made, even if the underlying API potentially supports multiple VMs.
FFI_PLUGIN_EXPORT int SpawnJvm(JavaVMInitArgs* args);

/// Load class through platform-specific mechanism.
///
/// Currently uses application classloader on android,
/// and JNIEnv->FindClass on other platforms.
FFI_PLUGIN_EXPORT jclass FindClass(const char* name);

/// Returns Application classLoader (on Android),
/// which can be used to load application and platform classes.
///
Expand Down Expand Up @@ -286,16 +278,6 @@ static inline void load_class_platform(jclass* cls, const char* name) {
#endif
}

static inline void load_class_local_ref(jclass* cls, const char* name) {
if (*cls == NULL) {
acquire_lock(&jni->locks.classLoadingLock);
if (*cls == NULL) {
load_class_platform(cls, name);
}
release_lock(&jni->locks.classLoadingLock);
}
}

static inline void load_class_global_ref(jclass* cls, const char* name) {
if (*cls == NULL) {
jclass tmp = NULL;
Expand All @@ -316,11 +298,7 @@ static inline void load_method(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.methodLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.methodLoadingLock);
*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
}
}

Expand All @@ -329,11 +307,7 @@ static inline void load_static_method(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.methodLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.methodLoadingLock);
*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
}
}

Expand All @@ -342,11 +316,7 @@ static inline void load_field(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.fieldLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.fieldLoadingLock);
*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
}
}

Expand All @@ -355,11 +325,7 @@ static inline void load_static_field(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.fieldLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.fieldLoadingLock);
*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
}
}

Expand Down
42 changes: 4 additions & 38 deletions pkgs/jnigen/example/in_app_java/src/android_utils/dartjni.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ typedef struct CallbackResult {

typedef struct JniLocks {
MutexLock classLoadingLock;
MutexLock methodLoadingLock;
MutexLock fieldLoadingLock;
} JniLocks;

/// Represents the error when dart-jni layer has already spawned singleton VM.
Expand Down Expand Up @@ -248,12 +246,6 @@ FFI_PLUGIN_EXPORT JNIEnv* GetJniEnv(void);
/// JVMs is made, even if the underlying API potentially supports multiple VMs.
FFI_PLUGIN_EXPORT int SpawnJvm(JavaVMInitArgs* args);

/// Load class through platform-specific mechanism.
///
/// Currently uses application classloader on android,
/// and JNIEnv->FindClass on other platforms.
FFI_PLUGIN_EXPORT jclass FindClass(const char* name);

/// Returns Application classLoader (on Android),
/// which can be used to load application and platform classes.
///
Expand Down Expand Up @@ -286,16 +278,6 @@ static inline void load_class_platform(jclass* cls, const char* name) {
#endif
}

static inline void load_class_local_ref(jclass* cls, const char* name) {
if (*cls == NULL) {
acquire_lock(&jni->locks.classLoadingLock);
if (*cls == NULL) {
load_class_platform(cls, name);
}
release_lock(&jni->locks.classLoadingLock);
}
}

static inline void load_class_global_ref(jclass* cls, const char* name) {
if (*cls == NULL) {
jclass tmp = NULL;
Expand All @@ -316,11 +298,7 @@ static inline void load_method(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.methodLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.methodLoadingLock);
*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
}
}

Expand All @@ -329,11 +307,7 @@ static inline void load_static_method(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.methodLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.methodLoadingLock);
*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
}
}

Expand All @@ -342,11 +316,7 @@ static inline void load_field(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.fieldLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.fieldLoadingLock);
*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
}
}

Expand All @@ -355,11 +325,7 @@ static inline void load_static_field(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.fieldLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.fieldLoadingLock);
*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
}
}

Expand Down
42 changes: 4 additions & 38 deletions pkgs/jnigen/example/kotlin_plugin/src/dartjni.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,6 @@ typedef struct CallbackResult {

typedef struct JniLocks {
MutexLock classLoadingLock;
MutexLock methodLoadingLock;
MutexLock fieldLoadingLock;
} JniLocks;

/// Represents the error when dart-jni layer has already spawned singleton VM.
Expand Down Expand Up @@ -248,12 +246,6 @@ FFI_PLUGIN_EXPORT JNIEnv* GetJniEnv(void);
/// JVMs is made, even if the underlying API potentially supports multiple VMs.
FFI_PLUGIN_EXPORT int SpawnJvm(JavaVMInitArgs* args);

/// Load class through platform-specific mechanism.
///
/// Currently uses application classloader on android,
/// and JNIEnv->FindClass on other platforms.
FFI_PLUGIN_EXPORT jclass FindClass(const char* name);

/// Returns Application classLoader (on Android),
/// which can be used to load application and platform classes.
///
Expand Down Expand Up @@ -286,16 +278,6 @@ static inline void load_class_platform(jclass* cls, const char* name) {
#endif
}

static inline void load_class_local_ref(jclass* cls, const char* name) {
if (*cls == NULL) {
acquire_lock(&jni->locks.classLoadingLock);
if (*cls == NULL) {
load_class_platform(cls, name);
}
release_lock(&jni->locks.classLoadingLock);
}
}

static inline void load_class_global_ref(jclass* cls, const char* name) {
if (*cls == NULL) {
jclass tmp = NULL;
Expand All @@ -316,11 +298,7 @@ static inline void load_method(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.methodLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.methodLoadingLock);
*res = (*jniEnv)->GetMethodID(jniEnv, cls, name, sig);
}
}

Expand All @@ -329,11 +307,7 @@ static inline void load_static_method(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.methodLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.methodLoadingLock);
*res = (*jniEnv)->GetStaticMethodID(jniEnv, cls, name, sig);
}
}

Expand All @@ -342,11 +316,7 @@ static inline void load_field(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.fieldLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.fieldLoadingLock);
*res = (*jniEnv)->GetFieldID(jniEnv, cls, name, sig);
}
}

Expand All @@ -355,11 +325,7 @@ static inline void load_static_field(jclass cls,
const char* name,
const char* sig) {
if (*res == NULL) {
acquire_lock(&jni->locks.fieldLoadingLock);
if (*res == NULL) {
*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
}
release_lock(&jni->locks.fieldLoadingLock);
*res = (*jniEnv)->GetStaticFieldID(jniEnv, cls, name, sig);
}
}

Expand Down
Loading

0 comments on commit b52b5d1

Please sign in to comment.