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

Unified Diff: base/android/jni_android.cc

Issue 11038015: Android: lazy initialization for method id. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Moves to MethodID Created 8 years, 2 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 a34bc186ef216adf621bf549f7ebca9baabadde2..c6024cbf0aa643cabe6465edf91b1604305c300c 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -8,14 +8,13 @@
#include "base/android/build_info.h"
#include "base/android/jni_string.h"
-#include "base/atomicops.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/threading/platform_thread.h"
namespace {
using base::android::GetClass;
-using base::android::GetMethodID;
+using base::android::MethodID;
using base::android::ScopedJavaLocalRef;
struct MethodIdentifier {
@@ -59,17 +58,20 @@ std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
ScopedJavaLocalRef<jclass> throwable_clazz =
GetClass(env, "java/lang/Throwable");
jmethodID throwable_printstacktrace =
- GetMethodID(env, throwable_clazz, "printStackTrace",
- "(Ljava/io/PrintStream;)V");
+ MethodID::Get<MethodID::METHODTYPE_NORMAL, MethodID::EXCEPTIONCHECK_YES>(
+ env, throwable_clazz.obj(), "printStackTrace",
+ "(Ljava/io/PrintStream;)V");
// Create an instance of ByteArrayOutputStream.
ScopedJavaLocalRef<jclass> bytearray_output_stream_clazz =
GetClass(env, "java/io/ByteArrayOutputStream");
jmethodID bytearray_output_stream_constructor =
- GetMethodID(env, bytearray_output_stream_clazz, "<init>", "()V");
+ MethodID::Get<MethodID::METHODTYPE_NORMAL, MethodID::EXCEPTIONCHECK_YES>(
+ env, bytearray_output_stream_clazz.obj(), "<init>", "()V");
jmethodID bytearray_output_stream_tostring =
- GetMethodID(env, bytearray_output_stream_clazz, "toString",
- "()Ljava/lang/String;");
+ MethodID::Get<MethodID::METHODTYPE_NORMAL, MethodID::EXCEPTIONCHECK_YES>(
+ env, bytearray_output_stream_clazz.obj(), "toString",
+ "()Ljava/lang/String;");
ScopedJavaLocalRef<jobject> bytearray_output_stream(env,
env->NewObject(bytearray_output_stream_clazz.obj(),
bytearray_output_stream_constructor));
@@ -78,8 +80,9 @@ std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
ScopedJavaLocalRef<jclass> printstream_clazz =
GetClass(env, "java/io/PrintStream");
jmethodID printstream_constructor =
- GetMethodID(env, printstream_clazz, "<init>",
- "(Ljava/io/OutputStream;)V");
+ MethodID::Get<MethodID::METHODTYPE_NORMAL, MethodID::EXCEPTIONCHECK_YES>(
+ env, printstream_clazz.obj(), "<init>",
+ "(Ljava/io/OutputStream;)V");
ScopedJavaLocalRef<jobject> printstream(env,
env->NewObject(printstream_clazz.obj(), printstream_constructor,
bytearray_output_stream.obj()));
@@ -97,35 +100,6 @@ std::string GetJavaExceptionInfo(JNIEnv* env, jthrowable java_throwable) {
return ConvertJavaStringToUTF8(exception_string);
}
-enum MethodType {
- METHODTYPE_STATIC,
- METHODTYPE_NORMAL,
-};
-
-enum ExceptionCheck {
- EXCEPTIONCHECK_YES,
- EXCEPTIONCHECK_NO,
-};
-
-template<MethodType method_type, ExceptionCheck exception_check>
-jmethodID GetMethodIDInternal(JNIEnv* env,
- jclass clazz,
- const char* method_name,
- const char* jni_signature) {
- jmethodID method_id = method_type == METHODTYPE_STATIC ?
- env->GetStaticMethodID(clazz, method_name, jni_signature) :
- env->GetMethodID(clazz, method_name, jni_signature);
- if (exception_check == EXCEPTIONCHECK_YES) {
- CHECK(!base::android::ClearException(env) && method_id) <<
- "Failed to find " <<
- (method_type == METHODTYPE_STATIC ? "static " : "") <<
- "method " << method_name << " " << jni_signature;
- } else if (base::android::HasException(env)) {
- env->ExceptionClear();
- }
- return method_id;
-}
-
} // namespace
namespace base {
@@ -183,68 +157,85 @@ bool HasClass(JNIEnv* env, const char* class_name) {
return true;
}
-jmethodID GetMethodID(JNIEnv* env,
- const JavaRef<jclass>& clazz,
- const char* method_name,
- const char* jni_signature) {
- // clazz.env() can not be used as that may be from a different thread.
- return GetMethodID(env, clazz.obj(), method_name, jni_signature);
-}
-
-jmethodID GetMethodID(JNIEnv* env,
- jclass clazz,
- const char* method_name,
- const char* jni_signature) {
- return GetMethodIDInternal<METHODTYPE_NORMAL, EXCEPTIONCHECK_YES>(
- env, clazz, method_name, jni_signature);
-}
-
-jmethodID GetMethodIDOrNull(JNIEnv* env,
- jclass clazz,
- const char* method_name,
- const char* jni_signature) {
- return GetMethodIDInternal<METHODTYPE_NORMAL, EXCEPTIONCHECK_NO>(
- env, clazz, method_name, jni_signature);
-}
-
-jmethodID GetStaticMethodID(JNIEnv* env,
- const JavaRef<jclass>& clazz,
- const char* method_name,
- const char* jni_signature) {
- return GetStaticMethodID(env, clazz.obj(), method_name,
- jni_signature);
+template<MethodID::MethodType method_type,
+ MethodID::ExceptionCheck exception_check>
+jmethodID MethodID::Get(JNIEnv* env,
+ jclass clazz,
+ const char* method_name,
+ const char* jni_signature) {
+ jmethodID id = method_type == METHODTYPE_STATIC ?
+ env->GetStaticMethodID(clazz, method_name, jni_signature) :
+ env->GetMethodID(clazz, method_name, jni_signature);
+ if (exception_check == EXCEPTIONCHECK_YES) {
+ CHECK(base::android::ClearException(env) || id) <<
+ "Failed to find " <<
+ (method_type == METHODTYPE_STATIC ? "static " : "") <<
+ "method " << method_name << " " << jni_signature;
+ } else if (base::android::HasException(env)) {
+ env->ExceptionClear();
+ }
+ return id;
}
-jmethodID GetStaticMethodID(JNIEnv* env,
+template<MethodID::MethodType method_type,
+ MethodID::ExceptionCheck exception_check>
+jmethodID MethodID::LazyGet(JNIEnv* env,
jclass clazz,
const char* method_name,
- const char* jni_signature) {
- return GetMethodIDInternal<METHODTYPE_STATIC, EXCEPTIONCHECK_YES>(
- env, clazz, method_name, jni_signature);
-}
-
-jmethodID GetStaticMethodIDOrNull(JNIEnv* env,
- jclass clazz,
- const char* method_name,
- const char* jni_signature) {
- return GetMethodIDInternal<METHODTYPE_STATIC, EXCEPTIONCHECK_NO>(
+ const char* jni_signature,
+ base::subtle::AtomicWord* atomic_method_id) {
+ COMPILE_ASSERT(sizeof(subtle::AtomicWord) >= sizeof(jmethodID),
+ AtomicWord_SmallerThan_jMethodID);
+ subtle::AtomicWord value = base::subtle::Acquire_Load(atomic_method_id);
+ if (value)
+ return reinterpret_cast<jmethodID>(value);
+ jmethodID id = MethodID::Get<method_type, exception_check>(
env, clazz, method_name, jni_signature);
+ base::subtle::Release_Store(
+ atomic_method_id, reinterpret_cast<subtle::AtomicWord>(id));
+ return id;
}
-bool HasMethod(JNIEnv* env,
- const JavaRef<jclass>& clazz,
- const char* method_name,
- const char* jni_signature) {
- jmethodID method_id =
- env->GetMethodID(clazz.obj(), method_name, jni_signature);
- if (!method_id) {
- ClearException(env);
- return false;
- }
- bool error = ClearException(env);
- DCHECK(!error);
- return true;
-}
+// Various template instantiations.
+template jmethodID MethodID::Get<MethodID::METHODTYPE_STATIC,
+ MethodID::EXCEPTIONCHECK_YES>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature);
+
+template jmethodID MethodID::Get<MethodID::METHODTYPE_NORMAL,
+ MethodID::EXCEPTIONCHECK_YES>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature);
+
+template jmethodID MethodID::Get<MethodID::METHODTYPE_STATIC,
+ MethodID::EXCEPTIONCHECK_NO>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature);
+
+template jmethodID MethodID::Get<MethodID::METHODTYPE_NORMAL,
+ MethodID::EXCEPTIONCHECK_NO>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature);
joth 2012/10/04 17:59:59 fwiw the ::Get() instantiations are not strictly n
bulach 2012/10/04 18:58:17 I'd love to delete, but I think this makes it clea
+
+template jmethodID MethodID::LazyGet<MethodID::METHODTYPE_STATIC,
+ MethodID::EXCEPTIONCHECK_YES>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature, base::subtle::AtomicWord* atomic_method_id);
+
+template jmethodID MethodID::LazyGet<MethodID::METHODTYPE_NORMAL,
+ MethodID::EXCEPTIONCHECK_YES>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature, base::subtle::AtomicWord* atomic_method_id);
+
+template jmethodID MethodID::LazyGet<MethodID::METHODTYPE_STATIC,
+ MethodID::EXCEPTIONCHECK_NO>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature, base::subtle::AtomicWord* atomic_method_id);
+
+template jmethodID MethodID::LazyGet<MethodID::METHODTYPE_NORMAL,
+ MethodID::EXCEPTIONCHECK_NO>(
+ JNIEnv* env, jclass clazz, const char* method_name,
+ const char* jni_signature, base::subtle::AtomicWord* atomic_method_id);
jfieldID GetFieldID(JNIEnv* env,
const JavaRef<jclass>& clazz,
@@ -310,7 +301,9 @@ jmethodID GetMethodIDFromClassName(JNIEnv* env,
}
ScopedJavaLocalRef<jclass> clazz(env, env->FindClass(class_name));
- jmethodID id = GetMethodID(env, clazz, method, jni_signature);
+ jmethodID id = MethodID::Get<
+ MethodID::METHODTYPE_NORMAL, MethodID::EXCEPTIONCHECK_YES>(
+ env, clazz.obj(), method, jni_signature);
while (base::subtle::Acquire_CompareAndSwap(&g_method_id_map_lock,
kUnlocked,

Powered by Google App Engine
This is Rietveld 408576698