1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "jni_internal.h"
18
19 #include <dlfcn.h>
20
21 #include <cstdarg>
22 #include <utility>
23 #include <vector>
24
25 #include "base/logging.h"
26 #include "base/mutex.h"
27 #include "base/stl_util.h"
28 #include "base/stringpiece.h"
29 #include "class_linker.h"
30 #include "dex_file-inl.h"
31 #include "gc/accounting/card_table-inl.h"
32 #include "interpreter/interpreter.h"
33 #include "invoke_arg_array_builder.h"
34 #include "jni.h"
35 #include "mirror/art_field-inl.h"
36 #include "mirror/art_method-inl.h"
37 #include "mirror/class-inl.h"
38 #include "mirror/class_loader.h"
39 #include "mirror/object-inl.h"
40 #include "mirror/object_array-inl.h"
41 #include "mirror/throwable.h"
42 #include "object_utils.h"
43 #include "runtime.h"
44 #include "safe_map.h"
45 #include "scoped_thread_state_change.h"
46 #include "ScopedLocalRef.h"
47 #include "thread.h"
48 #include "utf.h"
49 #include "UniquePtr.h"
50 #include "well_known_classes.h"
51
52 using ::art::mirror::ArtField;
53 using ::art::mirror::ArtMethod;
54 using ::art::mirror::Array;
55 using ::art::mirror::BooleanArray;
56 using ::art::mirror::ByteArray;
57 using ::art::mirror::CharArray;
58 using ::art::mirror::Class;
59 using ::art::mirror::ClassLoader;
60 using ::art::mirror::DoubleArray;
61 using ::art::mirror::FloatArray;
62 using ::art::mirror::IntArray;
63 using ::art::mirror::LongArray;
64 using ::art::mirror::Object;
65 using ::art::mirror::ObjectArray;
66 using ::art::mirror::ShortArray;
67 using ::art::mirror::String;
68 using ::art::mirror::Throwable;
69
70 namespace art {
71
72 static const size_t kMonitorsInitial = 32; // Arbitrary.
73 static const size_t kMonitorsMax = 4096; // Arbitrary sanity check.
74
75 static const size_t kLocalsInitial = 64; // Arbitrary.
76 static const size_t kLocalsMax = 512; // Arbitrary sanity check.
77
78 static const size_t kPinTableInitial = 16; // Arbitrary.
79 static const size_t kPinTableMax = 1024; // Arbitrary sanity check.
80
81 static size_t gGlobalsInitial = 512; // Arbitrary.
82 static size_t gGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
83
84 static const size_t kWeakGlobalsInitial = 16; // Arbitrary.
85 static const size_t kWeakGlobalsMax = 51200; // Arbitrary sanity check. (Must fit in 16 bits.)
86
AddWeakGlobalReference(ScopedObjectAccess & soa,Object * obj)87 static jweak AddWeakGlobalReference(ScopedObjectAccess& soa, Object* obj)
88 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
89 return soa.Vm()->AddWeakGlobalReference(soa.Self(), obj);
90 }
91
IsBadJniVersion(int version)92 static bool IsBadJniVersion(int version) {
93 // We don't support JNI_VERSION_1_1. These are the only other valid versions.
94 return version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 && version != JNI_VERSION_1_6;
95 }
96
CheckMethodArguments(ArtMethod * m,uint32_t * args)97 static void CheckMethodArguments(ArtMethod* m, uint32_t* args)
98 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
99 MethodHelper mh(m);
100 const DexFile::TypeList* params = mh.GetParameterTypeList();
101 if (params == NULL) {
102 return; // No arguments so nothing to check.
103 }
104 uint32_t offset = 0;
105 uint32_t num_params = params->Size();
106 size_t error_count = 0;
107 if (!m->IsStatic()) {
108 offset = 1;
109 }
110 for (uint32_t i = 0; i < num_params; i++) {
111 uint16_t type_idx = params->GetTypeItem(i).type_idx_;
112 Class* param_type = mh.GetClassFromTypeIdx(type_idx);
113 if (param_type == NULL) {
114 Thread* self = Thread::Current();
115 CHECK(self->IsExceptionPending());
116 LOG(ERROR) << "Internal error: unresolvable type for argument type in JNI invoke: "
117 << mh.GetTypeDescriptorFromTypeIdx(type_idx) << "\n"
118 << self->GetException(NULL)->Dump();
119 self->ClearException();
120 ++error_count;
121 } else if (!param_type->IsPrimitive()) {
122 // TODO: check primitives are in range.
123 Object* argument = reinterpret_cast<Object*>(args[i + offset]);
124 if (argument != NULL && !argument->InstanceOf(param_type)) {
125 LOG(ERROR) << "JNI ERROR (app bug): attempt to pass an instance of "
126 << PrettyTypeOf(argument) << " as argument " << (i + 1) << " to " << PrettyMethod(m);
127 ++error_count;
128 }
129 } else if (param_type->IsPrimitiveLong() || param_type->IsPrimitiveDouble()) {
130 offset++;
131 }
132 }
133 if (error_count > 0) {
134 // TODO: pass the JNI function name (such as "CallVoidMethodV") through so we can call JniAbort
135 // with an argument.
136 JniAbortF(NULL, "bad arguments passed to %s (see above for details)", PrettyMethod(m).c_str());
137 }
138 }
139
InvokeWithArgArray(const ScopedObjectAccess & soa,ArtMethod * method,ArgArray * arg_array,JValue * result,char result_type)140 void InvokeWithArgArray(const ScopedObjectAccess& soa, ArtMethod* method,
141 ArgArray* arg_array, JValue* result, char result_type)
142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
143 uint32_t* args = arg_array->GetArray();
144 if (UNLIKELY(soa.Env()->check_jni)) {
145 CheckMethodArguments(method, args);
146 }
147 method->Invoke(soa.Self(), args, arg_array->GetNumBytes(), result, result_type);
148 }
149
InvokeWithVarArgs(const ScopedObjectAccess & soa,jobject obj,jmethodID mid,va_list args)150 static JValue InvokeWithVarArgs(const ScopedObjectAccess& soa, jobject obj,
151 jmethodID mid, va_list args)
152 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
153 ArtMethod* method = soa.DecodeMethod(mid);
154 Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj);
155 MethodHelper mh(method);
156 JValue result;
157 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
158 arg_array.BuildArgArray(soa, receiver, args);
159 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
160 return result;
161 }
162
FindVirtualMethod(Object * receiver,ArtMethod * method)163 static ArtMethod* FindVirtualMethod(Object* receiver, ArtMethod* method)
164 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
165 return receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(method);
166 }
167
InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccess & soa,jobject obj,jmethodID mid,jvalue * args)168 static JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccess& soa,
169 jobject obj, jmethodID mid, jvalue* args)
170 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
171 Object* receiver = soa.Decode<Object*>(obj);
172 ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
173 MethodHelper mh(method);
174 JValue result;
175 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
176 arg_array.BuildArgArray(soa, receiver, args);
177 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
178 return result;
179 }
180
InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccess & soa,jobject obj,jmethodID mid,va_list args)181 static JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccess& soa,
182 jobject obj, jmethodID mid, va_list args)
183 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
184 Object* receiver = soa.Decode<Object*>(obj);
185 ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
186 MethodHelper mh(method);
187 JValue result;
188 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
189 arg_array.BuildArgArray(soa, receiver, args);
190 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
191 return result;
192 }
193
194 // Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
195 // separated with slashes but aren't wrapped with "L;" like regular descriptors
196 // (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
197 // exception; there the "L;" must be present ("[La/b/C;"). Historically we've
198 // supported names with dots too (such as "a.b.C").
NormalizeJniClassDescriptor(const char * name)199 static std::string NormalizeJniClassDescriptor(const char* name) {
200 std::string result;
201 // Add the missing "L;" if necessary.
202 if (name[0] == '[') {
203 result = name;
204 } else {
205 result += 'L';
206 result += name;
207 result += ';';
208 }
209 // Rewrite '.' as '/' for backwards compatibility.
210 if (result.find('.') != std::string::npos) {
211 LOG(WARNING) << "Call to JNI FindClass with dots in name: "
212 << "\"" << name << "\"";
213 std::replace(result.begin(), result.end(), '.', '/');
214 }
215 return result;
216 }
217
ThrowNoSuchMethodError(ScopedObjectAccess & soa,Class * c,const char * name,const char * sig,const char * kind)218 static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, Class* c,
219 const char* name, const char* sig, const char* kind)
220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
221 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
222 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchMethodError;",
223 "no %s method \"%s.%s%s\"",
224 kind, ClassHelper(c).GetDescriptor(), name, sig);
225 }
226
FindMethodID(ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)227 static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
228 const char* name, const char* sig, bool is_static)
229 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
230 Class* c = soa.Decode<Class*>(jni_class);
231 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
232 return NULL;
233 }
234
235 ArtMethod* method = NULL;
236 if (is_static) {
237 method = c->FindDirectMethod(name, sig);
238 } else {
239 method = c->FindVirtualMethod(name, sig);
240 if (method == NULL) {
241 // No virtual method matching the signature. Search declared
242 // private methods and constructors.
243 method = c->FindDeclaredDirectMethod(name, sig);
244 }
245 }
246
247 if (method == NULL || method->IsStatic() != is_static) {
248 ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
249 return NULL;
250 }
251
252 return soa.EncodeMethod(method);
253 }
254
GetClassLoader(const ScopedObjectAccess & soa)255 static ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
256 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
257 ArtMethod* method = soa.Self()->GetCurrentMethod(NULL);
258 // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
259 if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
260 return soa.Self()->GetClassLoaderOverride();
261 }
262 // If we have a method, use its ClassLoader for context.
263 if (method != NULL) {
264 return method->GetDeclaringClass()->GetClassLoader();
265 }
266 // We don't have a method, so try to use the system ClassLoader.
267 ClassLoader* class_loader = soa.Decode<ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
268 if (class_loader != NULL) {
269 return class_loader;
270 }
271 // See if the override ClassLoader is set for gtests.
272 class_loader = soa.Self()->GetClassLoaderOverride();
273 if (class_loader != NULL) {
274 // If so, CommonTest should have set UseCompileTimeClassPath.
275 CHECK(Runtime::Current()->UseCompileTimeClassPath());
276 return class_loader;
277 }
278 // Use the BOOTCLASSPATH.
279 return NULL;
280 }
281
FindFieldID(const ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)282 static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
283 const char* sig, bool is_static)
284 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
285 Class* c = soa.Decode<Class*>(jni_class);
286 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
287 return NULL;
288 }
289
290 ArtField* field = NULL;
291 Class* field_type;
292 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
293 if (sig[1] != '\0') {
294 SirtRef<mirror::ClassLoader> class_loader(soa.Self(), c->GetClassLoader());
295 field_type = class_linker->FindClass(sig, class_loader.get());
296 } else {
297 field_type = class_linker->FindPrimitiveClass(*sig);
298 }
299 if (field_type == NULL) {
300 // Failed to find type from the signature of the field.
301 DCHECK(soa.Self()->IsExceptionPending());
302 ThrowLocation throw_location;
303 SirtRef<Throwable> cause(soa.Self(), soa.Self()->GetException(&throw_location));
304 soa.Self()->ClearException();
305 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
306 "no type \"%s\" found and so no field \"%s\" could be found in class "
307 "\"%s\" or its superclasses", sig, name,
308 ClassHelper(c).GetDescriptor());
309 soa.Self()->GetException(NULL)->SetCause(cause.get());
310 return NULL;
311 }
312 if (is_static) {
313 field = c->FindStaticField(name, ClassHelper(field_type).GetDescriptor());
314 } else {
315 field = c->FindInstanceField(name, ClassHelper(field_type).GetDescriptor());
316 }
317 if (field == NULL) {
318 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
319 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/NoSuchFieldError;",
320 "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
321 sig, name, ClassHelper(c).GetDescriptor());
322 return NULL;
323 }
324 return soa.EncodeField(field);
325 }
326
PinPrimitiveArray(const ScopedObjectAccess & soa,const Array * array)327 static void PinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
328 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
329 JavaVMExt* vm = soa.Vm();
330 MutexLock mu(soa.Self(), vm->pins_lock);
331 vm->pin_table.Add(array);
332 }
333
UnpinPrimitiveArray(const ScopedObjectAccess & soa,const Array * array)334 static void UnpinPrimitiveArray(const ScopedObjectAccess& soa, const Array* array)
335 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
336 JavaVMExt* vm = soa.Vm();
337 MutexLock mu(soa.Self(), vm->pins_lock);
338 vm->pin_table.Remove(array);
339 }
340
ThrowAIOOBE(ScopedObjectAccess & soa,Array * array,jsize start,jsize length,const char * identifier)341 static void ThrowAIOOBE(ScopedObjectAccess& soa, Array* array, jsize start,
342 jsize length, const char* identifier)
343 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
344 std::string type(PrettyTypeOf(array));
345 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
346 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/ArrayIndexOutOfBoundsException;",
347 "%s offset=%d length=%d %s.length=%d",
348 type.c_str(), start, length, identifier, array->GetLength());
349 }
350
ThrowSIOOBE(ScopedObjectAccess & soa,jsize start,jsize length,jsize array_length)351 static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
352 jsize array_length)
353 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
354 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
355 soa.Self()->ThrowNewExceptionF(throw_location, "Ljava/lang/StringIndexOutOfBoundsException;",
356 "offset=%d length=%d string.length()=%d", start, length,
357 array_length);
358 }
359
ThrowNewException(JNIEnv * env,jclass exception_class,const char * msg,jobject cause)360 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
361 LOCKS_EXCLUDED(Locks::mutator_lock_) {
362 // Turn the const char* into a java.lang.String.
363 ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
364 if (msg != NULL && s.get() == NULL) {
365 return JNI_ERR;
366 }
367
368 // Choose an appropriate constructor and set up the arguments.
369 jvalue args[2];
370 const char* signature;
371 if (msg == NULL && cause == NULL) {
372 signature = "()V";
373 } else if (msg != NULL && cause == NULL) {
374 signature = "(Ljava/lang/String;)V";
375 args[0].l = s.get();
376 } else if (msg == NULL && cause != NULL) {
377 signature = "(Ljava/lang/Throwable;)V";
378 args[0].l = cause;
379 } else {
380 signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
381 args[0].l = s.get();
382 args[1].l = cause;
383 }
384 jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
385 if (mid == NULL) {
386 ScopedObjectAccess soa(env);
387 LOG(ERROR) << "No <init>" << signature << " in "
388 << PrettyClass(soa.Decode<Class*>(exception_class));
389 return JNI_ERR;
390 }
391
392 ScopedLocalRef<jthrowable> exception(env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
393 if (exception.get() == NULL) {
394 return JNI_ERR;
395 }
396 ScopedObjectAccess soa(env);
397 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
398 soa.Self()->SetException(throw_location, soa.Decode<Throwable*>(exception.get()));
399 return JNI_OK;
400 }
401
JII_AttachCurrentThread(JavaVM * vm,JNIEnv ** p_env,void * raw_args,bool as_daemon)402 static jint JII_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* raw_args, bool as_daemon) {
403 if (vm == NULL || p_env == NULL) {
404 return JNI_ERR;
405 }
406
407 // Return immediately if we're already attached.
408 Thread* self = Thread::Current();
409 if (self != NULL) {
410 *p_env = self->GetJniEnv();
411 return JNI_OK;
412 }
413
414 Runtime* runtime = reinterpret_cast<JavaVMExt*>(vm)->runtime;
415
416 // No threads allowed in zygote mode.
417 if (runtime->IsZygote()) {
418 LOG(ERROR) << "Attempt to attach a thread in the zygote";
419 return JNI_ERR;
420 }
421
422 JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(raw_args);
423 const char* thread_name = NULL;
424 jobject thread_group = NULL;
425 if (args != NULL) {
426 if (IsBadJniVersion(args->version)) {
427 LOG(ERROR) << "Bad JNI version passed to "
428 << (as_daemon ? "AttachCurrentThreadAsDaemon" : "AttachCurrentThread") << ": "
429 << args->version;
430 return JNI_EVERSION;
431 }
432 thread_name = args->name;
433 thread_group = args->group;
434 }
435
436 if (!runtime->AttachCurrentThread(thread_name, as_daemon, thread_group, !runtime->IsCompiler())) {
437 *p_env = NULL;
438 return JNI_ERR;
439 } else {
440 *p_env = Thread::Current()->GetJniEnv();
441 return JNI_OK;
442 }
443 }
444
445 class SharedLibrary {
446 public:
SharedLibrary(const std::string & path,void * handle,Object * class_loader)447 SharedLibrary(const std::string& path, void* handle, Object* class_loader)
448 : path_(path),
449 handle_(handle),
450 class_loader_(class_loader),
451 jni_on_load_lock_("JNI_OnLoad lock"),
452 jni_on_load_cond_("JNI_OnLoad condition variable", jni_on_load_lock_),
453 jni_on_load_thread_id_(Thread::Current()->GetThinLockId()),
454 jni_on_load_result_(kPending) {
455 }
456
GetClassLoader()457 Object* GetClassLoader() {
458 return class_loader_;
459 }
460
GetPath()461 std::string GetPath() {
462 return path_;
463 }
464
465 /*
466 * Check the result of an earlier call to JNI_OnLoad on this library.
467 * If the call has not yet finished in another thread, wait for it.
468 */
CheckOnLoadResult()469 bool CheckOnLoadResult()
470 LOCKS_EXCLUDED(jni_on_load_lock_)
471 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
472 Thread* self = Thread::Current();
473 self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
474 bool okay;
475 {
476 MutexLock mu(self, jni_on_load_lock_);
477
478 if (jni_on_load_thread_id_ == self->GetThinLockId()) {
479 // Check this so we don't end up waiting for ourselves. We need to return "true" so the
480 // caller can continue.
481 LOG(INFO) << *self << " recursive attempt to load library " << "\"" << path_ << "\"";
482 okay = true;
483 } else {
484 while (jni_on_load_result_ == kPending) {
485 VLOG(jni) << "[" << *self << " waiting for \"" << path_ << "\" " << "JNI_OnLoad...]";
486 jni_on_load_cond_.Wait(self);
487 }
488
489 okay = (jni_on_load_result_ == kOkay);
490 VLOG(jni) << "[Earlier JNI_OnLoad for \"" << path_ << "\" "
491 << (okay ? "succeeded" : "failed") << "]";
492 }
493 }
494 self->TransitionFromSuspendedToRunnable();
495 return okay;
496 }
497
SetResult(bool result)498 void SetResult(bool result) LOCKS_EXCLUDED(jni_on_load_lock_) {
499 Thread* self = Thread::Current();
500 MutexLock mu(self, jni_on_load_lock_);
501
502 jni_on_load_result_ = result ? kOkay : kFailed;
503 jni_on_load_thread_id_ = 0;
504
505 // Broadcast a wakeup to anybody sleeping on the condition variable.
506 jni_on_load_cond_.Broadcast(self);
507 }
508
FindSymbol(const std::string & symbol_name)509 void* FindSymbol(const std::string& symbol_name) {
510 return dlsym(handle_, symbol_name.c_str());
511 }
512
513 private:
514 enum JNI_OnLoadState {
515 kPending,
516 kFailed,
517 kOkay,
518 };
519
520 // Path to library "/system/lib/libjni.so".
521 std::string path_;
522
523 // The void* returned by dlopen(3).
524 void* handle_;
525
526 // The ClassLoader this library is associated with.
527 Object* class_loader_;
528
529 // Guards remaining items.
530 Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
531 // Wait for JNI_OnLoad in other thread.
532 ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
533 // Recursive invocation guard.
534 uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
535 // Result of earlier JNI_OnLoad call.
536 JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
537 };
538
539 // This exists mainly to keep implementation details out of the header file.
540 class Libraries {
541 public:
Libraries()542 Libraries() {
543 }
544
~Libraries()545 ~Libraries() {
546 STLDeleteValues(&libraries_);
547 }
548
Dump(std::ostream & os) const549 void Dump(std::ostream& os) const {
550 bool first = true;
551 for (const auto& library : libraries_) {
552 if (!first) {
553 os << ' ';
554 }
555 first = false;
556 os << library.first;
557 }
558 }
559
size() const560 size_t size() const {
561 return libraries_.size();
562 }
563
Get(const std::string & path)564 SharedLibrary* Get(const std::string& path) {
565 auto it = libraries_.find(path);
566 return (it == libraries_.end()) ? NULL : it->second;
567 }
568
Put(const std::string & path,SharedLibrary * library)569 void Put(const std::string& path, SharedLibrary* library) {
570 libraries_.Put(path, library);
571 }
572
573 // See section 11.3 "Linking Native Methods" of the JNI spec.
FindNativeMethod(const ArtMethod * m,std::string & detail)574 void* FindNativeMethod(const ArtMethod* m, std::string& detail)
575 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
576 std::string jni_short_name(JniShortName(m));
577 std::string jni_long_name(JniLongName(m));
578 const ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
579 for (const auto& lib : libraries_) {
580 SharedLibrary* library = lib.second;
581 if (library->GetClassLoader() != declaring_class_loader) {
582 // We only search libraries loaded by the appropriate ClassLoader.
583 continue;
584 }
585 // Try the short name then the long name...
586 void* fn = library->FindSymbol(jni_short_name);
587 if (fn == NULL) {
588 fn = library->FindSymbol(jni_long_name);
589 }
590 if (fn != NULL) {
591 VLOG(jni) << "[Found native code for " << PrettyMethod(m)
592 << " in \"" << library->GetPath() << "\"]";
593 return fn;
594 }
595 }
596 detail += "No implementation found for ";
597 detail += PrettyMethod(m);
598 detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
599 LOG(ERROR) << detail;
600 return NULL;
601 }
602
603 private:
604 SafeMap<std::string, SharedLibrary*> libraries_;
605 };
606
InvokeWithJValues(const ScopedObjectAccess & soa,jobject obj,jmethodID mid,jvalue * args)607 JValue InvokeWithJValues(const ScopedObjectAccess& soa, jobject obj, jmethodID mid,
608 jvalue* args) {
609 ArtMethod* method = soa.DecodeMethod(mid);
610 Object* receiver = method->IsStatic() ? NULL : soa.Decode<Object*>(obj);
611 MethodHelper mh(method);
612 JValue result;
613 ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
614 arg_array.BuildArgArray(soa, receiver, args);
615 InvokeWithArgArray(soa, method, &arg_array, &result, mh.GetShorty()[0]);
616 return result;
617 }
618
619 #define CHECK_NON_NULL_ARGUMENT(fn, value) \
620 if (UNLIKELY(value == NULL)) { \
621 JniAbortF(#fn, #value " == null"); \
622 }
623
624 #define CHECK_NON_NULL_MEMCPY_ARGUMENT(fn, length, value) \
625 if (UNLIKELY(length != 0 && value == NULL)) { \
626 JniAbortF(#fn, #value " == null"); \
627 }
628
629 class JNI {
630 public:
GetVersion(JNIEnv *)631 static jint GetVersion(JNIEnv*) {
632 return JNI_VERSION_1_6;
633 }
634
DefineClass(JNIEnv *,const char *,jobject,const jbyte *,jsize)635 static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
636 LOG(WARNING) << "JNI DefineClass is not supported";
637 return NULL;
638 }
639
FindClass(JNIEnv * env,const char * name)640 static jclass FindClass(JNIEnv* env, const char* name) {
641 CHECK_NON_NULL_ARGUMENT(FindClass, name);
642 Runtime* runtime = Runtime::Current();
643 ClassLinker* class_linker = runtime->GetClassLinker();
644 std::string descriptor(NormalizeJniClassDescriptor(name));
645 ScopedObjectAccess soa(env);
646 Class* c = NULL;
647 if (runtime->IsStarted()) {
648 ClassLoader* cl = GetClassLoader(soa);
649 c = class_linker->FindClass(descriptor.c_str(), cl);
650 } else {
651 c = class_linker->FindSystemClass(descriptor.c_str());
652 }
653 return soa.AddLocalReference<jclass>(c);
654 }
655
FromReflectedMethod(JNIEnv * env,jobject java_method)656 static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) {
657 CHECK_NON_NULL_ARGUMENT(FromReflectedMethod, java_method);
658 ScopedObjectAccess soa(env);
659 jobject art_method = env->GetObjectField(java_method,
660 WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod);
661 ArtMethod* method = soa.Decode<ArtMethod*>(art_method);
662 DCHECK(method != NULL);
663 return soa.EncodeMethod(method);
664 }
665
FromReflectedField(JNIEnv * env,jobject java_field)666 static jfieldID FromReflectedField(JNIEnv* env, jobject java_field) {
667 CHECK_NON_NULL_ARGUMENT(FromReflectedField, java_field);
668 ScopedObjectAccess soa(env);
669 jobject art_field = env->GetObjectField(java_field,
670 WellKnownClasses::java_lang_reflect_Field_artField);
671 ArtField* field = soa.Decode<ArtField*>(art_field);
672 DCHECK(field != NULL);
673 return soa.EncodeField(field);
674 }
675
ToReflectedMethod(JNIEnv * env,jclass,jmethodID mid,jboolean)676 static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
677 CHECK_NON_NULL_ARGUMENT(ToReflectedMethod, mid);
678 ScopedObjectAccess soa(env);
679 ArtMethod* m = soa.DecodeMethod(mid);
680 jobject art_method = soa.AddLocalReference<jobject>(m);
681 jobject reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);
682 if (env->ExceptionCheck()) {
683 return NULL;
684 }
685 SetObjectField(env,
686 reflect_method,
687 WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod,
688 art_method);
689 return reflect_method;
690 }
691
ToReflectedField(JNIEnv * env,jclass,jfieldID fid,jboolean)692 static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
693 CHECK_NON_NULL_ARGUMENT(ToReflectedField, fid);
694 ScopedObjectAccess soa(env);
695 ArtField* f = soa.DecodeField(fid);
696 jobject art_field = soa.AddLocalReference<jobject>(f);
697 jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
698 if (env->ExceptionCheck()) {
699 return NULL;
700 }
701 SetObjectField(env,
702 reflect_field,
703 WellKnownClasses::java_lang_reflect_Field_artField,
704 art_field);
705 return reflect_field;
706 }
707
GetObjectClass(JNIEnv * env,jobject java_object)708 static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
709 CHECK_NON_NULL_ARGUMENT(GetObjectClass, java_object);
710 ScopedObjectAccess soa(env);
711 Object* o = soa.Decode<Object*>(java_object);
712 return soa.AddLocalReference<jclass>(o->GetClass());
713 }
714
GetSuperclass(JNIEnv * env,jclass java_class)715 static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
716 CHECK_NON_NULL_ARGUMENT(GetSuperclass, java_class);
717 ScopedObjectAccess soa(env);
718 Class* c = soa.Decode<Class*>(java_class);
719 return soa.AddLocalReference<jclass>(c->GetSuperClass());
720 }
721
IsAssignableFrom(JNIEnv * env,jclass java_class1,jclass java_class2)722 static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
723 CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class1);
724 CHECK_NON_NULL_ARGUMENT(IsAssignableFrom, java_class2);
725 ScopedObjectAccess soa(env);
726 Class* c1 = soa.Decode<Class*>(java_class1);
727 Class* c2 = soa.Decode<Class*>(java_class2);
728 return c1->IsAssignableFrom(c2) ? JNI_TRUE : JNI_FALSE;
729 }
730
IsInstanceOf(JNIEnv * env,jobject jobj,jclass java_class)731 static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
732 CHECK_NON_NULL_ARGUMENT(IsInstanceOf, java_class);
733 if (jobj == NULL) {
734 // Note: JNI is different from regular Java instanceof in this respect
735 return JNI_TRUE;
736 } else {
737 ScopedObjectAccess soa(env);
738 Object* obj = soa.Decode<Object*>(jobj);
739 Class* c = soa.Decode<Class*>(java_class);
740 return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
741 }
742 }
743
Throw(JNIEnv * env,jthrowable java_exception)744 static jint Throw(JNIEnv* env, jthrowable java_exception) {
745 ScopedObjectAccess soa(env);
746 Throwable* exception = soa.Decode<Throwable*>(java_exception);
747 if (exception == NULL) {
748 return JNI_ERR;
749 }
750 ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
751 soa.Self()->SetException(throw_location, exception);
752 return JNI_OK;
753 }
754
ThrowNew(JNIEnv * env,jclass c,const char * msg)755 static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
756 CHECK_NON_NULL_ARGUMENT(ThrowNew, c);
757 return ThrowNewException(env, c, msg, NULL);
758 }
759
ExceptionCheck(JNIEnv * env)760 static jboolean ExceptionCheck(JNIEnv* env) {
761 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
762 }
763
ExceptionClear(JNIEnv * env)764 static void ExceptionClear(JNIEnv* env) {
765 static_cast<JNIEnvExt*>(env)->self->ClearException();
766 }
767
ExceptionDescribe(JNIEnv * env)768 static void ExceptionDescribe(JNIEnv* env) {
769 ScopedObjectAccess soa(env);
770
771 SirtRef<Object> old_throw_this_object(soa.Self(), NULL);
772 SirtRef<ArtMethod> old_throw_method(soa.Self(), NULL);
773 SirtRef<Throwable> old_exception(soa.Self(), NULL);
774 uint32_t old_throw_dex_pc;
775 {
776 ThrowLocation old_throw_location;
777 Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location);
778 old_throw_this_object.reset(old_throw_location.GetThis());
779 old_throw_method.reset(old_throw_location.GetMethod());
780 old_exception.reset(old_exception_obj);
781 old_throw_dex_pc = old_throw_location.GetDexPc();
782 soa.Self()->ClearException();
783 }
784 ScopedLocalRef<jthrowable> exception(env, soa.AddLocalReference<jthrowable>(old_exception.get()));
785 ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
786 jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
787 if (mid == NULL) {
788 LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
789 << PrettyTypeOf(old_exception.get());
790 } else {
791 env->CallVoidMethod(exception.get(), mid);
792 if (soa.Self()->IsExceptionPending()) {
793 LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(NULL))
794 << " thrown while calling printStackTrace";
795 soa.Self()->ClearException();
796 }
797 }
798 ThrowLocation gc_safe_throw_location(old_throw_this_object.get(), old_throw_method.get(),
799 old_throw_dex_pc);
800
801 soa.Self()->SetException(gc_safe_throw_location, old_exception.get());
802 }
803
ExceptionOccurred(JNIEnv * env)804 static jthrowable ExceptionOccurred(JNIEnv* env) {
805 ScopedObjectAccess soa(env);
806 Object* exception = soa.Self()->GetException(NULL);
807 return soa.AddLocalReference<jthrowable>(exception);
808 }
809
FatalError(JNIEnv *,const char * msg)810 static void FatalError(JNIEnv*, const char* msg) {
811 LOG(FATAL) << "JNI FatalError called: " << msg;
812 }
813
PushLocalFrame(JNIEnv * env,jint capacity)814 static jint PushLocalFrame(JNIEnv* env, jint capacity) {
815 if (EnsureLocalCapacity(env, capacity, "PushLocalFrame") != JNI_OK) {
816 return JNI_ERR;
817 }
818 static_cast<JNIEnvExt*>(env)->PushFrame(capacity);
819 return JNI_OK;
820 }
821
PopLocalFrame(JNIEnv * env,jobject java_survivor)822 static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
823 ScopedObjectAccess soa(env);
824 Object* survivor = soa.Decode<Object*>(java_survivor);
825 soa.Env()->PopFrame();
826 return soa.AddLocalReference<jobject>(survivor);
827 }
828
EnsureLocalCapacity(JNIEnv * env,jint desired_capacity)829 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
830 return EnsureLocalCapacity(env, desired_capacity, "EnsureLocalCapacity");
831 }
832
NewGlobalRef(JNIEnv * env,jobject obj)833 static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
834 ScopedObjectAccess soa(env);
835 Object* decoded_obj = soa.Decode<Object*>(obj);
836 // Check for null after decoding the object to handle cleared weak globals.
837 if (decoded_obj == nullptr) {
838 return nullptr;
839 }
840 JavaVMExt* vm = soa.Vm();
841 IndirectReferenceTable& globals = vm->globals;
842 WriterMutexLock mu(soa.Self(), vm->globals_lock);
843 IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
844 return reinterpret_cast<jobject>(ref);
845 }
846
DeleteGlobalRef(JNIEnv * env,jobject obj)847 static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
848 if (obj == NULL) {
849 return;
850 }
851 JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
852 IndirectReferenceTable& globals = vm->globals;
853 Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
854 WriterMutexLock mu(self, vm->globals_lock);
855
856 if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
857 LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
858 << "failed to find entry";
859 }
860 }
861
NewWeakGlobalRef(JNIEnv * env,jobject obj)862 static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
863 ScopedObjectAccess soa(env);
864 return AddWeakGlobalReference(soa, soa.Decode<Object*>(obj));
865 }
866
DeleteWeakGlobalRef(JNIEnv * env,jweak obj)867 static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
868 if (obj != nullptr) {
869 ScopedObjectAccess soa(env);
870 soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
871 }
872 }
873
NewLocalRef(JNIEnv * env,jobject obj)874 static jobject NewLocalRef(JNIEnv* env, jobject obj) {
875 ScopedObjectAccess soa(env);
876 mirror::Object* decoded_obj = soa.Decode<Object*>(obj);
877 // Check for null after decoding the object to handle cleared weak globals.
878 if (decoded_obj == nullptr) {
879 return nullptr;
880 }
881 return soa.AddLocalReference<jobject>(decoded_obj);
882 }
883
DeleteLocalRef(JNIEnv * env,jobject obj)884 static void DeleteLocalRef(JNIEnv* env, jobject obj) {
885 if (obj == NULL) {
886 return;
887 }
888 IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
889
890 uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
891 if (!locals.Remove(cookie, obj)) {
892 // Attempting to delete a local reference that is not in the
893 // topmost local reference frame is a no-op. DeleteLocalRef returns
894 // void and doesn't throw any exceptions, but we should probably
895 // complain about it so the user will notice that things aren't
896 // going quite the way they expect.
897 LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
898 << "failed to find entry";
899 }
900 }
901
IsSameObject(JNIEnv * env,jobject obj1,jobject obj2)902 static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
903 if (obj1 == obj2) {
904 return JNI_TRUE;
905 } else {
906 ScopedObjectAccess soa(env);
907 return (soa.Decode<Object*>(obj1) == soa.Decode<Object*>(obj2)) ? JNI_TRUE : JNI_FALSE;
908 }
909 }
910
AllocObject(JNIEnv * env,jclass java_class)911 static jobject AllocObject(JNIEnv* env, jclass java_class) {
912 CHECK_NON_NULL_ARGUMENT(AllocObject, java_class);
913 ScopedObjectAccess soa(env);
914 Class* c = soa.Decode<Class*>(java_class);
915 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
916 return NULL;
917 }
918 return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
919 }
920
NewObject(JNIEnv * env,jclass java_class,jmethodID mid,...)921 static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
922 va_list args;
923 va_start(args, mid);
924 CHECK_NON_NULL_ARGUMENT(NewObject, java_class);
925 CHECK_NON_NULL_ARGUMENT(NewObject, mid);
926 jobject result = NewObjectV(env, java_class, mid, args);
927 va_end(args);
928 return result;
929 }
930
NewObjectV(JNIEnv * env,jclass java_class,jmethodID mid,va_list args)931 static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
932 CHECK_NON_NULL_ARGUMENT(NewObjectV, java_class);
933 CHECK_NON_NULL_ARGUMENT(NewObjectV, mid);
934 ScopedObjectAccess soa(env);
935 Class* c = soa.Decode<Class*>(java_class);
936 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
937 return NULL;
938 }
939 Object* result = c->AllocObject(soa.Self());
940 if (result == NULL) {
941 return NULL;
942 }
943 jobject local_result = soa.AddLocalReference<jobject>(result);
944 CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
945 if (!soa.Self()->IsExceptionPending()) {
946 return local_result;
947 } else {
948 return NULL;
949 }
950 }
951
NewObjectA(JNIEnv * env,jclass java_class,jmethodID mid,jvalue * args)952 static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
953 CHECK_NON_NULL_ARGUMENT(NewObjectA, java_class);
954 CHECK_NON_NULL_ARGUMENT(NewObjectA, mid);
955 ScopedObjectAccess soa(env);
956 Class* c = soa.Decode<Class*>(java_class);
957 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
958 return NULL;
959 }
960 Object* result = c->AllocObject(soa.Self());
961 if (result == NULL) {
962 return NULL;
963 }
964 jobject local_result = soa.AddLocalReference<jobjectArray>(result);
965 CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
966 if (!soa.Self()->IsExceptionPending()) {
967 return local_result;
968 } else {
969 return NULL;
970 }
971 }
972
GetMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)973 static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
974 CHECK_NON_NULL_ARGUMENT(GetMethodID, java_class);
975 CHECK_NON_NULL_ARGUMENT(GetMethodID, name);
976 CHECK_NON_NULL_ARGUMENT(GetMethodID, sig);
977 ScopedObjectAccess soa(env);
978 return FindMethodID(soa, java_class, name, sig, false);
979 }
980
GetStaticMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)981 static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
982 const char* sig) {
983 CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, java_class);
984 CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, name);
985 CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, sig);
986 ScopedObjectAccess soa(env);
987 return FindMethodID(soa, java_class, name, sig, true);
988 }
989
CallObjectMethod(JNIEnv * env,jobject obj,jmethodID mid,...)990 static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
991 va_list ap;
992 va_start(ap, mid);
993 CHECK_NON_NULL_ARGUMENT(CallObjectMethod, obj);
994 CHECK_NON_NULL_ARGUMENT(CallObjectMethod, mid);
995 ScopedObjectAccess soa(env);
996 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
997 va_end(ap);
998 return soa.AddLocalReference<jobject>(result.GetL());
999 }
1000
CallObjectMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1001 static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1002 CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, obj);
1003 CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, mid);
1004 ScopedObjectAccess soa(env);
1005 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
1006 return soa.AddLocalReference<jobject>(result.GetL());
1007 }
1008
CallObjectMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1009 static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1010 CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, obj);
1011 CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, mid);
1012 ScopedObjectAccess soa(env);
1013 JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
1014 return soa.AddLocalReference<jobject>(result.GetL());
1015 }
1016
CallBooleanMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1017 static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1018 va_list ap;
1019 va_start(ap, mid);
1020 CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, obj);
1021 CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, mid);
1022 ScopedObjectAccess soa(env);
1023 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1024 va_end(ap);
1025 return result.GetZ();
1026 }
1027
CallBooleanMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1028 static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1029 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, obj);
1030 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, mid);
1031 ScopedObjectAccess soa(env);
1032 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
1033 }
1034
CallBooleanMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1035 static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1036 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, obj);
1037 CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, mid);
1038 ScopedObjectAccess soa(env);
1039 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
1040 }
1041
CallByteMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1042 static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1043 va_list ap;
1044 va_start(ap, mid);
1045 CHECK_NON_NULL_ARGUMENT(CallByteMethod, obj);
1046 CHECK_NON_NULL_ARGUMENT(CallByteMethod, mid);
1047 ScopedObjectAccess soa(env);
1048 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1049 va_end(ap);
1050 return result.GetB();
1051 }
1052
CallByteMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1053 static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1054 CHECK_NON_NULL_ARGUMENT(CallByteMethodV, obj);
1055 CHECK_NON_NULL_ARGUMENT(CallByteMethodV, mid);
1056 ScopedObjectAccess soa(env);
1057 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
1058 }
1059
CallByteMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1060 static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1061 CHECK_NON_NULL_ARGUMENT(CallByteMethodA, obj);
1062 CHECK_NON_NULL_ARGUMENT(CallByteMethodA, mid);
1063 ScopedObjectAccess soa(env);
1064 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
1065 }
1066
CallCharMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1067 static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1068 va_list ap;
1069 va_start(ap, mid);
1070 CHECK_NON_NULL_ARGUMENT(CallCharMethod, obj);
1071 CHECK_NON_NULL_ARGUMENT(CallCharMethod, mid);
1072 ScopedObjectAccess soa(env);
1073 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1074 va_end(ap);
1075 return result.GetC();
1076 }
1077
CallCharMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1078 static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1079 CHECK_NON_NULL_ARGUMENT(CallCharMethodV, obj);
1080 CHECK_NON_NULL_ARGUMENT(CallCharMethodV, mid);
1081 ScopedObjectAccess soa(env);
1082 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
1083 }
1084
CallCharMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1085 static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1086 CHECK_NON_NULL_ARGUMENT(CallCharMethodA, obj);
1087 CHECK_NON_NULL_ARGUMENT(CallCharMethodA, mid);
1088 ScopedObjectAccess soa(env);
1089 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
1090 }
1091
CallDoubleMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1092 static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1093 va_list ap;
1094 va_start(ap, mid);
1095 CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, obj);
1096 CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, mid);
1097 ScopedObjectAccess soa(env);
1098 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1099 va_end(ap);
1100 return result.GetD();
1101 }
1102
CallDoubleMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1103 static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1104 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, obj);
1105 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, mid);
1106 ScopedObjectAccess soa(env);
1107 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
1108 }
1109
CallDoubleMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1110 static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1111 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, obj);
1112 CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, mid);
1113 ScopedObjectAccess soa(env);
1114 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
1115 }
1116
CallFloatMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1117 static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1118 va_list ap;
1119 va_start(ap, mid);
1120 CHECK_NON_NULL_ARGUMENT(CallFloatMethod, obj);
1121 CHECK_NON_NULL_ARGUMENT(CallFloatMethod, mid);
1122 ScopedObjectAccess soa(env);
1123 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1124 va_end(ap);
1125 return result.GetF();
1126 }
1127
CallFloatMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1128 static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1129 CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, obj);
1130 CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, mid);
1131 ScopedObjectAccess soa(env);
1132 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
1133 }
1134
CallFloatMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1135 static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1136 CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, obj);
1137 CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, mid);
1138 ScopedObjectAccess soa(env);
1139 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
1140 }
1141
CallIntMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1142 static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1143 va_list ap;
1144 va_start(ap, mid);
1145 CHECK_NON_NULL_ARGUMENT(CallIntMethod, obj);
1146 CHECK_NON_NULL_ARGUMENT(CallIntMethod, mid);
1147 ScopedObjectAccess soa(env);
1148 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1149 va_end(ap);
1150 return result.GetI();
1151 }
1152
CallIntMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1153 static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1154 CHECK_NON_NULL_ARGUMENT(CallIntMethodV, obj);
1155 CHECK_NON_NULL_ARGUMENT(CallIntMethodV, mid);
1156 ScopedObjectAccess soa(env);
1157 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
1158 }
1159
CallIntMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1160 static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1161 CHECK_NON_NULL_ARGUMENT(CallIntMethodA, obj);
1162 CHECK_NON_NULL_ARGUMENT(CallIntMethodA, mid);
1163 ScopedObjectAccess soa(env);
1164 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
1165 }
1166
CallLongMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1167 static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1168 va_list ap;
1169 va_start(ap, mid);
1170 CHECK_NON_NULL_ARGUMENT(CallLongMethod, obj);
1171 CHECK_NON_NULL_ARGUMENT(CallLongMethod, mid);
1172 ScopedObjectAccess soa(env);
1173 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1174 va_end(ap);
1175 return result.GetJ();
1176 }
1177
CallLongMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1178 static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1179 CHECK_NON_NULL_ARGUMENT(CallLongMethodV, obj);
1180 CHECK_NON_NULL_ARGUMENT(CallLongMethodV, mid);
1181 ScopedObjectAccess soa(env);
1182 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
1183 }
1184
CallLongMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1185 static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1186 CHECK_NON_NULL_ARGUMENT(CallLongMethodA, obj);
1187 CHECK_NON_NULL_ARGUMENT(CallLongMethodA, mid);
1188 ScopedObjectAccess soa(env);
1189 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
1190 }
1191
CallShortMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1192 static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1193 va_list ap;
1194 va_start(ap, mid);
1195 CHECK_NON_NULL_ARGUMENT(CallShortMethod, obj);
1196 CHECK_NON_NULL_ARGUMENT(CallShortMethod, mid);
1197 ScopedObjectAccess soa(env);
1198 JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1199 va_end(ap);
1200 return result.GetS();
1201 }
1202
CallShortMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1203 static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1204 CHECK_NON_NULL_ARGUMENT(CallShortMethodV, obj);
1205 CHECK_NON_NULL_ARGUMENT(CallShortMethodV, mid);
1206 ScopedObjectAccess soa(env);
1207 return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
1208 }
1209
CallShortMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1210 static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1211 CHECK_NON_NULL_ARGUMENT(CallShortMethodA, obj);
1212 CHECK_NON_NULL_ARGUMENT(CallShortMethodA, mid);
1213 ScopedObjectAccess soa(env);
1214 return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
1215 }
1216
CallVoidMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1217 static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1218 va_list ap;
1219 va_start(ap, mid);
1220 CHECK_NON_NULL_ARGUMENT(CallVoidMethod, obj);
1221 CHECK_NON_NULL_ARGUMENT(CallVoidMethod, mid);
1222 ScopedObjectAccess soa(env);
1223 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
1224 va_end(ap);
1225 }
1226
CallVoidMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1227 static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1228 CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, obj);
1229 CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, mid);
1230 ScopedObjectAccess soa(env);
1231 InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
1232 }
1233
CallVoidMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1234 static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1235 CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, obj);
1236 CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, mid);
1237 ScopedObjectAccess soa(env);
1238 InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
1239 }
1240
CallNonvirtualObjectMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1241 static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1242 va_list ap;
1243 va_start(ap, mid);
1244 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, obj);
1245 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, mid);
1246 ScopedObjectAccess soa(env);
1247 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1248 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1249 va_end(ap);
1250 return local_result;
1251 }
1252
CallNonvirtualObjectMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1253 static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1254 va_list args) {
1255 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, obj);
1256 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, mid);
1257 ScopedObjectAccess soa(env);
1258 JValue result(InvokeWithVarArgs(soa, obj, mid, args));
1259 return soa.AddLocalReference<jobject>(result.GetL());
1260 }
1261
CallNonvirtualObjectMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1262 static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1263 jvalue* args) {
1264 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, obj);
1265 CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, mid);
1266 ScopedObjectAccess soa(env);
1267 JValue result(InvokeWithJValues(soa, obj, mid, args));
1268 return soa.AddLocalReference<jobject>(result.GetL());
1269 }
1270
CallNonvirtualBooleanMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1271 static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1272 ...) {
1273 va_list ap;
1274 va_start(ap, mid);
1275 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, obj);
1276 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, mid);
1277 ScopedObjectAccess soa(env);
1278 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1279 va_end(ap);
1280 return result.GetZ();
1281 }
1282
CallNonvirtualBooleanMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1283 static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1284 va_list args) {
1285 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, obj);
1286 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, mid);
1287 ScopedObjectAccess soa(env);
1288 return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
1289 }
1290
CallNonvirtualBooleanMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1291 static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1292 jvalue* args) {
1293 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, obj);
1294 CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, mid);
1295 ScopedObjectAccess soa(env);
1296 return InvokeWithJValues(soa, obj, mid, args).GetZ();
1297 }
1298
CallNonvirtualByteMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1299 static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1300 va_list ap;
1301 va_start(ap, mid);
1302 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, obj);
1303 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, mid);
1304 ScopedObjectAccess soa(env);
1305 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1306 va_end(ap);
1307 return result.GetB();
1308 }
1309
CallNonvirtualByteMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1310 static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1311 va_list args) {
1312 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, obj);
1313 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, mid);
1314 ScopedObjectAccess soa(env);
1315 return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1316 }
1317
CallNonvirtualByteMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1318 static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1319 jvalue* args) {
1320 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, obj);
1321 CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, mid);
1322 ScopedObjectAccess soa(env);
1323 return InvokeWithJValues(soa, obj, mid, args).GetB();
1324 }
1325
CallNonvirtualCharMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1326 static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1327 va_list ap;
1328 va_start(ap, mid);
1329 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, obj);
1330 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, mid);
1331 ScopedObjectAccess soa(env);
1332 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1333 va_end(ap);
1334 return result.GetC();
1335 }
1336
CallNonvirtualCharMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1337 static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1338 va_list args) {
1339 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, obj);
1340 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, mid);
1341 ScopedObjectAccess soa(env);
1342 return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1343 }
1344
CallNonvirtualCharMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1345 static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1346 jvalue* args) {
1347 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, obj);
1348 CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, mid);
1349 ScopedObjectAccess soa(env);
1350 return InvokeWithJValues(soa, obj, mid, args).GetC();
1351 }
1352
CallNonvirtualShortMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1353 static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1354 va_list ap;
1355 va_start(ap, mid);
1356 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, obj);
1357 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, mid);
1358 ScopedObjectAccess soa(env);
1359 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1360 va_end(ap);
1361 return result.GetS();
1362 }
1363
CallNonvirtualShortMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1364 static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1365 va_list args) {
1366 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, obj);
1367 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, mid);
1368 ScopedObjectAccess soa(env);
1369 return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1370 }
1371
CallNonvirtualShortMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1372 static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1373 jvalue* args) {
1374 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, obj);
1375 CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, mid);
1376 ScopedObjectAccess soa(env);
1377 return InvokeWithJValues(soa, obj, mid, args).GetS();
1378 }
1379
CallNonvirtualIntMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1380 static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1381 va_list ap;
1382 va_start(ap, mid);
1383 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, obj);
1384 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, mid);
1385 ScopedObjectAccess soa(env);
1386 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1387 va_end(ap);
1388 return result.GetI();
1389 }
1390
CallNonvirtualIntMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1391 static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1392 va_list args) {
1393 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, obj);
1394 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, mid);
1395 ScopedObjectAccess soa(env);
1396 return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1397 }
1398
CallNonvirtualIntMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1399 static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1400 jvalue* args) {
1401 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, obj);
1402 CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, mid);
1403 ScopedObjectAccess soa(env);
1404 return InvokeWithJValues(soa, obj, mid, args).GetI();
1405 }
1406
CallNonvirtualLongMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1407 static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1408 va_list ap;
1409 va_start(ap, mid);
1410 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, obj);
1411 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, mid);
1412 ScopedObjectAccess soa(env);
1413 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1414 va_end(ap);
1415 return result.GetJ();
1416 }
1417
CallNonvirtualLongMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1418 static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1419 va_list args) {
1420 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, obj);
1421 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, mid);
1422 ScopedObjectAccess soa(env);
1423 return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1424 }
1425
CallNonvirtualLongMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1426 static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1427 jvalue* args) {
1428 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, obj);
1429 CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, mid);
1430 ScopedObjectAccess soa(env);
1431 return InvokeWithJValues(soa, obj, mid, args).GetJ();
1432 }
1433
CallNonvirtualFloatMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1434 static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1435 va_list ap;
1436 va_start(ap, mid);
1437 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, obj);
1438 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, mid);
1439 ScopedObjectAccess soa(env);
1440 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1441 va_end(ap);
1442 return result.GetF();
1443 }
1444
CallNonvirtualFloatMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1445 static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1446 va_list args) {
1447 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, obj);
1448 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, mid);
1449 ScopedObjectAccess soa(env);
1450 return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1451 }
1452
CallNonvirtualFloatMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1453 static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1454 jvalue* args) {
1455 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, obj);
1456 CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, mid);
1457 ScopedObjectAccess soa(env);
1458 return InvokeWithJValues(soa, obj, mid, args).GetF();
1459 }
1460
CallNonvirtualDoubleMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1461 static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1462 va_list ap;
1463 va_start(ap, mid);
1464 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, obj);
1465 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, mid);
1466 ScopedObjectAccess soa(env);
1467 JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1468 va_end(ap);
1469 return result.GetD();
1470 }
1471
CallNonvirtualDoubleMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1472 static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1473 va_list args) {
1474 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, obj);
1475 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, mid);
1476 ScopedObjectAccess soa(env);
1477 return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1478 }
1479
CallNonvirtualDoubleMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1480 static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1481 jvalue* args) {
1482 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, obj);
1483 CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, mid);
1484 ScopedObjectAccess soa(env);
1485 return InvokeWithJValues(soa, obj, mid, args).GetD();
1486 }
1487
CallNonvirtualVoidMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1488 static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1489 va_list ap;
1490 va_start(ap, mid);
1491 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, obj);
1492 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, mid);
1493 ScopedObjectAccess soa(env);
1494 InvokeWithVarArgs(soa, obj, mid, ap);
1495 va_end(ap);
1496 }
1497
CallNonvirtualVoidMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1498 static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1499 va_list args) {
1500 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, obj);
1501 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, mid);
1502 ScopedObjectAccess soa(env);
1503 InvokeWithVarArgs(soa, obj, mid, args);
1504 }
1505
CallNonvirtualVoidMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1506 static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1507 jvalue* args) {
1508 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, obj);
1509 CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, mid);
1510 ScopedObjectAccess soa(env);
1511 InvokeWithJValues(soa, obj, mid, args);
1512 }
1513
GetFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1514 static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1515 CHECK_NON_NULL_ARGUMENT(GetFieldID, java_class);
1516 CHECK_NON_NULL_ARGUMENT(GetFieldID, name);
1517 CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
1518 ScopedObjectAccess soa(env);
1519 return FindFieldID(soa, java_class, name, sig, false);
1520 }
1521
GetStaticFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1522 static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1523 const char* sig) {
1524 CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, java_class);
1525 CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, name);
1526 CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
1527 ScopedObjectAccess soa(env);
1528 return FindFieldID(soa, java_class, name, sig, true);
1529 }
1530
GetObjectField(JNIEnv * env,jobject obj,jfieldID fid)1531 static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
1532 CHECK_NON_NULL_ARGUMENT(GetObjectField, obj);
1533 CHECK_NON_NULL_ARGUMENT(GetObjectField, fid);
1534 ScopedObjectAccess soa(env);
1535 Object* o = soa.Decode<Object*>(obj);
1536 ArtField* f = soa.DecodeField(fid);
1537 return soa.AddLocalReference<jobject>(f->GetObject(o));
1538 }
1539
GetStaticObjectField(JNIEnv * env,jclass,jfieldID fid)1540 static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
1541 CHECK_NON_NULL_ARGUMENT(GetStaticObjectField, fid);
1542 ScopedObjectAccess soa(env);
1543 ArtField* f = soa.DecodeField(fid);
1544 return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1545 }
1546
SetObjectField(JNIEnv * env,jobject java_object,jfieldID fid,jobject java_value)1547 static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
1548 CHECK_NON_NULL_ARGUMENT(SetObjectField, java_object);
1549 CHECK_NON_NULL_ARGUMENT(SetObjectField, fid);
1550 ScopedObjectAccess soa(env);
1551 Object* o = soa.Decode<Object*>(java_object);
1552 Object* v = soa.Decode<Object*>(java_value);
1553 ArtField* f = soa.DecodeField(fid);
1554 f->SetObject(o, v);
1555 }
1556
SetStaticObjectField(JNIEnv * env,jclass,jfieldID fid,jobject java_value)1557 static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
1558 CHECK_NON_NULL_ARGUMENT(SetStaticObjectField, fid);
1559 ScopedObjectAccess soa(env);
1560 Object* v = soa.Decode<Object*>(java_value);
1561 ArtField* f = soa.DecodeField(fid);
1562 f->SetObject(f->GetDeclaringClass(), v);
1563 }
1564
1565 #define GET_PRIMITIVE_FIELD(fn, instance) \
1566 CHECK_NON_NULL_ARGUMENT(Get #fn Field, instance); \
1567 CHECK_NON_NULL_ARGUMENT(Get #fn Field, fid); \
1568 ScopedObjectAccess soa(env); \
1569 Object* o = soa.Decode<Object*>(instance); \
1570 ArtField* f = soa.DecodeField(fid); \
1571 return f->Get ##fn (o)
1572
1573 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
1574 CHECK_NON_NULL_ARGUMENT(GetStatic #fn Field, fid); \
1575 ScopedObjectAccess soa(env); \
1576 ArtField* f = soa.DecodeField(fid); \
1577 return f->Get ##fn (f->GetDeclaringClass())
1578
1579 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
1580 CHECK_NON_NULL_ARGUMENT(Set #fn Field, instance); \
1581 CHECK_NON_NULL_ARGUMENT(Set #fn Field, fid); \
1582 ScopedObjectAccess soa(env); \
1583 Object* o = soa.Decode<Object*>(instance); \
1584 ArtField* f = soa.DecodeField(fid); \
1585 f->Set ##fn(o, value)
1586
1587 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
1588 CHECK_NON_NULL_ARGUMENT(SetStatic #fn Field, fid); \
1589 ScopedObjectAccess soa(env); \
1590 ArtField* f = soa.DecodeField(fid); \
1591 f->Set ##fn(f->GetDeclaringClass(), value)
1592
GetBooleanField(JNIEnv * env,jobject obj,jfieldID fid)1593 static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1594 GET_PRIMITIVE_FIELD(Boolean, obj);
1595 }
1596
GetByteField(JNIEnv * env,jobject obj,jfieldID fid)1597 static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1598 GET_PRIMITIVE_FIELD(Byte, obj);
1599 }
1600
GetCharField(JNIEnv * env,jobject obj,jfieldID fid)1601 static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1602 GET_PRIMITIVE_FIELD(Char, obj);
1603 }
1604
GetShortField(JNIEnv * env,jobject obj,jfieldID fid)1605 static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1606 GET_PRIMITIVE_FIELD(Short, obj);
1607 }
1608
GetIntField(JNIEnv * env,jobject obj,jfieldID fid)1609 static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1610 GET_PRIMITIVE_FIELD(Int, obj);
1611 }
1612
GetLongField(JNIEnv * env,jobject obj,jfieldID fid)1613 static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1614 GET_PRIMITIVE_FIELD(Long, obj);
1615 }
1616
GetFloatField(JNIEnv * env,jobject obj,jfieldID fid)1617 static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1618 GET_PRIMITIVE_FIELD(Float, obj);
1619 }
1620
GetDoubleField(JNIEnv * env,jobject obj,jfieldID fid)1621 static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1622 GET_PRIMITIVE_FIELD(Double, obj);
1623 }
1624
GetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid)1625 static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1626 GET_STATIC_PRIMITIVE_FIELD(Boolean);
1627 }
1628
GetStaticByteField(JNIEnv * env,jclass,jfieldID fid)1629 static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1630 GET_STATIC_PRIMITIVE_FIELD(Byte);
1631 }
1632
GetStaticCharField(JNIEnv * env,jclass,jfieldID fid)1633 static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1634 GET_STATIC_PRIMITIVE_FIELD(Char);
1635 }
1636
GetStaticShortField(JNIEnv * env,jclass,jfieldID fid)1637 static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1638 GET_STATIC_PRIMITIVE_FIELD(Short);
1639 }
1640
GetStaticIntField(JNIEnv * env,jclass,jfieldID fid)1641 static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1642 GET_STATIC_PRIMITIVE_FIELD(Int);
1643 }
1644
GetStaticLongField(JNIEnv * env,jclass,jfieldID fid)1645 static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1646 GET_STATIC_PRIMITIVE_FIELD(Long);
1647 }
1648
GetStaticFloatField(JNIEnv * env,jclass,jfieldID fid)1649 static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1650 GET_STATIC_PRIMITIVE_FIELD(Float);
1651 }
1652
GetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid)1653 static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1654 GET_STATIC_PRIMITIVE_FIELD(Double);
1655 }
1656
SetBooleanField(JNIEnv * env,jobject obj,jfieldID fid,jboolean v)1657 static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1658 SET_PRIMITIVE_FIELD(Boolean, obj, v);
1659 }
1660
SetByteField(JNIEnv * env,jobject obj,jfieldID fid,jbyte v)1661 static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1662 SET_PRIMITIVE_FIELD(Byte, obj, v);
1663 }
1664
SetCharField(JNIEnv * env,jobject obj,jfieldID fid,jchar v)1665 static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1666 SET_PRIMITIVE_FIELD(Char, obj, v);
1667 }
1668
SetFloatField(JNIEnv * env,jobject obj,jfieldID fid,jfloat v)1669 static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1670 SET_PRIMITIVE_FIELD(Float, obj, v);
1671 }
1672
SetDoubleField(JNIEnv * env,jobject obj,jfieldID fid,jdouble v)1673 static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1674 SET_PRIMITIVE_FIELD(Double, obj, v);
1675 }
1676
SetIntField(JNIEnv * env,jobject obj,jfieldID fid,jint v)1677 static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1678 SET_PRIMITIVE_FIELD(Int, obj, v);
1679 }
1680
SetLongField(JNIEnv * env,jobject obj,jfieldID fid,jlong v)1681 static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1682 SET_PRIMITIVE_FIELD(Long, obj, v);
1683 }
1684
SetShortField(JNIEnv * env,jobject obj,jfieldID fid,jshort v)1685 static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1686 SET_PRIMITIVE_FIELD(Short, obj, v);
1687 }
1688
SetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid,jboolean v)1689 static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1690 SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1691 }
1692
SetStaticByteField(JNIEnv * env,jclass,jfieldID fid,jbyte v)1693 static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1694 SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1695 }
1696
SetStaticCharField(JNIEnv * env,jclass,jfieldID fid,jchar v)1697 static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1698 SET_STATIC_PRIMITIVE_FIELD(Char, v);
1699 }
1700
SetStaticFloatField(JNIEnv * env,jclass,jfieldID fid,jfloat v)1701 static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1702 SET_STATIC_PRIMITIVE_FIELD(Float, v);
1703 }
1704
SetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid,jdouble v)1705 static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1706 SET_STATIC_PRIMITIVE_FIELD(Double, v);
1707 }
1708
SetStaticIntField(JNIEnv * env,jclass,jfieldID fid,jint v)1709 static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1710 SET_STATIC_PRIMITIVE_FIELD(Int, v);
1711 }
1712
SetStaticLongField(JNIEnv * env,jclass,jfieldID fid,jlong v)1713 static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1714 SET_STATIC_PRIMITIVE_FIELD(Long, v);
1715 }
1716
SetStaticShortField(JNIEnv * env,jclass,jfieldID fid,jshort v)1717 static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1718 SET_STATIC_PRIMITIVE_FIELD(Short, v);
1719 }
1720
CallStaticObjectMethod(JNIEnv * env,jclass,jmethodID mid,...)1721 static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1722 va_list ap;
1723 va_start(ap, mid);
1724 CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethod, mid);
1725 ScopedObjectAccess soa(env);
1726 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1727 jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1728 va_end(ap);
1729 return local_result;
1730 }
1731
CallStaticObjectMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1732 static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1733 CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodV, mid);
1734 ScopedObjectAccess soa(env);
1735 JValue result(InvokeWithVarArgs(soa, NULL, mid, args));
1736 return soa.AddLocalReference<jobject>(result.GetL());
1737 }
1738
CallStaticObjectMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1739 static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1740 CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodA, mid);
1741 ScopedObjectAccess soa(env);
1742 JValue result(InvokeWithJValues(soa, NULL, mid, args));
1743 return soa.AddLocalReference<jobject>(result.GetL());
1744 }
1745
CallStaticBooleanMethod(JNIEnv * env,jclass,jmethodID mid,...)1746 static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1747 va_list ap;
1748 va_start(ap, mid);
1749 CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethod, mid);
1750 ScopedObjectAccess soa(env);
1751 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1752 va_end(ap);
1753 return result.GetZ();
1754 }
1755
CallStaticBooleanMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1756 static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1757 CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodV, mid);
1758 ScopedObjectAccess soa(env);
1759 return InvokeWithVarArgs(soa, NULL, mid, args).GetZ();
1760 }
1761
CallStaticBooleanMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1762 static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1763 CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodA, mid);
1764 ScopedObjectAccess soa(env);
1765 return InvokeWithJValues(soa, NULL, mid, args).GetZ();
1766 }
1767
CallStaticByteMethod(JNIEnv * env,jclass,jmethodID mid,...)1768 static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1769 va_list ap;
1770 va_start(ap, mid);
1771 CHECK_NON_NULL_ARGUMENT(CallStaticByteMethod, mid);
1772 ScopedObjectAccess soa(env);
1773 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1774 va_end(ap);
1775 return result.GetB();
1776 }
1777
CallStaticByteMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1778 static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1779 CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodV, mid);
1780 ScopedObjectAccess soa(env);
1781 return InvokeWithVarArgs(soa, NULL, mid, args).GetB();
1782 }
1783
CallStaticByteMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1784 static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1785 CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodA, mid);
1786 ScopedObjectAccess soa(env);
1787 return InvokeWithJValues(soa, NULL, mid, args).GetB();
1788 }
1789
CallStaticCharMethod(JNIEnv * env,jclass,jmethodID mid,...)1790 static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1791 va_list ap;
1792 va_start(ap, mid);
1793 CHECK_NON_NULL_ARGUMENT(CallStaticCharMethod, mid);
1794 ScopedObjectAccess soa(env);
1795 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1796 va_end(ap);
1797 return result.GetC();
1798 }
1799
CallStaticCharMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1800 static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1801 CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodV, mid);
1802 ScopedObjectAccess soa(env);
1803 return InvokeWithVarArgs(soa, NULL, mid, args).GetC();
1804 }
1805
CallStaticCharMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1806 static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1807 CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodA, mid);
1808 ScopedObjectAccess soa(env);
1809 return InvokeWithJValues(soa, NULL, mid, args).GetC();
1810 }
1811
CallStaticShortMethod(JNIEnv * env,jclass,jmethodID mid,...)1812 static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1813 va_list ap;
1814 va_start(ap, mid);
1815 CHECK_NON_NULL_ARGUMENT(CallStaticShortMethod, mid);
1816 ScopedObjectAccess soa(env);
1817 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1818 va_end(ap);
1819 return result.GetS();
1820 }
1821
CallStaticShortMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1822 static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1823 CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodV, mid);
1824 ScopedObjectAccess soa(env);
1825 return InvokeWithVarArgs(soa, NULL, mid, args).GetS();
1826 }
1827
CallStaticShortMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1828 static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1829 CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodA, mid);
1830 ScopedObjectAccess soa(env);
1831 return InvokeWithJValues(soa, NULL, mid, args).GetS();
1832 }
1833
CallStaticIntMethod(JNIEnv * env,jclass,jmethodID mid,...)1834 static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1835 va_list ap;
1836 va_start(ap, mid);
1837 CHECK_NON_NULL_ARGUMENT(CallStaticIntMethod, mid);
1838 ScopedObjectAccess soa(env);
1839 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1840 va_end(ap);
1841 return result.GetI();
1842 }
1843
CallStaticIntMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1844 static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1845 CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodV, mid);
1846 ScopedObjectAccess soa(env);
1847 return InvokeWithVarArgs(soa, NULL, mid, args).GetI();
1848 }
1849
CallStaticIntMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1850 static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1851 CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodA, mid);
1852 ScopedObjectAccess soa(env);
1853 return InvokeWithJValues(soa, NULL, mid, args).GetI();
1854 }
1855
CallStaticLongMethod(JNIEnv * env,jclass,jmethodID mid,...)1856 static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1857 va_list ap;
1858 va_start(ap, mid);
1859 CHECK_NON_NULL_ARGUMENT(CallStaticLongMethod, mid);
1860 ScopedObjectAccess soa(env);
1861 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1862 va_end(ap);
1863 return result.GetJ();
1864 }
1865
CallStaticLongMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1866 static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1867 CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodV, mid);
1868 ScopedObjectAccess soa(env);
1869 return InvokeWithVarArgs(soa, NULL, mid, args).GetJ();
1870 }
1871
CallStaticLongMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1872 static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1873 CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodA, mid);
1874 ScopedObjectAccess soa(env);
1875 return InvokeWithJValues(soa, NULL, mid, args).GetJ();
1876 }
1877
CallStaticFloatMethod(JNIEnv * env,jclass,jmethodID mid,...)1878 static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1879 va_list ap;
1880 va_start(ap, mid);
1881 CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethod, mid);
1882 ScopedObjectAccess soa(env);
1883 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1884 va_end(ap);
1885 return result.GetF();
1886 }
1887
CallStaticFloatMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1888 static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1889 CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodV, mid);
1890 ScopedObjectAccess soa(env);
1891 return InvokeWithVarArgs(soa, NULL, mid, args).GetF();
1892 }
1893
CallStaticFloatMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1894 static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1895 CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodA, mid);
1896 ScopedObjectAccess soa(env);
1897 return InvokeWithJValues(soa, NULL, mid, args).GetF();
1898 }
1899
CallStaticDoubleMethod(JNIEnv * env,jclass,jmethodID mid,...)1900 static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1901 va_list ap;
1902 va_start(ap, mid);
1903 CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethod, mid);
1904 ScopedObjectAccess soa(env);
1905 JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
1906 va_end(ap);
1907 return result.GetD();
1908 }
1909
CallStaticDoubleMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1910 static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1911 CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodV, mid);
1912 ScopedObjectAccess soa(env);
1913 return InvokeWithVarArgs(soa, NULL, mid, args).GetD();
1914 }
1915
CallStaticDoubleMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1916 static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1917 CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodA, mid);
1918 ScopedObjectAccess soa(env);
1919 return InvokeWithJValues(soa, NULL, mid, args).GetD();
1920 }
1921
CallStaticVoidMethod(JNIEnv * env,jclass,jmethodID mid,...)1922 static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1923 va_list ap;
1924 va_start(ap, mid);
1925 CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethod, mid);
1926 ScopedObjectAccess soa(env);
1927 InvokeWithVarArgs(soa, NULL, mid, ap);
1928 va_end(ap);
1929 }
1930
CallStaticVoidMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1931 static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1932 CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodV, mid);
1933 ScopedObjectAccess soa(env);
1934 InvokeWithVarArgs(soa, NULL, mid, args);
1935 }
1936
CallStaticVoidMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1937 static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1938 CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodA, mid);
1939 ScopedObjectAccess soa(env);
1940 InvokeWithJValues(soa, NULL, mid, args);
1941 }
1942
NewString(JNIEnv * env,const jchar * chars,jsize char_count)1943 static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
1944 if (UNLIKELY(chars == NULL && char_count > 0)) { \
1945 JniAbortF("NewString", "char == null && char_count > 0"); \
1946 }
1947 ScopedObjectAccess soa(env);
1948 String* result = String::AllocFromUtf16(soa.Self(), char_count, chars);
1949 return soa.AddLocalReference<jstring>(result);
1950 }
1951
NewStringUTF(JNIEnv * env,const char * utf)1952 static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1953 if (utf == NULL) {
1954 return NULL;
1955 }
1956 ScopedObjectAccess soa(env);
1957 String* result = String::AllocFromModifiedUtf8(soa.Self(), utf);
1958 return soa.AddLocalReference<jstring>(result);
1959 }
1960
GetStringLength(JNIEnv * env,jstring java_string)1961 static jsize GetStringLength(JNIEnv* env, jstring java_string) {
1962 CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
1963 ScopedObjectAccess soa(env);
1964 return soa.Decode<String*>(java_string)->GetLength();
1965 }
1966
GetStringUTFLength(JNIEnv * env,jstring java_string)1967 static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
1968 CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
1969 ScopedObjectAccess soa(env);
1970 return soa.Decode<String*>(java_string)->GetUtfLength();
1971 }
1972
GetStringRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,jchar * buf)1973 static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1974 jchar* buf) {
1975 CHECK_NON_NULL_ARGUMENT(GetStringRegion, java_string);
1976 ScopedObjectAccess soa(env);
1977 String* s = soa.Decode<String*>(java_string);
1978 if (start < 0 || length < 0 || start + length > s->GetLength()) {
1979 ThrowSIOOBE(soa, start, length, s->GetLength());
1980 } else {
1981 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
1982 const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1983 memcpy(buf, chars + start, length * sizeof(jchar));
1984 }
1985 }
1986
GetStringUTFRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,char * buf)1987 static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1988 char* buf) {
1989 CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
1990 ScopedObjectAccess soa(env);
1991 String* s = soa.Decode<String*>(java_string);
1992 if (start < 0 || length < 0 || start + length > s->GetLength()) {
1993 ThrowSIOOBE(soa, start, length, s->GetLength());
1994 } else {
1995 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringUTFRegion, length, buf);
1996 const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1997 ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1998 }
1999 }
2000
GetStringChars(JNIEnv * env,jstring java_string,jboolean * is_copy)2001 static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2002 CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
2003 ScopedObjectAccess soa(env);
2004 String* s = soa.Decode<String*>(java_string);
2005 const CharArray* chars = s->GetCharArray();
2006 PinPrimitiveArray(soa, chars);
2007 if (is_copy != NULL) {
2008 *is_copy = JNI_FALSE;
2009 }
2010 return chars->GetData() + s->GetOffset();
2011 }
2012
ReleaseStringChars(JNIEnv * env,jstring java_string,const jchar *)2013 static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar*) {
2014 CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
2015 ScopedObjectAccess soa(env);
2016 UnpinPrimitiveArray(soa, soa.Decode<String*>(java_string)->GetCharArray());
2017 }
2018
GetStringCritical(JNIEnv * env,jstring java_string,jboolean * is_copy)2019 static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2020 return GetStringChars(env, java_string, is_copy);
2021 }
2022
ReleaseStringCritical(JNIEnv * env,jstring java_string,const jchar * chars)2023 static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
2024 return ReleaseStringChars(env, java_string, chars);
2025 }
2026
GetStringUTFChars(JNIEnv * env,jstring java_string,jboolean * is_copy)2027 static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2028 if (java_string == NULL) {
2029 return NULL;
2030 }
2031 if (is_copy != NULL) {
2032 *is_copy = JNI_TRUE;
2033 }
2034 ScopedObjectAccess soa(env);
2035 String* s = soa.Decode<String*>(java_string);
2036 size_t byte_count = s->GetUtfLength();
2037 char* bytes = new char[byte_count + 1];
2038 CHECK(bytes != NULL); // bionic aborts anyway.
2039 const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
2040 ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
2041 bytes[byte_count] = '\0';
2042 return bytes;
2043 }
2044
ReleaseStringUTFChars(JNIEnv * env,jstring,const char * chars)2045 static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
2046 delete[] chars;
2047 }
2048
GetArrayLength(JNIEnv * env,jarray java_array)2049 static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
2050 CHECK_NON_NULL_ARGUMENT(GetArrayLength, java_array);
2051 ScopedObjectAccess soa(env);
2052 Object* obj = soa.Decode<Object*>(java_array);
2053 if (UNLIKELY(!obj->IsArrayInstance())) {
2054 JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
2055 }
2056 Array* array = obj->AsArray();
2057 return array->GetLength();
2058 }
2059
GetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index)2060 static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
2061 CHECK_NON_NULL_ARGUMENT(GetObjectArrayElement, java_array);
2062 ScopedObjectAccess soa(env);
2063 ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
2064 return soa.AddLocalReference<jobject>(array->Get(index));
2065 }
2066
SetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index,jobject java_value)2067 static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2068 jobject java_value) {
2069 CHECK_NON_NULL_ARGUMENT(SetObjectArrayElement, java_array);
2070 ScopedObjectAccess soa(env);
2071 ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
2072 Object* value = soa.Decode<Object*>(java_value);
2073 array->Set(index, value);
2074 }
2075
NewBooleanArray(JNIEnv * env,jsize length)2076 static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
2077 ScopedObjectAccess soa(env);
2078 return NewPrimitiveArray<jbooleanArray, BooleanArray>(soa, length);
2079 }
2080
NewByteArray(JNIEnv * env,jsize length)2081 static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
2082 ScopedObjectAccess soa(env);
2083 return NewPrimitiveArray<jbyteArray, ByteArray>(soa, length);
2084 }
2085
NewCharArray(JNIEnv * env,jsize length)2086 static jcharArray NewCharArray(JNIEnv* env, jsize length) {
2087 ScopedObjectAccess soa(env);
2088 return NewPrimitiveArray<jcharArray, CharArray>(soa, length);
2089 }
2090
NewDoubleArray(JNIEnv * env,jsize length)2091 static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
2092 ScopedObjectAccess soa(env);
2093 return NewPrimitiveArray<jdoubleArray, DoubleArray>(soa, length);
2094 }
2095
NewFloatArray(JNIEnv * env,jsize length)2096 static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
2097 ScopedObjectAccess soa(env);
2098 return NewPrimitiveArray<jfloatArray, FloatArray>(soa, length);
2099 }
2100
NewIntArray(JNIEnv * env,jsize length)2101 static jintArray NewIntArray(JNIEnv* env, jsize length) {
2102 ScopedObjectAccess soa(env);
2103 return NewPrimitiveArray<jintArray, IntArray>(soa, length);
2104 }
2105
NewLongArray(JNIEnv * env,jsize length)2106 static jlongArray NewLongArray(JNIEnv* env, jsize length) {
2107 ScopedObjectAccess soa(env);
2108 return NewPrimitiveArray<jlongArray, LongArray>(soa, length);
2109 }
2110
NewObjectArray(JNIEnv * env,jsize length,jclass element_jclass,jobject initial_element)2111 static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) {
2112 if (length < 0) {
2113 JniAbortF("NewObjectArray", "negative array length: %d", length);
2114 }
2115
2116 // Compute the array class corresponding to the given element class.
2117 ScopedObjectAccess soa(env);
2118 Class* element_class = soa.Decode<Class*>(element_jclass);
2119 std::string descriptor;
2120 descriptor += "[";
2121 descriptor += ClassHelper(element_class).GetDescriptor();
2122
2123 // Find the class.
2124 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2125 Class* array_class = class_linker->FindClass(descriptor.c_str(),
2126 element_class->GetClassLoader());
2127 if (array_class == NULL) {
2128 return NULL;
2129 }
2130
2131 // Allocate and initialize if necessary.
2132 ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length);
2133 if (initial_element != NULL) {
2134 Object* initial_object = soa.Decode<Object*>(initial_element);
2135 for (jsize i = 0; i < length; ++i) {
2136 result->Set(i, initial_object);
2137 }
2138 }
2139 return soa.AddLocalReference<jobjectArray>(result);
2140 }
2141
NewShortArray(JNIEnv * env,jsize length)2142 static jshortArray NewShortArray(JNIEnv* env, jsize length) {
2143 ScopedObjectAccess soa(env);
2144 return NewPrimitiveArray<jshortArray, ShortArray>(soa, length);
2145 }
2146
GetPrimitiveArrayCritical(JNIEnv * env,jarray java_array,jboolean * is_copy)2147 static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
2148 CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayCritical, java_array);
2149 ScopedObjectAccess soa(env);
2150 Array* array = soa.Decode<Array*>(java_array);
2151 PinPrimitiveArray(soa, array);
2152 if (is_copy != NULL) {
2153 *is_copy = JNI_FALSE;
2154 }
2155 return array->GetRawData(array->GetClass()->GetComponentSize());
2156 }
2157
ReleasePrimitiveArrayCritical(JNIEnv * env,jarray array,void *,jint mode)2158 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void*, jint mode) {
2159 CHECK_NON_NULL_ARGUMENT(ReleasePrimitiveArrayCritical, array);
2160 ReleasePrimitiveArray(env, array, mode);
2161 }
2162
GetBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * is_copy)2163 static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
2164 CHECK_NON_NULL_ARGUMENT(GetBooleanArrayElements, array);
2165 ScopedObjectAccess soa(env);
2166 return GetPrimitiveArray<jbooleanArray, jboolean*, BooleanArray>(soa, array, is_copy);
2167 }
2168
GetByteArrayElements(JNIEnv * env,jbyteArray array,jboolean * is_copy)2169 static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
2170 CHECK_NON_NULL_ARGUMENT(GetByteArrayElements, array);
2171 ScopedObjectAccess soa(env);
2172 return GetPrimitiveArray<jbyteArray, jbyte*, ByteArray>(soa, array, is_copy);
2173 }
2174
GetCharArrayElements(JNIEnv * env,jcharArray array,jboolean * is_copy)2175 static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
2176 CHECK_NON_NULL_ARGUMENT(GetCharArrayElements, array);
2177 ScopedObjectAccess soa(env);
2178 return GetPrimitiveArray<jcharArray, jchar*, CharArray>(soa, array, is_copy);
2179 }
2180
GetDoubleArrayElements(JNIEnv * env,jdoubleArray array,jboolean * is_copy)2181 static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
2182 CHECK_NON_NULL_ARGUMENT(GetDoubleArrayElements, array);
2183 ScopedObjectAccess soa(env);
2184 return GetPrimitiveArray<jdoubleArray, jdouble*, DoubleArray>(soa, array, is_copy);
2185 }
2186
GetFloatArrayElements(JNIEnv * env,jfloatArray array,jboolean * is_copy)2187 static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
2188 CHECK_NON_NULL_ARGUMENT(GetFloatArrayElements, array);
2189 ScopedObjectAccess soa(env);
2190 return GetPrimitiveArray<jfloatArray, jfloat*, FloatArray>(soa, array, is_copy);
2191 }
2192
GetIntArrayElements(JNIEnv * env,jintArray array,jboolean * is_copy)2193 static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
2194 CHECK_NON_NULL_ARGUMENT(GetIntArrayElements, array);
2195 ScopedObjectAccess soa(env);
2196 return GetPrimitiveArray<jintArray, jint*, IntArray>(soa, array, is_copy);
2197 }
2198
GetLongArrayElements(JNIEnv * env,jlongArray array,jboolean * is_copy)2199 static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
2200 CHECK_NON_NULL_ARGUMENT(GetLongArrayElements, array);
2201 ScopedObjectAccess soa(env);
2202 return GetPrimitiveArray<jlongArray, jlong*, LongArray>(soa, array, is_copy);
2203 }
2204
GetShortArrayElements(JNIEnv * env,jshortArray array,jboolean * is_copy)2205 static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
2206 CHECK_NON_NULL_ARGUMENT(GetShortArrayElements, array);
2207 ScopedObjectAccess soa(env);
2208 return GetPrimitiveArray<jshortArray, jshort*, ShortArray>(soa, array, is_copy);
2209 }
2210
ReleaseBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean *,jint mode)2211 static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean*, jint mode) {
2212 ReleasePrimitiveArray(env, array, mode);
2213 }
2214
ReleaseByteArrayElements(JNIEnv * env,jbyteArray array,jbyte *,jint mode)2215 static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte*, jint mode) {
2216 ReleasePrimitiveArray(env, array, mode);
2217 }
2218
ReleaseCharArrayElements(JNIEnv * env,jcharArray array,jchar *,jint mode)2219 static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar*, jint mode) {
2220 ReleasePrimitiveArray(env, array, mode);
2221 }
2222
ReleaseDoubleArrayElements(JNIEnv * env,jdoubleArray array,jdouble *,jint mode)2223 static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble*, jint mode) {
2224 ReleasePrimitiveArray(env, array, mode);
2225 }
2226
ReleaseFloatArrayElements(JNIEnv * env,jfloatArray array,jfloat *,jint mode)2227 static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat*, jint mode) {
2228 ReleasePrimitiveArray(env, array, mode);
2229 }
2230
ReleaseIntArrayElements(JNIEnv * env,jintArray array,jint *,jint mode)2231 static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint*, jint mode) {
2232 ReleasePrimitiveArray(env, array, mode);
2233 }
2234
ReleaseLongArrayElements(JNIEnv * env,jlongArray array,jlong *,jint mode)2235 static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong*, jint mode) {
2236 ReleasePrimitiveArray(env, array, mode);
2237 }
2238
ReleaseShortArrayElements(JNIEnv * env,jshortArray array,jshort *,jint mode)2239 static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort*, jint mode) {
2240 ReleasePrimitiveArray(env, array, mode);
2241 }
2242
GetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,jboolean * buf)2243 static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2244 jboolean* buf) {
2245 ScopedObjectAccess soa(env);
2246 GetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
2247 }
2248
GetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,jbyte * buf)2249 static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2250 jbyte* buf) {
2251 ScopedObjectAccess soa(env);
2252 GetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
2253 }
2254
GetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,jchar * buf)2255 static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2256 jchar* buf) {
2257 ScopedObjectAccess soa(env);
2258 GetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
2259 }
2260
GetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,jdouble * buf)2261 static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2262 jdouble* buf) {
2263 ScopedObjectAccess soa(env);
2264 GetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
2265 }
2266
GetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,jfloat * buf)2267 static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2268 jfloat* buf) {
2269 ScopedObjectAccess soa(env);
2270 GetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
2271 }
2272
GetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,jint * buf)2273 static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2274 jint* buf) {
2275 ScopedObjectAccess soa(env);
2276 GetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
2277 }
2278
GetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,jlong * buf)2279 static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2280 jlong* buf) {
2281 ScopedObjectAccess soa(env);
2282 GetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
2283 }
2284
GetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,jshort * buf)2285 static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2286 jshort* buf) {
2287 ScopedObjectAccess soa(env);
2288 GetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
2289 }
2290
SetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,const jboolean * buf)2291 static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2292 const jboolean* buf) {
2293 ScopedObjectAccess soa(env);
2294 SetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
2295 }
2296
SetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,const jbyte * buf)2297 static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2298 const jbyte* buf) {
2299 ScopedObjectAccess soa(env);
2300 SetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
2301 }
2302
SetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,const jchar * buf)2303 static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2304 const jchar* buf) {
2305 ScopedObjectAccess soa(env);
2306 SetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
2307 }
2308
SetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,const jdouble * buf)2309 static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2310 const jdouble* buf) {
2311 ScopedObjectAccess soa(env);
2312 SetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
2313 }
2314
SetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,const jfloat * buf)2315 static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2316 const jfloat* buf) {
2317 ScopedObjectAccess soa(env);
2318 SetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
2319 }
2320
SetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,const jint * buf)2321 static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2322 const jint* buf) {
2323 ScopedObjectAccess soa(env);
2324 SetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
2325 }
2326
SetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,const jlong * buf)2327 static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2328 const jlong* buf) {
2329 ScopedObjectAccess soa(env);
2330 SetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
2331 }
2332
SetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,const jshort * buf)2333 static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2334 const jshort* buf) {
2335 ScopedObjectAccess soa(env);
2336 SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
2337 }
2338
RegisterNatives(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count)2339 static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2340 jint method_count) {
2341 return RegisterNativeMethods(env, java_class, methods, method_count, true);
2342 }
2343
RegisterNativeMethods(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count,bool return_errors)2344 static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2345 jint method_count, bool return_errors) {
2346 if (UNLIKELY(method_count < 0)) {
2347 JniAbortF("RegisterNatives", "negative method count: %d", method_count);
2348 return JNI_ERR; // Not reached.
2349 }
2350 CHECK_NON_NULL_ARGUMENT(RegisterNatives, java_class);
2351 ScopedObjectAccess soa(env);
2352 Class* c = soa.Decode<Class*>(java_class);
2353 if (UNLIKELY(method_count == 0)) {
2354 LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2355 << PrettyDescriptor(c);
2356 return JNI_OK;
2357 }
2358 CHECK_NON_NULL_ARGUMENT(RegisterNatives, methods);
2359 for (jint i = 0; i < method_count; ++i) {
2360 const char* name = methods[i].name;
2361 const char* sig = methods[i].signature;
2362
2363 if (*sig == '!') {
2364 // TODO: fast jni. it's too noisy to log all these.
2365 ++sig;
2366 }
2367
2368 ArtMethod* m = c->FindDirectMethod(name, sig);
2369 if (m == NULL) {
2370 m = c->FindVirtualMethod(name, sig);
2371 }
2372 if (m == NULL) {
2373 LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
2374 << PrettyDescriptor(c) << "." << name << sig;
2375 ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2376 return JNI_ERR;
2377 } else if (!m->IsNative()) {
2378 LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2379 << PrettyDescriptor(c) << "." << name << sig
2380 << " as native";
2381 ThrowNoSuchMethodError(soa, c, name, sig, "native");
2382 return JNI_ERR;
2383 }
2384
2385 VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
2386
2387 m->RegisterNative(soa.Self(), methods[i].fnPtr);
2388 }
2389 return JNI_OK;
2390 }
2391
UnregisterNatives(JNIEnv * env,jclass java_class)2392 static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
2393 CHECK_NON_NULL_ARGUMENT(UnregisterNatives, java_class);
2394 ScopedObjectAccess soa(env);
2395 Class* c = soa.Decode<Class*>(java_class);
2396
2397 VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
2398
2399 for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
2400 ArtMethod* m = c->GetDirectMethod(i);
2401 if (m->IsNative()) {
2402 m->UnregisterNative(soa.Self());
2403 }
2404 }
2405 for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
2406 ArtMethod* m = c->GetVirtualMethod(i);
2407 if (m->IsNative()) {
2408 m->UnregisterNative(soa.Self());
2409 }
2410 }
2411
2412 return JNI_OK;
2413 }
2414
MonitorEnter(JNIEnv * env,jobject java_object)2415 static jint MonitorEnter(JNIEnv* env, jobject java_object)
2416 EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
2417 CHECK_NON_NULL_ARGUMENT(MonitorEnter, java_object);
2418 ScopedObjectAccess soa(env);
2419 Object* o = soa.Decode<Object*>(java_object);
2420 o->MonitorEnter(soa.Self());
2421 if (soa.Self()->IsExceptionPending()) {
2422 return JNI_ERR;
2423 }
2424 soa.Env()->monitors.Add(o);
2425 return JNI_OK;
2426 }
2427
MonitorExit(JNIEnv * env,jobject java_object)2428 static jint MonitorExit(JNIEnv* env, jobject java_object)
2429 UNLOCK_FUNCTION(monitor_lock_) {
2430 CHECK_NON_NULL_ARGUMENT(MonitorExit, java_object);
2431 ScopedObjectAccess soa(env);
2432 Object* o = soa.Decode<Object*>(java_object);
2433 o->MonitorExit(soa.Self());
2434 if (soa.Self()->IsExceptionPending()) {
2435 return JNI_ERR;
2436 }
2437 soa.Env()->monitors.Remove(o);
2438 return JNI_OK;
2439 }
2440
GetJavaVM(JNIEnv * env,JavaVM ** vm)2441 static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
2442 CHECK_NON_NULL_ARGUMENT(GetJavaVM, vm);
2443 Runtime* runtime = Runtime::Current();
2444 if (runtime != NULL) {
2445 *vm = runtime->GetJavaVM();
2446 } else {
2447 *vm = NULL;
2448 }
2449 return (*vm != NULL) ? JNI_OK : JNI_ERR;
2450 }
2451
NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)2452 static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
2453 if (capacity < 0) {
2454 JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %lld", capacity);
2455 }
2456 if (address == NULL && capacity != 0) {
2457 JniAbortF("NewDirectByteBuffer", "non-zero capacity for NULL pointer: %lld", capacity);
2458 }
2459
2460 // At the moment, the Java side is limited to 32 bits.
2461 CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff);
2462 CHECK_LE(capacity, 0xffffffff);
2463 jlong address_arg = reinterpret_cast<jlong>(address);
2464 jint capacity_arg = static_cast<jint>(capacity);
2465
2466 jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2467 WellKnownClasses::java_nio_DirectByteBuffer_init,
2468 address_arg, capacity_arg);
2469 return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? NULL : result;
2470 }
2471
GetDirectBufferAddress(JNIEnv * env,jobject java_buffer)2472 static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2473 return reinterpret_cast<void*>(env->GetLongField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2474 }
2475
GetDirectBufferCapacity(JNIEnv * env,jobject java_buffer)2476 static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2477 return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2478 }
2479
GetObjectRefType(JNIEnv * env,jobject java_object)2480 static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
2481 CHECK_NON_NULL_ARGUMENT(GetObjectRefType, java_object);
2482
2483 // Do we definitely know what kind of reference this is?
2484 IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2485 IndirectRefKind kind = GetIndirectRefKind(ref);
2486 switch (kind) {
2487 case kLocal:
2488 if (static_cast<JNIEnvExt*>(env)->locals.Get(ref) != kInvalidIndirectRefObject) {
2489 return JNILocalRefType;
2490 }
2491 return JNIInvalidRefType;
2492 case kGlobal:
2493 return JNIGlobalRefType;
2494 case kWeakGlobal:
2495 return JNIWeakGlobalRefType;
2496 case kSirtOrInvalid:
2497 // Is it in a stack IRT?
2498 if (static_cast<JNIEnvExt*>(env)->self->SirtContains(java_object)) {
2499 return JNILocalRefType;
2500 }
2501
2502 if (!static_cast<JNIEnvExt*>(env)->vm->work_around_app_jni_bugs) {
2503 return JNIInvalidRefType;
2504 }
2505
2506 // If we're handing out direct pointers, check whether it's a direct pointer
2507 // to a local reference.
2508 {
2509 ScopedObjectAccess soa(env);
2510 if (soa.Decode<Object*>(java_object) == reinterpret_cast<Object*>(java_object)) {
2511 if (soa.Env()->locals.ContainsDirectPointer(reinterpret_cast<Object*>(java_object))) {
2512 return JNILocalRefType;
2513 }
2514 }
2515 }
2516 return JNIInvalidRefType;
2517 }
2518 LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2519 return JNIInvalidRefType;
2520 }
2521
2522 private:
EnsureLocalCapacity(JNIEnv * env,jint desired_capacity,const char * caller)2523 static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity,
2524 const char* caller) {
2525 // TODO: we should try to expand the table if necessary.
2526 if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
2527 LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2528 return JNI_ERR;
2529 }
2530 // TODO: this isn't quite right, since "capacity" includes holes.
2531 size_t capacity = static_cast<JNIEnvExt*>(env)->locals.Capacity();
2532 bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2533 if (!okay) {
2534 ScopedObjectAccess soa(env);
2535 soa.Self()->ThrowOutOfMemoryError(caller);
2536 }
2537 return okay ? JNI_OK : JNI_ERR;
2538 }
2539
2540 template<typename JniT, typename ArtT>
NewPrimitiveArray(const ScopedObjectAccess & soa,jsize length)2541 static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length)
2542 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2543 if (length < 0) {
2544 JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
2545 }
2546 ArtT* result = ArtT::Alloc(soa.Self(), length);
2547 return soa.AddLocalReference<JniT>(result);
2548 }
2549
2550 template <typename ArrayT, typename CArrayT, typename ArtArrayT>
GetPrimitiveArray(ScopedObjectAccess & soa,ArrayT java_array,jboolean * is_copy)2551 static CArrayT GetPrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array,
2552 jboolean* is_copy)
2553 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2554 ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
2555 PinPrimitiveArray(soa, array);
2556 if (is_copy != NULL) {
2557 *is_copy = JNI_FALSE;
2558 }
2559 return array->GetData();
2560 }
2561
2562 template <typename ArrayT>
ReleasePrimitiveArray(JNIEnv * env,ArrayT java_array,jint mode)2563 static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, jint mode) {
2564 if (mode != JNI_COMMIT) {
2565 ScopedObjectAccess soa(env);
2566 Array* array = soa.Decode<Array*>(java_array);
2567 UnpinPrimitiveArray(soa, array);
2568 }
2569 }
2570
2571 template <typename JavaArrayT, typename JavaT, typename ArrayT>
GetPrimitiveArrayRegion(ScopedObjectAccess & soa,JavaArrayT java_array,jsize start,jsize length,JavaT * buf)2572 static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
2573 jsize start, jsize length, JavaT* buf)
2574 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2575 CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayRegion, java_array);
2576 ArrayT* array = soa.Decode<ArrayT*>(java_array);
2577 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2578 ThrowAIOOBE(soa, array, start, length, "src");
2579 } else {
2580 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
2581 JavaT* data = array->GetData();
2582 memcpy(buf, data + start, length * sizeof(JavaT));
2583 }
2584 }
2585
2586 template <typename JavaArrayT, typename JavaT, typename ArrayT>
SetPrimitiveArrayRegion(ScopedObjectAccess & soa,JavaArrayT java_array,jsize start,jsize length,const JavaT * buf)2587 static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
2588 jsize start, jsize length, const JavaT* buf)
2589 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2590 CHECK_NON_NULL_ARGUMENT(SetPrimitiveArrayRegion, java_array);
2591 ArrayT* array = soa.Decode<ArrayT*>(java_array);
2592 if (start < 0 || length < 0 || start + length > array->GetLength()) {
2593 ThrowAIOOBE(soa, array, start, length, "dst");
2594 } else {
2595 CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
2596 JavaT* data = array->GetData();
2597 memcpy(data + start, buf, length * sizeof(JavaT));
2598 }
2599 }
2600 };
2601
2602 const JNINativeInterface gJniNativeInterface = {
2603 NULL, // reserved0.
2604 NULL, // reserved1.
2605 NULL, // reserved2.
2606 NULL, // reserved3.
2607 JNI::GetVersion,
2608 JNI::DefineClass,
2609 JNI::FindClass,
2610 JNI::FromReflectedMethod,
2611 JNI::FromReflectedField,
2612 JNI::ToReflectedMethod,
2613 JNI::GetSuperclass,
2614 JNI::IsAssignableFrom,
2615 JNI::ToReflectedField,
2616 JNI::Throw,
2617 JNI::ThrowNew,
2618 JNI::ExceptionOccurred,
2619 JNI::ExceptionDescribe,
2620 JNI::ExceptionClear,
2621 JNI::FatalError,
2622 JNI::PushLocalFrame,
2623 JNI::PopLocalFrame,
2624 JNI::NewGlobalRef,
2625 JNI::DeleteGlobalRef,
2626 JNI::DeleteLocalRef,
2627 JNI::IsSameObject,
2628 JNI::NewLocalRef,
2629 JNI::EnsureLocalCapacity,
2630 JNI::AllocObject,
2631 JNI::NewObject,
2632 JNI::NewObjectV,
2633 JNI::NewObjectA,
2634 JNI::GetObjectClass,
2635 JNI::IsInstanceOf,
2636 JNI::GetMethodID,
2637 JNI::CallObjectMethod,
2638 JNI::CallObjectMethodV,
2639 JNI::CallObjectMethodA,
2640 JNI::CallBooleanMethod,
2641 JNI::CallBooleanMethodV,
2642 JNI::CallBooleanMethodA,
2643 JNI::CallByteMethod,
2644 JNI::CallByteMethodV,
2645 JNI::CallByteMethodA,
2646 JNI::CallCharMethod,
2647 JNI::CallCharMethodV,
2648 JNI::CallCharMethodA,
2649 JNI::CallShortMethod,
2650 JNI::CallShortMethodV,
2651 JNI::CallShortMethodA,
2652 JNI::CallIntMethod,
2653 JNI::CallIntMethodV,
2654 JNI::CallIntMethodA,
2655 JNI::CallLongMethod,
2656 JNI::CallLongMethodV,
2657 JNI::CallLongMethodA,
2658 JNI::CallFloatMethod,
2659 JNI::CallFloatMethodV,
2660 JNI::CallFloatMethodA,
2661 JNI::CallDoubleMethod,
2662 JNI::CallDoubleMethodV,
2663 JNI::CallDoubleMethodA,
2664 JNI::CallVoidMethod,
2665 JNI::CallVoidMethodV,
2666 JNI::CallVoidMethodA,
2667 JNI::CallNonvirtualObjectMethod,
2668 JNI::CallNonvirtualObjectMethodV,
2669 JNI::CallNonvirtualObjectMethodA,
2670 JNI::CallNonvirtualBooleanMethod,
2671 JNI::CallNonvirtualBooleanMethodV,
2672 JNI::CallNonvirtualBooleanMethodA,
2673 JNI::CallNonvirtualByteMethod,
2674 JNI::CallNonvirtualByteMethodV,
2675 JNI::CallNonvirtualByteMethodA,
2676 JNI::CallNonvirtualCharMethod,
2677 JNI::CallNonvirtualCharMethodV,
2678 JNI::CallNonvirtualCharMethodA,
2679 JNI::CallNonvirtualShortMethod,
2680 JNI::CallNonvirtualShortMethodV,
2681 JNI::CallNonvirtualShortMethodA,
2682 JNI::CallNonvirtualIntMethod,
2683 JNI::CallNonvirtualIntMethodV,
2684 JNI::CallNonvirtualIntMethodA,
2685 JNI::CallNonvirtualLongMethod,
2686 JNI::CallNonvirtualLongMethodV,
2687 JNI::CallNonvirtualLongMethodA,
2688 JNI::CallNonvirtualFloatMethod,
2689 JNI::CallNonvirtualFloatMethodV,
2690 JNI::CallNonvirtualFloatMethodA,
2691 JNI::CallNonvirtualDoubleMethod,
2692 JNI::CallNonvirtualDoubleMethodV,
2693 JNI::CallNonvirtualDoubleMethodA,
2694 JNI::CallNonvirtualVoidMethod,
2695 JNI::CallNonvirtualVoidMethodV,
2696 JNI::CallNonvirtualVoidMethodA,
2697 JNI::GetFieldID,
2698 JNI::GetObjectField,
2699 JNI::GetBooleanField,
2700 JNI::GetByteField,
2701 JNI::GetCharField,
2702 JNI::GetShortField,
2703 JNI::GetIntField,
2704 JNI::GetLongField,
2705 JNI::GetFloatField,
2706 JNI::GetDoubleField,
2707 JNI::SetObjectField,
2708 JNI::SetBooleanField,
2709 JNI::SetByteField,
2710 JNI::SetCharField,
2711 JNI::SetShortField,
2712 JNI::SetIntField,
2713 JNI::SetLongField,
2714 JNI::SetFloatField,
2715 JNI::SetDoubleField,
2716 JNI::GetStaticMethodID,
2717 JNI::CallStaticObjectMethod,
2718 JNI::CallStaticObjectMethodV,
2719 JNI::CallStaticObjectMethodA,
2720 JNI::CallStaticBooleanMethod,
2721 JNI::CallStaticBooleanMethodV,
2722 JNI::CallStaticBooleanMethodA,
2723 JNI::CallStaticByteMethod,
2724 JNI::CallStaticByteMethodV,
2725 JNI::CallStaticByteMethodA,
2726 JNI::CallStaticCharMethod,
2727 JNI::CallStaticCharMethodV,
2728 JNI::CallStaticCharMethodA,
2729 JNI::CallStaticShortMethod,
2730 JNI::CallStaticShortMethodV,
2731 JNI::CallStaticShortMethodA,
2732 JNI::CallStaticIntMethod,
2733 JNI::CallStaticIntMethodV,
2734 JNI::CallStaticIntMethodA,
2735 JNI::CallStaticLongMethod,
2736 JNI::CallStaticLongMethodV,
2737 JNI::CallStaticLongMethodA,
2738 JNI::CallStaticFloatMethod,
2739 JNI::CallStaticFloatMethodV,
2740 JNI::CallStaticFloatMethodA,
2741 JNI::CallStaticDoubleMethod,
2742 JNI::CallStaticDoubleMethodV,
2743 JNI::CallStaticDoubleMethodA,
2744 JNI::CallStaticVoidMethod,
2745 JNI::CallStaticVoidMethodV,
2746 JNI::CallStaticVoidMethodA,
2747 JNI::GetStaticFieldID,
2748 JNI::GetStaticObjectField,
2749 JNI::GetStaticBooleanField,
2750 JNI::GetStaticByteField,
2751 JNI::GetStaticCharField,
2752 JNI::GetStaticShortField,
2753 JNI::GetStaticIntField,
2754 JNI::GetStaticLongField,
2755 JNI::GetStaticFloatField,
2756 JNI::GetStaticDoubleField,
2757 JNI::SetStaticObjectField,
2758 JNI::SetStaticBooleanField,
2759 JNI::SetStaticByteField,
2760 JNI::SetStaticCharField,
2761 JNI::SetStaticShortField,
2762 JNI::SetStaticIntField,
2763 JNI::SetStaticLongField,
2764 JNI::SetStaticFloatField,
2765 JNI::SetStaticDoubleField,
2766 JNI::NewString,
2767 JNI::GetStringLength,
2768 JNI::GetStringChars,
2769 JNI::ReleaseStringChars,
2770 JNI::NewStringUTF,
2771 JNI::GetStringUTFLength,
2772 JNI::GetStringUTFChars,
2773 JNI::ReleaseStringUTFChars,
2774 JNI::GetArrayLength,
2775 JNI::NewObjectArray,
2776 JNI::GetObjectArrayElement,
2777 JNI::SetObjectArrayElement,
2778 JNI::NewBooleanArray,
2779 JNI::NewByteArray,
2780 JNI::NewCharArray,
2781 JNI::NewShortArray,
2782 JNI::NewIntArray,
2783 JNI::NewLongArray,
2784 JNI::NewFloatArray,
2785 JNI::NewDoubleArray,
2786 JNI::GetBooleanArrayElements,
2787 JNI::GetByteArrayElements,
2788 JNI::GetCharArrayElements,
2789 JNI::GetShortArrayElements,
2790 JNI::GetIntArrayElements,
2791 JNI::GetLongArrayElements,
2792 JNI::GetFloatArrayElements,
2793 JNI::GetDoubleArrayElements,
2794 JNI::ReleaseBooleanArrayElements,
2795 JNI::ReleaseByteArrayElements,
2796 JNI::ReleaseCharArrayElements,
2797 JNI::ReleaseShortArrayElements,
2798 JNI::ReleaseIntArrayElements,
2799 JNI::ReleaseLongArrayElements,
2800 JNI::ReleaseFloatArrayElements,
2801 JNI::ReleaseDoubleArrayElements,
2802 JNI::GetBooleanArrayRegion,
2803 JNI::GetByteArrayRegion,
2804 JNI::GetCharArrayRegion,
2805 JNI::GetShortArrayRegion,
2806 JNI::GetIntArrayRegion,
2807 JNI::GetLongArrayRegion,
2808 JNI::GetFloatArrayRegion,
2809 JNI::GetDoubleArrayRegion,
2810 JNI::SetBooleanArrayRegion,
2811 JNI::SetByteArrayRegion,
2812 JNI::SetCharArrayRegion,
2813 JNI::SetShortArrayRegion,
2814 JNI::SetIntArrayRegion,
2815 JNI::SetLongArrayRegion,
2816 JNI::SetFloatArrayRegion,
2817 JNI::SetDoubleArrayRegion,
2818 JNI::RegisterNatives,
2819 JNI::UnregisterNatives,
2820 JNI::MonitorEnter,
2821 JNI::MonitorExit,
2822 JNI::GetJavaVM,
2823 JNI::GetStringRegion,
2824 JNI::GetStringUTFRegion,
2825 JNI::GetPrimitiveArrayCritical,
2826 JNI::ReleasePrimitiveArrayCritical,
2827 JNI::GetStringCritical,
2828 JNI::ReleaseStringCritical,
2829 JNI::NewWeakGlobalRef,
2830 JNI::DeleteWeakGlobalRef,
2831 JNI::ExceptionCheck,
2832 JNI::NewDirectByteBuffer,
2833 JNI::GetDirectBufferAddress,
2834 JNI::GetDirectBufferCapacity,
2835 JNI::GetObjectRefType,
2836 };
2837
JNIEnvExt(Thread * self,JavaVMExt * vm)2838 JNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
2839 : self(self),
2840 vm(vm),
2841 local_ref_cookie(IRT_FIRST_SEGMENT),
2842 locals(kLocalsInitial, kLocalsMax, kLocal),
2843 check_jni(false),
2844 critical(false),
2845 monitors("monitors", kMonitorsInitial, kMonitorsMax) {
2846 functions = unchecked_functions = &gJniNativeInterface;
2847 if (vm->check_jni) {
2848 SetCheckJniEnabled(true);
2849 }
2850 // The JniEnv local reference values must be at a consistent offset or else cross-compilation
2851 // errors will ensue.
2852 CHECK_EQ(JNIEnvExt::LocalRefCookieOffset().Int32Value(), 12);
2853 CHECK_EQ(JNIEnvExt::SegmentStateOffset().Int32Value(), 16);
2854 }
2855
~JNIEnvExt()2856 JNIEnvExt::~JNIEnvExt() {
2857 }
2858
SetCheckJniEnabled(bool enabled)2859 void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
2860 check_jni = enabled;
2861 functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
2862 }
2863
DumpReferenceTables(std::ostream & os)2864 void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
2865 locals.Dump(os);
2866 monitors.Dump(os);
2867 }
2868
PushFrame(int)2869 void JNIEnvExt::PushFrame(int /*capacity*/) {
2870 // TODO: take 'capacity' into account.
2871 stacked_local_ref_cookies.push_back(local_ref_cookie);
2872 local_ref_cookie = locals.GetSegmentState();
2873 }
2874
PopFrame()2875 void JNIEnvExt::PopFrame() {
2876 locals.SetSegmentState(local_ref_cookie);
2877 local_ref_cookie = stacked_local_ref_cookies.back();
2878 stacked_local_ref_cookies.pop_back();
2879 }
2880
SegmentStateOffset()2881 Offset JNIEnvExt::SegmentStateOffset() {
2882 return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
2883 IndirectReferenceTable::SegmentStateOffset().Int32Value());
2884 }
2885
2886 // JNI Invocation interface.
2887
JNI_CreateJavaVM(JavaVM ** p_vm,JNIEnv ** p_env,void * vm_args)2888 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
2889 const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
2890 if (IsBadJniVersion(args->version)) {
2891 LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
2892 return JNI_EVERSION;
2893 }
2894 Runtime::Options options;
2895 for (int i = 0; i < args->nOptions; ++i) {
2896 JavaVMOption* option = &args->options[i];
2897 options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
2898 }
2899 bool ignore_unrecognized = args->ignoreUnrecognized;
2900 if (!Runtime::Create(options, ignore_unrecognized)) {
2901 return JNI_ERR;
2902 }
2903 Runtime* runtime = Runtime::Current();
2904 bool started = runtime->Start();
2905 if (!started) {
2906 delete Thread::Current()->GetJniEnv();
2907 delete runtime->GetJavaVM();
2908 LOG(WARNING) << "CreateJavaVM failed";
2909 return JNI_ERR;
2910 }
2911 *p_env = Thread::Current()->GetJniEnv();
2912 *p_vm = runtime->GetJavaVM();
2913 return JNI_OK;
2914 }
2915
JNI_GetCreatedJavaVMs(JavaVM ** vms,jsize,jsize * vm_count)2916 extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
2917 Runtime* runtime = Runtime::Current();
2918 if (runtime == NULL) {
2919 *vm_count = 0;
2920 } else {
2921 *vm_count = 1;
2922 vms[0] = runtime->GetJavaVM();
2923 }
2924 return JNI_OK;
2925 }
2926
2927 // Historically unsupported.
JNI_GetDefaultJavaVMInitArgs(void *)2928 extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
2929 return JNI_ERR;
2930 }
2931
2932 class JII {
2933 public:
DestroyJavaVM(JavaVM * vm)2934 static jint DestroyJavaVM(JavaVM* vm) {
2935 if (vm == NULL) {
2936 return JNI_ERR;
2937 }
2938 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
2939 delete raw_vm->runtime;
2940 return JNI_OK;
2941 }
2942
AttachCurrentThread(JavaVM * vm,JNIEnv ** p_env,void * thr_args)2943 static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
2944 return JII_AttachCurrentThread(vm, p_env, thr_args, false);
2945 }
2946
AttachCurrentThreadAsDaemon(JavaVM * vm,JNIEnv ** p_env,void * thr_args)2947 static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
2948 return JII_AttachCurrentThread(vm, p_env, thr_args, true);
2949 }
2950
DetachCurrentThread(JavaVM * vm)2951 static jint DetachCurrentThread(JavaVM* vm) {
2952 if (vm == NULL || Thread::Current() == NULL) {
2953 return JNI_ERR;
2954 }
2955 JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
2956 Runtime* runtime = raw_vm->runtime;
2957 runtime->DetachCurrentThread();
2958 return JNI_OK;
2959 }
2960
GetEnv(JavaVM * vm,void ** env,jint version)2961 static jint GetEnv(JavaVM* vm, void** env, jint version) {
2962 // GetEnv always returns a JNIEnv* for the most current supported JNI version,
2963 // and unlike other calls that take a JNI version doesn't care if you supply
2964 // JNI_VERSION_1_1, which we don't otherwise support.
2965 if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) {
2966 LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
2967 return JNI_EVERSION;
2968 }
2969 if (vm == NULL || env == NULL) {
2970 return JNI_ERR;
2971 }
2972 Thread* thread = Thread::Current();
2973 if (thread == NULL) {
2974 *env = NULL;
2975 return JNI_EDETACHED;
2976 }
2977 *env = thread->GetJniEnv();
2978 return JNI_OK;
2979 }
2980 };
2981
2982 const JNIInvokeInterface gJniInvokeInterface = {
2983 NULL, // reserved0
2984 NULL, // reserved1
2985 NULL, // reserved2
2986 JII::DestroyJavaVM,
2987 JII::AttachCurrentThread,
2988 JII::DetachCurrentThread,
2989 JII::GetEnv,
2990 JII::AttachCurrentThreadAsDaemon
2991 };
2992
JavaVMExt(Runtime * runtime,Runtime::ParsedOptions * options)2993 JavaVMExt::JavaVMExt(Runtime* runtime, Runtime::ParsedOptions* options)
2994 : runtime(runtime),
2995 check_jni_abort_hook(NULL),
2996 check_jni_abort_hook_data(NULL),
2997 check_jni(false),
2998 force_copy(false), // TODO: add a way to enable this
2999 trace(options->jni_trace_),
3000 work_around_app_jni_bugs(false),
3001 pins_lock("JNI pin table lock", kPinTableLock),
3002 pin_table("pin table", kPinTableInitial, kPinTableMax),
3003 globals_lock("JNI global reference table lock"),
3004 globals(gGlobalsInitial, gGlobalsMax, kGlobal),
3005 libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
3006 libraries(new Libraries),
3007 weak_globals_lock_("JNI weak global reference table lock"),
3008 weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
3009 allow_new_weak_globals_(true),
3010 weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) {
3011 functions = unchecked_functions = &gJniInvokeInterface;
3012 if (options->check_jni_) {
3013 SetCheckJniEnabled(true);
3014 }
3015 }
3016
~JavaVMExt()3017 JavaVMExt::~JavaVMExt() {
3018 delete libraries;
3019 }
3020
AddWeakGlobalReference(Thread * self,mirror::Object * obj)3021 jweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) {
3022 if (obj == nullptr) {
3023 return nullptr;
3024 }
3025 MutexLock mu(self, weak_globals_lock_);
3026 while (UNLIKELY(!allow_new_weak_globals_)) {
3027 weak_globals_add_condition_.WaitHoldingLocks(self);
3028 }
3029 IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj);
3030 return reinterpret_cast<jweak>(ref);
3031 }
3032
DeleteWeakGlobalRef(Thread * self,jweak obj)3033 void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
3034 MutexLock mu(self, weak_globals_lock_);
3035 if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) {
3036 LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
3037 << "failed to find entry";
3038 }
3039 }
3040
SetCheckJniEnabled(bool enabled)3041 void JavaVMExt::SetCheckJniEnabled(bool enabled) {
3042 check_jni = enabled;
3043 functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
3044 }
3045
DumpForSigQuit(std::ostream & os)3046 void JavaVMExt::DumpForSigQuit(std::ostream& os) {
3047 os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
3048 if (force_copy) {
3049 os << " (with forcecopy)";
3050 }
3051 os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off");
3052 Thread* self = Thread::Current();
3053 {
3054 MutexLock mu(self, pins_lock);
3055 os << "; pins=" << pin_table.Size();
3056 }
3057 {
3058 ReaderMutexLock mu(self, globals_lock);
3059 os << "; globals=" << globals.Capacity();
3060 }
3061 {
3062 MutexLock mu(self, weak_globals_lock_);
3063 if (weak_globals_.Capacity() > 0) {
3064 os << " (plus " << weak_globals_.Capacity() << " weak)";
3065 }
3066 }
3067 os << '\n';
3068
3069 {
3070 MutexLock mu(self, libraries_lock);
3071 os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
3072 }
3073 }
3074
DisallowNewWeakGlobals()3075 void JavaVMExt::DisallowNewWeakGlobals() {
3076 MutexLock mu(Thread::Current(), weak_globals_lock_);
3077 allow_new_weak_globals_ = false;
3078 }
3079
AllowNewWeakGlobals()3080 void JavaVMExt::AllowNewWeakGlobals() {
3081 Thread* self = Thread::Current();
3082 MutexLock mu(self, weak_globals_lock_);
3083 allow_new_weak_globals_ = true;
3084 weak_globals_add_condition_.Broadcast(self);
3085 }
3086
SweepWeakGlobals(IsMarkedTester is_marked,void * arg)3087 void JavaVMExt::SweepWeakGlobals(IsMarkedTester is_marked, void* arg) {
3088 MutexLock mu(Thread::Current(), weak_globals_lock_);
3089 for (const Object** entry : weak_globals_) {
3090 if (!is_marked(*entry, arg)) {
3091 *entry = kClearedJniWeakGlobal;
3092 }
3093 }
3094 }
3095
DecodeWeakGlobal(Thread * self,IndirectRef ref)3096 mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
3097 MutexLock mu(self, weak_globals_lock_);
3098 while (UNLIKELY(!allow_new_weak_globals_)) {
3099 weak_globals_add_condition_.WaitHoldingLocks(self);
3100 }
3101 return const_cast<mirror::Object*>(weak_globals_.Get(ref));
3102 }
3103
DumpReferenceTables(std::ostream & os)3104 void JavaVMExt::DumpReferenceTables(std::ostream& os) {
3105 Thread* self = Thread::Current();
3106 {
3107 ReaderMutexLock mu(self, globals_lock);
3108 globals.Dump(os);
3109 }
3110 {
3111 MutexLock mu(self, weak_globals_lock_);
3112 weak_globals_.Dump(os);
3113 }
3114 {
3115 MutexLock mu(self, pins_lock);
3116 pin_table.Dump(os);
3117 }
3118 }
3119
LoadNativeLibrary(const std::string & path,ClassLoader * class_loader,std::string & detail)3120 bool JavaVMExt::LoadNativeLibrary(const std::string& path, ClassLoader* class_loader,
3121 std::string& detail) {
3122 detail.clear();
3123
3124 // See if we've already loaded this library. If we have, and the class loader
3125 // matches, return successfully without doing anything.
3126 // TODO: for better results we should canonicalize the pathname (or even compare
3127 // inodes). This implementation is fine if everybody is using System.loadLibrary.
3128 SharedLibrary* library;
3129 Thread* self = Thread::Current();
3130 {
3131 // TODO: move the locking (and more of this logic) into Libraries.
3132 MutexLock mu(self, libraries_lock);
3133 library = libraries->Get(path);
3134 }
3135 if (library != NULL) {
3136 if (library->GetClassLoader() != class_loader) {
3137 // The library will be associated with class_loader. The JNI
3138 // spec says we can't load the same library into more than one
3139 // class loader.
3140 StringAppendF(&detail, "Shared library \"%s\" already opened by "
3141 "ClassLoader %p; can't open in ClassLoader %p",
3142 path.c_str(), library->GetClassLoader(), class_loader);
3143 LOG(WARNING) << detail;
3144 return false;
3145 }
3146 VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
3147 << "ClassLoader " << class_loader << "]";
3148 if (!library->CheckOnLoadResult()) {
3149 StringAppendF(&detail, "JNI_OnLoad failed on a previous attempt "
3150 "to load \"%s\"", path.c_str());
3151 return false;
3152 }
3153 return true;
3154 }
3155
3156 // Open the shared library. Because we're using a full path, the system
3157 // doesn't have to search through LD_LIBRARY_PATH. (It may do so to
3158 // resolve this library's dependencies though.)
3159
3160 // Failures here are expected when java.library.path has several entries
3161 // and we have to hunt for the lib.
3162
3163 // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
3164 // class unloading. Libraries will only be unloaded when the reference count (incremented by
3165 // dlopen) becomes zero from dlclose.
3166
3167 // This can execute slowly for a large library on a busy system, so we
3168 // want to switch from kRunnable while it executes. This allows the GC to ignore us.
3169 self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
3170 void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY);
3171 self->TransitionFromSuspendedToRunnable();
3172
3173 VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";
3174
3175 if (handle == NULL) {
3176 detail = dlerror();
3177 LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << detail;
3178 return false;
3179 }
3180
3181 // Create a new entry.
3182 // TODO: move the locking (and more of this logic) into Libraries.
3183 bool created_library = false;
3184 {
3185 MutexLock mu(self, libraries_lock);
3186 library = libraries->Get(path);
3187 if (library == NULL) { // We won race to get libraries_lock
3188 library = new SharedLibrary(path, handle, class_loader);
3189 libraries->Put(path, library);
3190 created_library = true;
3191 }
3192 }
3193 if (!created_library) {
3194 LOG(INFO) << "WOW: we lost a race to add shared library: "
3195 << "\"" << path << "\" ClassLoader=" << class_loader;
3196 return library->CheckOnLoadResult();
3197 }
3198
3199 VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
3200
3201 bool was_successful = false;
3202 void* sym = dlsym(handle, "JNI_OnLoad");
3203 if (sym == NULL) {
3204 VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
3205 was_successful = true;
3206 } else {
3207 // Call JNI_OnLoad. We have to override the current class
3208 // loader, which will always be "null" since the stuff at the
3209 // top of the stack is around Runtime.loadLibrary(). (See
3210 // the comments in the JNI FindClass function.)
3211 typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
3212 JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
3213 ClassLoader* old_class_loader = self->GetClassLoaderOverride();
3214 self->SetClassLoaderOverride(class_loader);
3215
3216 int version = 0;
3217 {
3218 ScopedThreadStateChange tsc(self, kNative);
3219 VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
3220 version = (*jni_on_load)(this, NULL);
3221 }
3222
3223 self->SetClassLoaderOverride(old_class_loader);
3224
3225 if (version == JNI_ERR) {
3226 StringAppendF(&detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
3227 } else if (IsBadJniVersion(version)) {
3228 StringAppendF(&detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
3229 path.c_str(), version);
3230 // It's unwise to call dlclose() here, but we can mark it
3231 // as bad and ensure that future load attempts will fail.
3232 // We don't know how far JNI_OnLoad got, so there could
3233 // be some partially-initialized stuff accessible through
3234 // newly-registered native method calls. We could try to
3235 // unregister them, but that doesn't seem worthwhile.
3236 } else {
3237 was_successful = true;
3238 }
3239 VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
3240 << " from JNI_OnLoad in \"" << path << "\"]";
3241 }
3242
3243 library->SetResult(was_successful);
3244 return was_successful;
3245 }
3246
FindCodeForNativeMethod(ArtMethod * m)3247 void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m) {
3248 CHECK(m->IsNative());
3249
3250 Class* c = m->GetDeclaringClass();
3251
3252 // If this is a static method, it could be called before the class
3253 // has been initialized.
3254 if (m->IsStatic()) {
3255 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
3256 return NULL;
3257 }
3258 } else {
3259 CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
3260 }
3261
3262 std::string detail;
3263 void* native_method;
3264 Thread* self = Thread::Current();
3265 {
3266 MutexLock mu(self, libraries_lock);
3267 native_method = libraries->FindNativeMethod(m, detail);
3268 }
3269 // Throwing can cause libraries_lock to be reacquired.
3270 if (native_method == NULL) {
3271 ThrowLocation throw_location = self->GetCurrentLocationForThrow();
3272 self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
3273 }
3274 return native_method;
3275 }
3276
VisitRoots(RootVisitor * visitor,void * arg)3277 void JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) {
3278 Thread* self = Thread::Current();
3279 {
3280 ReaderMutexLock mu(self, globals_lock);
3281 globals.VisitRoots(visitor, arg);
3282 }
3283 {
3284 MutexLock mu(self, pins_lock);
3285 pin_table.VisitRoots(visitor, arg);
3286 }
3287 // The weak_globals table is visited by the GC itself (because it mutates the table).
3288 }
3289
RegisterNativeMethods(JNIEnv * env,const char * jni_class_name,const JNINativeMethod * methods,jint method_count)3290 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
3291 jint method_count) {
3292 ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
3293 if (c.get() == NULL) {
3294 LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3295 }
3296 JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3297 }
3298
3299 } // namespace art
3300
operator <<(std::ostream & os,const jobjectRefType & rhs)3301 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3302 switch (rhs) {
3303 case JNIInvalidRefType:
3304 os << "JNIInvalidRefType";
3305 return os;
3306 case JNILocalRefType:
3307 os << "JNILocalRefType";
3308 return os;
3309 case JNIGlobalRefType:
3310 os << "JNIGlobalRefType";
3311 return os;
3312 case JNIWeakGlobalRefType:
3313 os << "JNIWeakGlobalRefType";
3314 return os;
3315 default:
3316 LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3317 return os;
3318 }
3319 }
3320