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

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
« no previous file with comments | « base/android/jni_android.h ('k') | base/android/jni_generator/golden_sample_for_tests_jni.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/android/jni_android.cc
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 6f080fb6e3b112d6d12feedc2d5d03ca5edd4386..e09c2d5d150587aedfbb9d57fc294b57dcc931ad 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,68 @@ void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
g_application_context.Get().Reset(context);
}
+void InitReplacementClassLoader(JNIEnv* env,
+ const JavaRef<jobject>& class_loader) {
+ DCHECK(g_class_loader.Get().is_null());
+ DCHECK(!class_loader.is_null());
+
+ ScopedJavaLocalRef<jclass> class_loader_clazz =
+ GetClass(env, "java/lang/ClassLoader");
+ CHECK(!ClearException(env));
+ g_class_loader_load_class_method_id =
+ env->GetMethodID(class_loader_clazz.obj(),
+ "loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+ CHECK(!ClearException(env));
+
+ DCHECK(env->IsInstanceOf(class_loader.obj(), class_loader_clazz.obj()));
+ 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 cas_result = base::subtle::Release_CompareAndSwap(
+ atomic_class_id,
+ null_aw,
+ reinterpret_cast<subtle::AtomicWord>(clazz.obj()));
+ if (cas_result == null_aw) {
+ // We intentionally leak the global ref since we now storing it as a raw
+ // pointer in |atomic_class_id|.
+ return clazz.Release();
+ } else {
+ return reinterpret_cast<jclass>(cas_result);
+ }
+}
+
template<MethodID::Type type>
jmethodID MethodID::Get(JNIEnv* env,
jclass clazz,
« no previous file with comments | « base/android/jni_android.h ('k') | base/android/jni_generator/golden_sample_for_tests_jni.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698