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

Side by Side Diff: content/browser/renderer_host/java/java_method.cc

Issue 8769005: Don't use Singleton to cache JNI method IDs in Java Bridge (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Finer grained locking Created 9 years 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/browser/renderer_host/java/java_method.h" 5 #include "content/browser/renderer_host/java/java_method.h"
6 6
7 #include "base/android/jni_android.h" 7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h" 8 #include "base/android/jni_string.h"
9 #include "base/memory/singleton.h" 9 #include "base/memory/singleton.h"
10 #include "base/string_util.h" // For ReplaceSubstringsAfterOffset 10 #include "base/string_util.h" // For ReplaceSubstringsAfterOffset
11 11
12 using base::android::AttachCurrentThread; 12 using base::android::AttachCurrentThread;
13 using base::android::ConvertJavaStringToUTF8; 13 using base::android::ConvertJavaStringToUTF8;
14 using base::android::MethodID; 14 using base::android::GetMethodIDFromClassName;
15 using base::android::ScopedJavaLocalRef; 15 using base::android::ScopedJavaLocalRef;
16 16
17 namespace { 17 namespace {
18 18
19 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method";
20 const char kGetParameterTypes[] = "getParameterTypes";
21 const char kReturningJavaLangClassArray[] = "()[Ljava/lang/Class;";
22
23 const char kJavaLangClass[] = "java/lang/Class";
24 const char kGetName[] = "getName";
25 const char kReturningJavaLangClass[] = "()Ljava/lang/String;";
26
19 std::string BinaryNameToJNIName(const std::string& binary_name, 27 std::string BinaryNameToJNIName(const std::string& binary_name,
20 JavaType* type) { 28 JavaType* type) {
21 DCHECK(type); 29 DCHECK(type);
22 *type = JavaType::CreateFromBinaryName(binary_name); 30 *type = JavaType::CreateFromBinaryName(binary_name);
23 switch (type->type) { 31 switch (type->type) {
24 case JavaType::TypeBoolean: 32 case JavaType::TypeBoolean:
25 return "Z"; 33 return "Z";
26 case JavaType::TypeByte: 34 case JavaType::TypeByte:
27 return "B"; 35 return "B";
28 case JavaType::TypeChar: 36 case JavaType::TypeChar:
(...skipping 14 matching lines...) Expand all
43 return "["; 51 return "[";
44 default: 52 default:
45 DCHECK(type->type == JavaType::TypeString || 53 DCHECK(type->type == JavaType::TypeString ||
46 type->type == JavaType::TypeObject); 54 type->type == JavaType::TypeObject);
47 std::string jni_name = "L" + binary_name + ";"; 55 std::string jni_name = "L" + binary_name + ";";
48 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/"); 56 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/");
49 return jni_name; 57 return jni_name;
50 } 58 }
51 } 59 }
52 60
53 class MethodGetParameterTypesID : public MethodID {
54 public:
55 static MethodGetParameterTypesID* GetInstance() {
56 return Singleton<MethodGetParameterTypesID>::get();
57 }
58 private:
59 friend struct DefaultSingletonTraits<MethodGetParameterTypesID>;
60 MethodGetParameterTypesID()
61 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
62 "getParameterTypes", "()[Ljava/lang/Class;") {
63 }
64 DISALLOW_COPY_AND_ASSIGN(MethodGetParameterTypesID);
65 };
66
67 class MethodGetNameID : public MethodID {
68 public:
69 static MethodGetNameID* GetInstance() {
70 return Singleton<MethodGetNameID>::get();
71 }
72 private:
73 friend struct DefaultSingletonTraits<MethodGetNameID>;
74 MethodGetNameID()
75 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
76 "getName", "()Ljava/lang/String;") {
77 }
78 DISALLOW_COPY_AND_ASSIGN(MethodGetNameID);
79 };
80
81 class MethodGetReturnTypeID : public MethodID {
82 public:
83 static MethodGetReturnTypeID* GetInstance() {
84 return Singleton<MethodGetReturnTypeID>::get();
85 }
86 private:
87 friend struct DefaultSingletonTraits<MethodGetReturnTypeID>;
88 MethodGetReturnTypeID()
89 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
90 "getReturnType", "()Ljava/lang/Class;") {
91 }
92 DISALLOW_COPY_AND_ASSIGN(MethodGetReturnTypeID);
93 };
94
95 class MethodGetDeclaringClassID : public MethodID {
96 public:
97 static MethodGetDeclaringClassID* GetInstance() {
98 return Singleton<MethodGetDeclaringClassID>::get();
99 }
100 private:
101 friend struct DefaultSingletonTraits<MethodGetDeclaringClassID>;
102 MethodGetDeclaringClassID()
103 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
104 "getDeclaringClass", "()Ljava/lang/Class;") {
105 }
106 DISALLOW_COPY_AND_ASSIGN(MethodGetDeclaringClassID);
107 };
108
109 class ClassGetNameID : public MethodID {
110 public:
111 static ClassGetNameID* GetInstance() {
112 return Singleton<ClassGetNameID>::get();
113 }
114 private:
115 friend struct DefaultSingletonTraits<ClassGetNameID>;
116 ClassGetNameID()
117 : MethodID(AttachCurrentThread(), "java/lang/Class", "getName",
118 "()Ljava/lang/String;") {
119 }
120 DISALLOW_COPY_AND_ASSIGN(ClassGetNameID);
121 };
122
123 } // namespace 61 } // namespace
124 62
125 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method) 63 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method)
126 : java_method_(method), 64 : java_method_(method),
127 have_calculated_num_parameters_(false), 65 have_calculated_num_parameters_(false),
128 id_(NULL) { 66 id_(NULL) {
129 JNIEnv* env = java_method_.env(); 67 JNIEnv* env = java_method_.env();
130 // On construction, we do nothing except get the name. Everything else is 68 // On construction, we do nothing except get the name. Everything else is
131 // done lazily. 69 // done lazily.
132 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( 70 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
133 env->CallObjectMethod(java_method_.obj(), 71 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
134 MethodGetNameID::GetInstance()->id()))); 72 env,
73 "java/lang/reflect/Method",
74 "getName",
75 "()Ljava/lang/String;"))));
135 name_ = ConvertJavaStringToUTF8(env, name.obj()); 76 name_ = ConvertJavaStringToUTF8(env, name.obj());
136 } 77 }
137 78
138 JavaMethod::~JavaMethod() { 79 JavaMethod::~JavaMethod() {
139 } 80 }
140 81
141 size_t JavaMethod::num_parameters() const { 82 size_t JavaMethod::num_parameters() const {
142 EnsureNumParametersIsSetUp(); 83 EnsureNumParametersIsSetUp();
143 return num_parameters_; 84 return num_parameters_;
144 } 85 }
(...skipping 17 matching lines...) Expand all
162 if (have_calculated_num_parameters_) { 103 if (have_calculated_num_parameters_) {
163 return; 104 return;
164 } 105 }
165 have_calculated_num_parameters_ = true; 106 have_calculated_num_parameters_ = true;
166 107
167 // The number of parameters will be used frequently when determining 108 // The number of parameters will be used frequently when determining
168 // whether to call this method. We don't get the ID etc until actually 109 // whether to call this method. We don't get the ID etc until actually
169 // required. 110 // required.
170 JNIEnv* env = java_method_.env(); 111 JNIEnv* env = java_method_.env();
171 ScopedJavaLocalRef<jarray> parameters(env, static_cast<jarray>( 112 ScopedJavaLocalRef<jarray> parameters(env, static_cast<jarray>(
172 env->CallObjectMethod(java_method_.obj(), 113 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
173 MethodGetParameterTypesID::GetInstance()->id()))); 114 env,
115 kJavaLangReflectMethod,
116 kGetParameterTypes,
117 kReturningJavaLangClassArray))));
174 num_parameters_ = env->GetArrayLength(parameters.obj()); 118 num_parameters_ = env->GetArrayLength(parameters.obj());
175 } 119 }
176 120
177 void JavaMethod::EnsureTypesAndIDAreSetUp() const { 121 void JavaMethod::EnsureTypesAndIDAreSetUp() const {
178 if (id_) { 122 if (id_) {
179 return; 123 return;
180 } 124 }
181 125
182 // Get the parameters 126 // Get the parameters
183 JNIEnv* env = java_method_.env(); 127 JNIEnv* env = java_method_.env();
184 ScopedJavaLocalRef<jobjectArray> parameters(env, static_cast<jobjectArray>( 128 ScopedJavaLocalRef<jobjectArray> parameters(env, static_cast<jobjectArray>(
185 env->CallObjectMethod(java_method_.obj(), 129 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
186 MethodGetParameterTypesID::GetInstance()->id()))); 130 env,
131 kJavaLangReflectMethod,
132 kGetParameterTypes,
133 kReturningJavaLangClassArray))));
187 // Usually, this will already have been called. 134 // Usually, this will already have been called.
188 EnsureNumParametersIsSetUp(); 135 EnsureNumParametersIsSetUp();
189 DCHECK_EQ(num_parameters_, 136 DCHECK_EQ(num_parameters_,
190 static_cast<size_t>(env->GetArrayLength(parameters.obj()))); 137 static_cast<size_t>(env->GetArrayLength(parameters.obj())));
191 138
192 // Java gives us the argument type using an extended version of the 'binary 139 // Java gives us the argument type using an extended version of the 'binary
193 // name'. See 140 // name'. See
194 // http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#getNa me(). 141 // http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#getNa me().
195 // If we build the signature now, there's no need to store the binary name 142 // If we build the signature now, there's no need to store the binary name
196 // of the arguments. We just store the simple type. 143 // of the arguments. We just store the simple type.
197 std::string signature("("); 144 std::string signature("(");
198 145
199 // Form the signature and record the parameter types. 146 // Form the signature and record the parameter types.
200 parameter_types_.resize(num_parameters_); 147 parameter_types_.resize(num_parameters_);
201 for (size_t i = 0; i < num_parameters_; ++i) { 148 for (size_t i = 0; i < num_parameters_; ++i) {
202 ScopedJavaLocalRef<jobject> parameter(env, env->GetObjectArrayElement( 149 ScopedJavaLocalRef<jobject> parameter(env, env->GetObjectArrayElement(
203 parameters.obj(), i)); 150 parameters.obj(), i));
204 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( 151 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
205 env->CallObjectMethod(parameter.obj(), 152 env->CallObjectMethod(parameter.obj(), GetMethodIDFromClassName(
206 ClassGetNameID::GetInstance()->id()))); 153 env,
154 kJavaLangClass,
155 kGetName,
156 kReturningJavaLangClass))));
207 std::string name_utf8 = ConvertJavaStringToUTF8(env, name.obj()); 157 std::string name_utf8 = ConvertJavaStringToUTF8(env, name.obj());
208 signature += BinaryNameToJNIName(name_utf8, &parameter_types_[i]); 158 signature += BinaryNameToJNIName(name_utf8, &parameter_types_[i]);
209 } 159 }
210 signature += ")"; 160 signature += ")";
211 161
212 // Get the return type 162 // Get the return type
213 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( 163 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>(
214 env->CallObjectMethod(java_method_.obj(), 164 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
215 MethodGetReturnTypeID::GetInstance()->id()))); 165 env,
166 "java/lang/reflect/Method",
167 "getReturnType",
168 "()Ljava/lang/Class;"))));
216 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( 169 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
217 env->CallObjectMethod(clazz.obj(), ClassGetNameID::GetInstance()->id()))); 170 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName(
171 env,
172 kJavaLangClass,
173 kGetName,
174 kReturningJavaLangClass))));
218 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), 175 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()),
219 &return_type_); 176 &return_type_);
220 177
221 // Get the ID for this method. 178 // Get the ID for this method.
222 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( 179 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>(
223 env->CallObjectMethod(java_method_.obj(), 180 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
224 MethodGetDeclaringClassID::GetInstance()->id()))); 181 env,
182 "java/lang/reflect/Method",
183 "getDeclaringClass",
184 "()Ljava/lang/Class;"))));
225 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(), 185 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(),
226 signature.c_str()); 186 signature.c_str());
227 187
228 java_method_.Reset(); 188 java_method_.Reset();
229 } 189 }
OLDNEW
« base/android/jni_android.cc ('K') | « content/browser/renderer_host/java/java_bound_object.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698