Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1903)

Unified Diff: base/android/jni_android.cc

Issue 472553002: Make class lookup lazy in jni_generator when using lazy method lookup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/android/jni_android.cc
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 6f080fb6e3b112d6d12feedc2d5d03ca5edd4386..7e60397192d4b9810e6a20af3296a1fd71c94e81 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -8,6 +8,7 @@
#include "base/android/build_info.h"
#include "base/android/jni_string.h"
+#include "base/android/jni_utils.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
@@ -21,6 +22,9 @@ JavaVM* g_jvm = NULL;
// that may still be running at shutdown. There is no harm in doing this.
base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
g_application_context = LAZY_INSTANCE_INITIALIZER;
+base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
+ g_class_loader = LAZY_INSTANCE_INITIALIZER;
+jmethodID g_class_loader_load_class_method_id = 0;
std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
ScopedJavaLocalRef<jclass> throwable_clazz =
@@ -118,17 +122,66 @@ void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
g_application_context.Get().Reset(context);
}
+void InitFallbackClassLoader(JNIEnv* env) {
+ DCHECK(g_class_loader.Get().is_null());
+
+ ScopedJavaLocalRef<jclass> class_loader_clazz =
+ GetClass(env, "java/lang/ClassLoader");
+ g_class_loader_load_class_method_id =
+ env->GetMethodID(class_loader_clazz.obj(),
+ "loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+ ScopedJavaLocalRef<jobject> class_loader = GetClassLoader(env);
mkosiba (inactive) 2014/08/15 16:53:50 having jni_android depend on jni initialization ha
+ DCHECK(!class_loader.is_null());
+ g_class_loader.Get().Reset(class_loader);
+}
+
const jobject GetApplicationContext() {
DCHECK(!g_application_context.Get().is_null());
return g_application_context.Get().obj();
}
ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
- jclass clazz = env->FindClass(class_name);
+ jclass clazz;
+ if (!g_class_loader.Get().is_null()) {
+ clazz = static_cast<jclass>(
+ env->CallObjectMethod(g_class_loader.Get().obj(),
+ g_class_loader_load_class_method_id,
+ ConvertUTF8ToJavaString(env, class_name).obj()));
+ } else {
+ clazz = env->FindClass(class_name);
+ }
CHECK(!ClearException(env) && clazz) << "Failed to find class " << class_name;
return ScopedJavaLocalRef<jclass>(env, clazz);
}
+jclass LazyGetClass(
+ JNIEnv* env,
+ const char* class_name,
+ base::subtle::AtomicWord* atomic_class_id) {
+ COMPILE_ASSERT(sizeof(subtle::AtomicWord) >= sizeof(jclass),
+ AtomicWord_SmallerThan_jMethodID);
+ subtle::AtomicWord value = base::subtle::Acquire_Load(atomic_class_id);
+ if (value)
+ return reinterpret_cast<jclass>(value);
+ ScopedJavaGlobalRef<jclass> clazz;
+ clazz.Reset(GetClass(env, class_name));
+ subtle::AtomicWord null_aw = reinterpret_cast<subtle::AtomicWord>(NULL);
+ subtle::AtomicWord old = base::subtle::Release_CompareAndSwap(
+ atomic_class_id,
+ null_aw,
+ reinterpret_cast<subtle::AtomicWord>(clazz.obj()));
+ if (old == null_aw) {
+ // We intentionally release the global ref as that makes it easy to store
+ // the ref in |atomic_class_id|.
+ return clazz.Release();
+ } else {
+ subtle::AtomicWord value = base::subtle::Release_Load(atomic_class_id);
+ CHECK(value);
+ return reinterpret_cast<jclass>(value);
+ }
+}
+
template<MethodID::Type type>
jmethodID MethodID::Get(JNIEnv* env,
jclass clazz,

Powered by Google App Engine
This is Rietveld 408576698