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

Side by Side Diff: trunk/src/base/android/jni_android.cc

Issue 492713002: Revert 290810 "Make class lookup lazy in jni_generator when usin..." (Closed) Base URL: svn://svn.chromium.org/chrome/
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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/android/jni_android.h" 5 #include "base/android/jni_android.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/android/jni_string.h" 10 #include "base/android/jni_string.h"
11 #include "base/android/jni_utils.h"
12 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
13 #include "base/logging.h" 12 #include "base/logging.h"
14 13
15 namespace { 14 namespace {
16 using base::android::GetClass; 15 using base::android::GetClass;
17 using base::android::MethodID; 16 using base::android::MethodID;
18 using base::android::ScopedJavaLocalRef; 17 using base::android::ScopedJavaLocalRef;
19 18
20 JavaVM* g_jvm = NULL; 19 JavaVM* g_jvm = NULL;
21 // Leak the global app context, as it is used from a non-joinable worker thread 20 // Leak the global app context, as it is used from a non-joinable worker thread
22 // that may still be running at shutdown. There is no harm in doing this. 21 // that may still be running at shutdown. There is no harm in doing this.
23 base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky 22 base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
24 g_application_context = LAZY_INSTANCE_INITIALIZER; 23 g_application_context = LAZY_INSTANCE_INITIALIZER;
25 base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >::Leaky
26 g_class_loader = LAZY_INSTANCE_INITIALIZER;
27 jmethodID g_class_loader_load_class_method_id = 0;
28 24
29 std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) { 25 std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
30 ScopedJavaLocalRef<jclass> throwable_clazz = 26 ScopedJavaLocalRef<jclass> throwable_clazz =
31 GetClass(env, "java/lang/Throwable"); 27 GetClass(env, "java/lang/Throwable");
32 jmethodID throwable_printstacktrace = 28 jmethodID throwable_printstacktrace =
33 MethodID::Get<MethodID::TYPE_INSTANCE>( 29 MethodID::Get<MethodID::TYPE_INSTANCE>(
34 env, throwable_clazz.obj(), "printStackTrace", 30 env, throwable_clazz.obj(), "printStackTrace",
35 "(Ljava/io/PrintStream;)V"); 31 "(Ljava/io/PrintStream;)V");
36 32
37 // Create an instance of ByteArrayOutputStream. 33 // Create an instance of ByteArrayOutputStream.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 111
116 void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) { 112 void InitApplicationContext(JNIEnv* env, const JavaRef<jobject>& context) {
117 if (env->IsSameObject(g_application_context.Get().obj(), context.obj())) { 113 if (env->IsSameObject(g_application_context.Get().obj(), context.obj())) {
118 // It's safe to set the context more than once if it's the same context. 114 // It's safe to set the context more than once if it's the same context.
119 return; 115 return;
120 } 116 }
121 DCHECK(g_application_context.Get().is_null()); 117 DCHECK(g_application_context.Get().is_null());
122 g_application_context.Get().Reset(context); 118 g_application_context.Get().Reset(context);
123 } 119 }
124 120
125 void InitReplacementClassLoader(JNIEnv* env,
126 const JavaRef<jobject>& class_loader) {
127 DCHECK(g_class_loader.Get().is_null());
128 DCHECK(!class_loader.is_null());
129
130 ScopedJavaLocalRef<jclass> class_loader_clazz =
131 GetClass(env, "java/lang/ClassLoader");
132 CHECK(!ClearException(env));
133 g_class_loader_load_class_method_id =
134 env->GetMethodID(class_loader_clazz.obj(),
135 "loadClass",
136 "(Ljava/lang/String;)Ljava/lang/Class;");
137 CHECK(!ClearException(env));
138
139 DCHECK(env->IsInstanceOf(class_loader.obj(), class_loader_clazz.obj()));
140 g_class_loader.Get().Reset(class_loader);
141 }
142
143 const jobject GetApplicationContext() { 121 const jobject GetApplicationContext() {
144 DCHECK(!g_application_context.Get().is_null()); 122 DCHECK(!g_application_context.Get().is_null());
145 return g_application_context.Get().obj(); 123 return g_application_context.Get().obj();
146 } 124 }
147 125
148 ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) { 126 ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
149 jclass clazz; 127 jclass clazz = env->FindClass(class_name);
150 if (!g_class_loader.Get().is_null()) {
151 clazz = static_cast<jclass>(
152 env->CallObjectMethod(g_class_loader.Get().obj(),
153 g_class_loader_load_class_method_id,
154 ConvertUTF8ToJavaString(env, class_name).obj()));
155 } else {
156 clazz = env->FindClass(class_name);
157 }
158 CHECK(!ClearException(env) && clazz) << "Failed to find class " << class_name; 128 CHECK(!ClearException(env) && clazz) << "Failed to find class " << class_name;
159 return ScopedJavaLocalRef<jclass>(env, clazz); 129 return ScopedJavaLocalRef<jclass>(env, clazz);
160 } 130 }
161 131
162 jclass LazyGetClass(
163 JNIEnv* env,
164 const char* class_name,
165 base::subtle::AtomicWord* atomic_class_id) {
166 COMPILE_ASSERT(sizeof(subtle::AtomicWord) >= sizeof(jclass),
167 AtomicWord_SmallerThan_jMethodID);
168 subtle::AtomicWord value = base::subtle::Acquire_Load(atomic_class_id);
169 if (value)
170 return reinterpret_cast<jclass>(value);
171 ScopedJavaGlobalRef<jclass> clazz;
172 clazz.Reset(GetClass(env, class_name));
173 subtle::AtomicWord null_aw = reinterpret_cast<subtle::AtomicWord>(NULL);
174 subtle::AtomicWord cas_result = base::subtle::Release_CompareAndSwap(
175 atomic_class_id,
176 null_aw,
177 reinterpret_cast<subtle::AtomicWord>(clazz.obj()));
178 if (cas_result == null_aw) {
179 // We intentionally leak the global ref since we now storing it as a raw
180 // pointer in |atomic_class_id|.
181 return clazz.Release();
182 } else {
183 return reinterpret_cast<jclass>(cas_result);
184 }
185 }
186
187 template<MethodID::Type type> 132 template<MethodID::Type type>
188 jmethodID MethodID::Get(JNIEnv* env, 133 jmethodID MethodID::Get(JNIEnv* env,
189 jclass clazz, 134 jclass clazz,
190 const char* method_name, 135 const char* method_name,
191 const char* jni_signature) { 136 const char* jni_signature) {
192 jmethodID id = type == TYPE_STATIC ? 137 jmethodID id = type == TYPE_STATIC ?
193 env->GetStaticMethodID(clazz, method_name, jni_signature) : 138 env->GetStaticMethodID(clazz, method_name, jni_signature) :
194 env->GetMethodID(clazz, method_name, jni_signature); 139 env->GetMethodID(clazz, method_name, jni_signature);
195 CHECK(base::android::ClearException(env) || id) << 140 CHECK(base::android::ClearException(env) || id) <<
196 "Failed to find " << 141 "Failed to find " <<
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 base::android::BuildInfo::GetInstance()->set_java_exception_info( 209 base::android::BuildInfo::GetInstance()->set_java_exception_info(
265 GetJavaExceptionInfo(env, java_throwable)); 210 GetJavaExceptionInfo(env, java_throwable));
266 } 211 }
267 212
268 // Now, feel good about it and die. 213 // Now, feel good about it and die.
269 CHECK(false) << "Please include Java exception stack in crash report"; 214 CHECK(false) << "Please include Java exception stack in crash report";
270 } 215 }
271 216
272 } // namespace android 217 } // namespace android
273 } // namespace base 218 } // namespace base
OLDNEW
« no previous file with comments | « trunk/src/base/android/jni_android.h ('k') | trunk/src/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