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