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     class_loader_.VisitRootIfNonNull(visitor, arg, RootInfo(kRootVMInternal));
441   }
442 
443  private:
444   enum JNI_OnLoadState {
445     kPending,
446     kFailed,
447     kOkay,
448   };
449 
450   // Path to library "/system/lib/libjni.so".
451   std::string path_;
452 
453   // The void* returned by dlopen(3).
454   void* handle_;
455 
456   // True if a native bridge is required.
457   bool needs_native_bridge_;
458 
459   // The ClassLoader this library is associated with.
460   GcRoot<mirror::Object> class_loader_;
461 
462   // Guards remaining items.
463   Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
464   // Wait for JNI_OnLoad in other thread.
465   ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
466   // Recursive invocation guard.
467   uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
468   // Result of earlier JNI_OnLoad call.
469   JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
470 };
471 
472 // This exists mainly to keep implementation details out of the header file.
473 class Libraries {
474  public:
Libraries()475   Libraries() {
476   }
477 
~Libraries()478   ~Libraries() {
479     STLDeleteValues(&libraries_);
480   }
481 
Dump(std::ostream & os) const482   void Dump(std::ostream& os) const {
483     bool first = true;
484     for (const auto& library : libraries_) {
485       if (!first) {
486         os << ' ';
487       }
488       first = false;
489       os << library.first;
490     }
491   }
492 
size() const493   size_t size() const {
494     return libraries_.size();
495   }
496 
Get(const std::string & path)497   SharedLibrary* Get(const std::string& path) {
498     auto it = libraries_.find(path);
499     return (it == libraries_.end()) ? nullptr : it->second;
500   }
501 
Put(const std::string & path,SharedLibrary * library)502   void Put(const std::string& path, SharedLibrary* library) {
503     libraries_.Put(path, library);
504   }
505 
506   // See section 11.3 "Linking Native Methods" of the JNI spec.
FindNativeMethod(mirror::ArtMethod * m,std::string & detail)507   void* FindNativeMethod(mirror::ArtMethod* m, std::string& detail)
508       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
509     std::string jni_short_name(JniShortName(m));
510     std::string jni_long_name(JniLongName(m));
511     const mirror::ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
512     for (const auto& lib : libraries_) {
513       SharedLibrary* library = lib.second;
514       if (library->GetClassLoader() != declaring_class_loader) {
515         // We only search libraries loaded by the appropriate ClassLoader.
516         continue;
517       }
518       // Try the short name then the long name...
519       void* fn = nullptr;
520       if (UNLIKELY(library->NeedsNativeBridge())) {
521         fn = library->FindSymbolWithNativeBridge(jni_short_name, m);
522         if (fn == nullptr) {
523           fn = library->FindSymbolWithNativeBridge(jni_long_name, m);
524         }
525       } else {
526         fn = library->FindSymbol(jni_short_name);
527         if (fn == nullptr) {
528           fn = library->FindSymbol(jni_long_name);
529         }
530       }
531       if (fn != nullptr) {
532         VLOG(jni) << "[Found native code for " << PrettyMethod(m)
533                   << " in \"" << library->GetPath() << "\"]";
534         return fn;
535       }
536     }
537     detail += "No implementation found for ";
538     detail += PrettyMethod(m);
539     detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
540     LOG(ERROR) << detail;
541     return nullptr;
542   }
543 
VisitRoots(RootCallback * callback,void * arg)544   void VisitRoots(RootCallback* callback, void* arg) {
545     for (auto& lib_pair : libraries_) {
546       lib_pair.second->VisitRoots(callback, arg);
547     }
548   }
549 
550  private:
551   AllocationTrackingSafeMap<std::string, SharedLibrary*, kAllocatorTagJNILibrarires> libraries_;
552 };
553 
554 #define CHECK_NON_NULL_ARGUMENT(value) \
555     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
556 
557 #define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
558     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
559 
560 #define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
561     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
562 
563 #define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
564     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
565 
566 #define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
567   if (UNLIKELY(value == nullptr)) { \
568     JniAbortF(name, #value " == null"); \
569     return return_val; \
570   }
571 
572 #define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
573   if (UNLIKELY(length != 0 && value == nullptr)) { \
574     JniAbortF(__FUNCTION__, #value " == null"); \
575     return; \
576   }
577 
578 class JNI {
579  public:
GetVersion(JNIEnv *)580   static jint GetVersion(JNIEnv*) {
581     return JNI_VERSION_1_6;
582   }
583 
DefineClass(JNIEnv *,const char *,jobject,const jbyte *,jsize)584   static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
585     LOG(WARNING) << "JNI DefineClass is not supported";
586     return nullptr;
587   }
588 
FindClass(JNIEnv * env,const char * name)589   static jclass FindClass(JNIEnv* env, const char* name) {
590     CHECK_NON_NULL_ARGUMENT(name);
591     Runtime* runtime = Runtime::Current();
592     ClassLinker* class_linker = runtime->GetClassLinker();
593     std::string descriptor(NormalizeJniClassDescriptor(name));
594     ScopedObjectAccess soa(env);
595     mirror::Class* c = nullptr;
596     if (runtime->IsStarted()) {
597       StackHandleScope<1> hs(soa.Self());
598       Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
599       c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
600     } else {
601       c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
602     }
603     return soa.AddLocalReference<jclass>(c);
604   }
605 
FromReflectedMethod(JNIEnv * env,jobject jlr_method)606   static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
607     CHECK_NON_NULL_ARGUMENT(jlr_method);
608     ScopedObjectAccess soa(env);
609     return soa.EncodeMethod(mirror::ArtMethod::FromReflectedMethod(soa, jlr_method));
610   }
611 
FromReflectedField(JNIEnv * env,jobject jlr_field)612   static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
613     CHECK_NON_NULL_ARGUMENT(jlr_field);
614     ScopedObjectAccess soa(env);
615     return soa.EncodeField(mirror::ArtField::FromReflectedField(soa, jlr_field));
616   }
617 
ToReflectedMethod(JNIEnv * env,jclass,jmethodID mid,jboolean)618   static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
619     CHECK_NON_NULL_ARGUMENT(mid);
620     ScopedObjectAccess soa(env);
621     mirror::ArtMethod* m = soa.DecodeMethod(mid);
622     CHECK(!kMovingMethods);
623     ScopedLocalRef<jobject> art_method(env, soa.AddLocalReference<jobject>(m));
624     jobject reflect_method;
625     if (m->IsConstructor()) {
626       reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor);
627     } else {
628       reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);
629     }
630     if (env->ExceptionCheck()) {
631       return nullptr;
632     }
633     SetObjectField(env, reflect_method,
634                    WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, art_method.get());
635     return reflect_method;
636   }
637 
ToReflectedField(JNIEnv * env,jclass,jfieldID fid,jboolean)638   static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
639     CHECK_NON_NULL_ARGUMENT(fid);
640     ScopedObjectAccess soa(env);
641     mirror::ArtField* f = soa.DecodeField(fid);
642     ScopedLocalRef<jobject> art_field(env, soa.AddLocalReference<jobject>(f));
643     jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
644     if (env->ExceptionCheck()) {
645       return nullptr;
646     }
647     SetObjectField(env, reflect_field,
648                    WellKnownClasses::java_lang_reflect_Field_artField, art_field.get());
649     return reflect_field;
650   }
651 
GetObjectClass(JNIEnv * env,jobject java_object)652   static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
653     CHECK_NON_NULL_ARGUMENT(java_object);
654     ScopedObjectAccess soa(env);
655     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
656     return soa.AddLocalReference<jclass>(o->GetClass());
657   }
658 
GetSuperclass(JNIEnv * env,jclass java_class)659   static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
660     CHECK_NON_NULL_ARGUMENT(java_class);
661     ScopedObjectAccess soa(env);
662     mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
663     return soa.AddLocalReference<jclass>(c->GetSuperClass());
664   }
665 
666   // Note: java_class1 should be safely castable to java_class2, and
667   // not the other way around.
IsAssignableFrom(JNIEnv * env,jclass java_class1,jclass java_class2)668   static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
669     CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
670     CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
671     ScopedObjectAccess soa(env);
672     mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
673     mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
674     return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
675   }
676 
IsInstanceOf(JNIEnv * env,jobject jobj,jclass java_class)677   static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
678     CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
679     if (jobj == nullptr) {
680       // Note: JNI is different from regular Java instanceof in this respect
681       return JNI_TRUE;
682     } else {
683       ScopedObjectAccess soa(env);
684       mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
685       mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
686       return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
687     }
688   }
689 
Throw(JNIEnv * env,jthrowable java_exception)690   static jint Throw(JNIEnv* env, jthrowable java_exception) {
691     ScopedObjectAccess soa(env);
692     mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
693     if (exception == nullptr) {
694       return JNI_ERR;
695     }
696     ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
697     soa.Self()->SetException(throw_location, exception);
698     return JNI_OK;
699   }
700 
ThrowNew(JNIEnv * env,jclass c,const char * msg)701   static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
702     CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
703     return ThrowNewException(env, c, msg, nullptr);
704   }
705 
ExceptionCheck(JNIEnv * env)706   static jboolean ExceptionCheck(JNIEnv* env) {
707     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
708   }
709 
ExceptionClear(JNIEnv * env)710   static void ExceptionClear(JNIEnv* env) {
711     ScopedObjectAccess soa(env);
712     soa.Self()->ClearException();
713   }
714 
ExceptionDescribe(JNIEnv * env)715   static void ExceptionDescribe(JNIEnv* env) {
716     ScopedObjectAccess soa(env);
717 
718     // If we have no exception to describe, pass through.
719     if (!soa.Self()->GetException(nullptr)) {
720       return;
721     }
722 
723     StackHandleScope<3> hs(soa.Self());
724     // TODO: Use nullptr instead of null handles?
725     auto old_throw_this_object(hs.NewHandle<mirror::Object>(nullptr));
726     auto old_throw_method(hs.NewHandle<mirror::ArtMethod>(nullptr));
727     auto old_exception(hs.NewHandle<mirror::Throwable>(nullptr));
728     uint32_t old_throw_dex_pc;
729     bool old_is_exception_reported;
730     {
731       ThrowLocation old_throw_location;
732       mirror::Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location);
733       old_throw_this_object.Assign(old_throw_location.GetThis());
734       old_throw_method.Assign(old_throw_location.GetMethod());
735       old_exception.Assign(old_exception_obj);
736       old_throw_dex_pc = old_throw_location.GetDexPc();
737       old_is_exception_reported = soa.Self()->IsExceptionReportedToInstrumentation();
738       soa.Self()->ClearException();
739     }
740     ScopedLocalRef<jthrowable> exception(env,
741                                          soa.AddLocalReference<jthrowable>(old_exception.Get()));
742     ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
743     jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
744     if (mid == nullptr) {
745       LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
746                    << PrettyTypeOf(old_exception.Get());
747     } else {
748       env->CallVoidMethod(exception.get(), mid);
749       if (soa.Self()->IsExceptionPending()) {
750         LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(nullptr))
751                      << " thrown while calling printStackTrace";
752         soa.Self()->ClearException();
753       }
754     }
755     ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(),
756                                          old_throw_dex_pc);
757 
758     soa.Self()->SetException(gc_safe_throw_location, old_exception.Get());
759     soa.Self()->SetExceptionReportedToInstrumentation(old_is_exception_reported);
760   }
761 
ExceptionOccurred(JNIEnv * env)762   static jthrowable ExceptionOccurred(JNIEnv* env) {
763     ScopedObjectAccess soa(env);
764     mirror::Object* exception = soa.Self()->GetException(nullptr);
765     return soa.AddLocalReference<jthrowable>(exception);
766   }
767 
FatalError(JNIEnv *,const char * msg)768   static void FatalError(JNIEnv*, const char* msg) {
769     LOG(FATAL) << "JNI FatalError called: " << msg;
770   }
771 
PushLocalFrame(JNIEnv * env,jint capacity)772   static jint PushLocalFrame(JNIEnv* env, jint capacity) {
773     // TODO: SOA may not be necessary but I do it to please lock annotations.
774     ScopedObjectAccess soa(env);
775     if (EnsureLocalCapacity(soa, capacity, "PushLocalFrame") != JNI_OK) {
776       return JNI_ERR;
777     }
778     static_cast<JNIEnvExt*>(env)->PushFrame(capacity);
779     return JNI_OK;
780   }
781 
PopLocalFrame(JNIEnv * env,jobject java_survivor)782   static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
783     ScopedObjectAccess soa(env);
784     mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
785     soa.Env()->PopFrame();
786     return soa.AddLocalReference<jobject>(survivor);
787   }
788 
EnsureLocalCapacity(JNIEnv * env,jint desired_capacity)789   static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
790     // TODO: SOA may not be necessary but I do it to please lock annotations.
791     ScopedObjectAccess soa(env);
792     return EnsureLocalCapacity(soa, desired_capacity, "EnsureLocalCapacity");
793   }
794 
NewGlobalRef(JNIEnv * env,jobject obj)795   static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
796     ScopedObjectAccess soa(env);
797     mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
798     // Check for null after decoding the object to handle cleared weak globals.
799     if (decoded_obj == nullptr) {
800       return nullptr;
801     }
802     JavaVMExt* vm = soa.Vm();
803     IndirectReferenceTable& globals = vm->globals;
804     WriterMutexLock mu(soa.Self(), vm->globals_lock);
805     IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
806     return reinterpret_cast<jobject>(ref);
807   }
808 
DeleteGlobalRef(JNIEnv * env,jobject obj)809   static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
810     if (obj == nullptr) {
811       return;
812     }
813     JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
814     IndirectReferenceTable& globals = vm->globals;
815     Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
816     WriterMutexLock mu(self, vm->globals_lock);
817 
818     if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
819       LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
820                    << "failed to find entry";
821     }
822   }
823 
NewWeakGlobalRef(JNIEnv * env,jobject obj)824   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
825     ScopedObjectAccess soa(env);
826     return AddWeakGlobalReference(soa, soa.Decode<mirror::Object*>(obj));
827   }
828 
DeleteWeakGlobalRef(JNIEnv * env,jweak obj)829   static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
830     if (obj != nullptr) {
831       ScopedObjectAccess soa(env);
832       soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
833     }
834   }
835 
NewLocalRef(JNIEnv * env,jobject obj)836   static jobject NewLocalRef(JNIEnv* env, jobject obj) {
837     ScopedObjectAccess soa(env);
838     mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
839     // Check for null after decoding the object to handle cleared weak globals.
840     if (decoded_obj == nullptr) {
841       return nullptr;
842     }
843     return soa.AddLocalReference<jobject>(decoded_obj);
844   }
845 
DeleteLocalRef(JNIEnv * env,jobject obj)846   static void DeleteLocalRef(JNIEnv* env, jobject obj) {
847     if (obj == nullptr) {
848       return;
849     }
850     ScopedObjectAccess soa(env);
851     IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
852 
853     uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
854     if (!locals.Remove(cookie, obj)) {
855       // Attempting to delete a local reference that is not in the
856       // topmost local reference frame is a no-op.  DeleteLocalRef returns
857       // void and doesn't throw any exceptions, but we should probably
858       // complain about it so the user will notice that things aren't
859       // going quite the way they expect.
860       LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
861                    << "failed to find entry";
862     }
863   }
864 
IsSameObject(JNIEnv * env,jobject obj1,jobject obj2)865   static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
866     if (obj1 == obj2) {
867       return JNI_TRUE;
868     } else {
869       ScopedObjectAccess soa(env);
870       return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
871               ? JNI_TRUE : JNI_FALSE;
872     }
873   }
874 
AllocObject(JNIEnv * env,jclass java_class)875   static jobject AllocObject(JNIEnv* env, jclass java_class) {
876     CHECK_NON_NULL_ARGUMENT(java_class);
877     ScopedObjectAccess soa(env);
878     mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
879     if (c == nullptr) {
880       return nullptr;
881     }
882     return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
883   }
884 
NewObject(JNIEnv * env,jclass java_class,jmethodID mid,...)885   static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
886     va_list args;
887     va_start(args, mid);
888     CHECK_NON_NULL_ARGUMENT(java_class);
889     CHECK_NON_NULL_ARGUMENT(mid);
890     jobject result = NewObjectV(env, java_class, mid, args);
891     va_end(args);
892     return result;
893   }
894 
NewObjectV(JNIEnv * env,jclass java_class,jmethodID mid,va_list args)895   static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
896     CHECK_NON_NULL_ARGUMENT(java_class);
897     CHECK_NON_NULL_ARGUMENT(mid);
898     ScopedObjectAccess soa(env);
899     mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
900     if (c == nullptr) {
901       return nullptr;
902     }
903     mirror::Object* result = c->AllocObject(soa.Self());
904     if (result == nullptr) {
905       return nullptr;
906     }
907     jobject local_result = soa.AddLocalReference<jobject>(result);
908     CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
909     if (soa.Self()->IsExceptionPending()) {
910       return nullptr;
911     }
912     return local_result;
913   }
914 
NewObjectA(JNIEnv * env,jclass java_class,jmethodID mid,jvalue * args)915   static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
916     CHECK_NON_NULL_ARGUMENT(java_class);
917     CHECK_NON_NULL_ARGUMENT(mid);
918     ScopedObjectAccess soa(env);
919     mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
920     if (c == nullptr) {
921       return nullptr;
922     }
923     mirror::Object* result = c->AllocObject(soa.Self());
924     if (result == nullptr) {
925       return nullptr;
926     }
927     jobject local_result = soa.AddLocalReference<jobjectArray>(result);
928     CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
929     if (soa.Self()->IsExceptionPending()) {
930       return nullptr;
931     }
932     return local_result;
933   }
934 
GetMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)935   static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
936     CHECK_NON_NULL_ARGUMENT(java_class);
937     CHECK_NON_NULL_ARGUMENT(name);
938     CHECK_NON_NULL_ARGUMENT(sig);
939     ScopedObjectAccess soa(env);
940     return FindMethodID(soa, java_class, name, sig, false);
941   }
942 
GetStaticMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)943   static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
944                                      const char* sig) {
945     CHECK_NON_NULL_ARGUMENT(java_class);
946     CHECK_NON_NULL_ARGUMENT(name);
947     CHECK_NON_NULL_ARGUMENT(sig);
948     ScopedObjectAccess soa(env);
949     return FindMethodID(soa, java_class, name, sig, true);
950   }
951 
CallObjectMethod(JNIEnv * env,jobject obj,jmethodID mid,...)952   static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
953     va_list ap;
954     va_start(ap, mid);
955     CHECK_NON_NULL_ARGUMENT(obj);
956     CHECK_NON_NULL_ARGUMENT(mid);
957     ScopedObjectAccess soa(env);
958     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
959     va_end(ap);
960     return soa.AddLocalReference<jobject>(result.GetL());
961   }
962 
CallObjectMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)963   static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
964     CHECK_NON_NULL_ARGUMENT(obj);
965     CHECK_NON_NULL_ARGUMENT(mid);
966     ScopedObjectAccess soa(env);
967     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
968     return soa.AddLocalReference<jobject>(result.GetL());
969   }
970 
CallObjectMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)971   static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
972     CHECK_NON_NULL_ARGUMENT(obj);
973     CHECK_NON_NULL_ARGUMENT(mid);
974     ScopedObjectAccess soa(env);
975     JValue result(InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
976                                                       args));
977     return soa.AddLocalReference<jobject>(result.GetL());
978   }
979 
CallBooleanMethod(JNIEnv * env,jobject obj,jmethodID mid,...)980   static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
981     va_list ap;
982     va_start(ap, mid);
983     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
984     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
985     ScopedObjectAccess soa(env);
986     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
987     va_end(ap);
988     return result.GetZ();
989   }
990 
CallBooleanMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)991   static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
992     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
993     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
994     ScopedObjectAccess soa(env);
995     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
996   }
997 
CallBooleanMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)998   static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
999     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1000     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1001     ScopedObjectAccess soa(env);
1002     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1003                                                args).GetZ();
1004   }
1005 
CallByteMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1006   static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1007     va_list ap;
1008     va_start(ap, mid);
1009     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1010     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1011     ScopedObjectAccess soa(env);
1012     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1013     va_end(ap);
1014     return result.GetB();
1015   }
1016 
CallByteMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1017   static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1018     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1019     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1020     ScopedObjectAccess soa(env);
1021     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
1022   }
1023 
CallByteMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1024   static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1025     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1026     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1027     ScopedObjectAccess soa(env);
1028     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1029                                                args).GetB();
1030   }
1031 
CallCharMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1032   static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1033     va_list ap;
1034     va_start(ap, mid);
1035     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1036     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1037     ScopedObjectAccess soa(env);
1038     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1039     va_end(ap);
1040     return result.GetC();
1041   }
1042 
CallCharMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1043   static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1044     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1045     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1046     ScopedObjectAccess soa(env);
1047     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
1048   }
1049 
CallCharMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1050   static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1051     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1052     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1053     ScopedObjectAccess soa(env);
1054     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1055                                                args).GetC();
1056   }
1057 
CallDoubleMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1058   static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1059     va_list ap;
1060     va_start(ap, mid);
1061     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1062     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1063     ScopedObjectAccess soa(env);
1064     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1065     va_end(ap);
1066     return result.GetD();
1067   }
1068 
CallDoubleMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1069   static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1070     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1071     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1072     ScopedObjectAccess soa(env);
1073     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
1074   }
1075 
CallDoubleMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1076   static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1077     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1078     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1079     ScopedObjectAccess soa(env);
1080     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1081                                                args).GetD();
1082   }
1083 
CallFloatMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1084   static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1085     va_list ap;
1086     va_start(ap, mid);
1087     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1088     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1089     ScopedObjectAccess soa(env);
1090     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1091     va_end(ap);
1092     return result.GetF();
1093   }
1094 
CallFloatMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1095   static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1096     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1097     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1098     ScopedObjectAccess soa(env);
1099     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
1100   }
1101 
CallFloatMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1102   static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1103     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1104     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1105     ScopedObjectAccess soa(env);
1106     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1107                                                args).GetF();
1108   }
1109 
CallIntMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1110   static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1111     va_list ap;
1112     va_start(ap, mid);
1113     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1114     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1115     ScopedObjectAccess soa(env);
1116     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1117     va_end(ap);
1118     return result.GetI();
1119   }
1120 
CallIntMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1121   static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1122     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1123     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1124     ScopedObjectAccess soa(env);
1125     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
1126   }
1127 
CallIntMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1128   static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1129     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1130     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1131     ScopedObjectAccess soa(env);
1132     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1133                                                args).GetI();
1134   }
1135 
CallLongMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1136   static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1137     va_list ap;
1138     va_start(ap, mid);
1139     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1140     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1141     ScopedObjectAccess soa(env);
1142     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1143     va_end(ap);
1144     return result.GetJ();
1145   }
1146 
CallLongMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1147   static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1148     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1149     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1150     ScopedObjectAccess soa(env);
1151     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
1152   }
1153 
CallLongMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1154   static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1155     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1156     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1157     ScopedObjectAccess soa(env);
1158     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1159                                                args).GetJ();
1160   }
1161 
CallShortMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1162   static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1163     va_list ap;
1164     va_start(ap, mid);
1165     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1166     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1167     ScopedObjectAccess soa(env);
1168     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1169     va_end(ap);
1170     return result.GetS();
1171   }
1172 
CallShortMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1173   static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1174     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1175     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1176     ScopedObjectAccess soa(env);
1177     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
1178   }
1179 
CallShortMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1180   static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1181     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1182     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1183     ScopedObjectAccess soa(env);
1184     return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1185                                                args).GetS();
1186   }
1187 
CallVoidMethod(JNIEnv * env,jobject obj,jmethodID mid,...)1188   static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1189     va_list ap;
1190     va_start(ap, mid);
1191     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1192     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1193     ScopedObjectAccess soa(env);
1194     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
1195     va_end(ap);
1196   }
1197 
CallVoidMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)1198   static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1199     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1200     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1201     ScopedObjectAccess soa(env);
1202     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
1203   }
1204 
CallVoidMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)1205   static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1206     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1207     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1208     ScopedObjectAccess soa(env);
1209     InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
1210   }
1211 
CallNonvirtualObjectMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1212   static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1213     va_list ap;
1214     va_start(ap, mid);
1215     CHECK_NON_NULL_ARGUMENT(obj);
1216     CHECK_NON_NULL_ARGUMENT(mid);
1217     ScopedObjectAccess soa(env);
1218     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1219     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1220     va_end(ap);
1221     return local_result;
1222   }
1223 
CallNonvirtualObjectMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1224   static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1225                                              va_list args) {
1226     CHECK_NON_NULL_ARGUMENT(obj);
1227     CHECK_NON_NULL_ARGUMENT(mid);
1228     ScopedObjectAccess soa(env);
1229     JValue result(InvokeWithVarArgs(soa, obj, mid, args));
1230     return soa.AddLocalReference<jobject>(result.GetL());
1231   }
1232 
CallNonvirtualObjectMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1233   static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1234                                              jvalue* args) {
1235     CHECK_NON_NULL_ARGUMENT(obj);
1236     CHECK_NON_NULL_ARGUMENT(mid);
1237     ScopedObjectAccess soa(env);
1238     JValue result(InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args));
1239     return soa.AddLocalReference<jobject>(result.GetL());
1240   }
1241 
CallNonvirtualBooleanMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1242   static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1243                                               ...) {
1244     va_list ap;
1245     va_start(ap, mid);
1246     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1247     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1248     ScopedObjectAccess soa(env);
1249     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1250     va_end(ap);
1251     return result.GetZ();
1252   }
1253 
CallNonvirtualBooleanMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1254   static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1255                                                va_list args) {
1256     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1257     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1258     ScopedObjectAccess soa(env);
1259     return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
1260   }
1261 
CallNonvirtualBooleanMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1262   static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1263                                                jvalue* args) {
1264     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1265     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1266     ScopedObjectAccess soa(env);
1267     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetZ();
1268   }
1269 
CallNonvirtualByteMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1270   static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1271     va_list ap;
1272     va_start(ap, mid);
1273     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1274     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1275     ScopedObjectAccess soa(env);
1276     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1277     va_end(ap);
1278     return result.GetB();
1279   }
1280 
CallNonvirtualByteMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1281   static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1282                                          va_list args) {
1283     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1284     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1285     ScopedObjectAccess soa(env);
1286     return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1287   }
1288 
CallNonvirtualByteMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1289   static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1290                                          jvalue* args) {
1291     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1292     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1293     ScopedObjectAccess soa(env);
1294     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetB();
1295   }
1296 
CallNonvirtualCharMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1297   static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1298     va_list ap;
1299     va_start(ap, mid);
1300     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1301     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1302     ScopedObjectAccess soa(env);
1303     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1304     va_end(ap);
1305     return result.GetC();
1306   }
1307 
CallNonvirtualCharMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1308   static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1309                                          va_list args) {
1310     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1311     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1312     ScopedObjectAccess soa(env);
1313     return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1314   }
1315 
CallNonvirtualCharMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1316   static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1317                                          jvalue* args) {
1318     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1319     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1320     ScopedObjectAccess soa(env);
1321     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetC();
1322   }
1323 
CallNonvirtualShortMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1324   static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1325     va_list ap;
1326     va_start(ap, mid);
1327     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1328     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1329     ScopedObjectAccess soa(env);
1330     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1331     va_end(ap);
1332     return result.GetS();
1333   }
1334 
CallNonvirtualShortMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1335   static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1336                                            va_list args) {
1337     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1338     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1339     ScopedObjectAccess soa(env);
1340     return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1341   }
1342 
CallNonvirtualShortMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1343   static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1344                                            jvalue* args) {
1345     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1346     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1347     ScopedObjectAccess soa(env);
1348     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetS();
1349   }
1350 
CallNonvirtualIntMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1351   static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1352     va_list ap;
1353     va_start(ap, mid);
1354     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1355     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1356     ScopedObjectAccess soa(env);
1357     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1358     va_end(ap);
1359     return result.GetI();
1360   }
1361 
CallNonvirtualIntMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1362   static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1363                                        va_list args) {
1364     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1365     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1366     ScopedObjectAccess soa(env);
1367     return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1368   }
1369 
CallNonvirtualIntMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1370   static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1371                                        jvalue* args) {
1372     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1373     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1374     ScopedObjectAccess soa(env);
1375     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetI();
1376   }
1377 
CallNonvirtualLongMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1378   static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1379     va_list ap;
1380     va_start(ap, mid);
1381     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1382     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1383     ScopedObjectAccess soa(env);
1384     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1385     va_end(ap);
1386     return result.GetJ();
1387   }
1388 
CallNonvirtualLongMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1389   static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1390                                          va_list args) {
1391     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1392     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1393     ScopedObjectAccess soa(env);
1394     return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1395   }
1396 
CallNonvirtualLongMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1397   static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1398                                          jvalue* args) {
1399     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1400     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1401     ScopedObjectAccess soa(env);
1402     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetJ();
1403   }
1404 
CallNonvirtualFloatMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1405   static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1406     va_list ap;
1407     va_start(ap, mid);
1408     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1409     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1410     ScopedObjectAccess soa(env);
1411     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1412     va_end(ap);
1413     return result.GetF();
1414   }
1415 
CallNonvirtualFloatMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1416   static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1417                                            va_list args) {
1418     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1419     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1420     ScopedObjectAccess soa(env);
1421     return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1422   }
1423 
CallNonvirtualFloatMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1424   static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1425                                            jvalue* args) {
1426     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1427     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1428     ScopedObjectAccess soa(env);
1429     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetF();
1430   }
1431 
CallNonvirtualDoubleMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1432   static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1433     va_list ap;
1434     va_start(ap, mid);
1435     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1436     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1437     ScopedObjectAccess soa(env);
1438     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1439     va_end(ap);
1440     return result.GetD();
1441   }
1442 
CallNonvirtualDoubleMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1443   static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1444                                              va_list args) {
1445     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1446     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1447     ScopedObjectAccess soa(env);
1448     return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1449   }
1450 
CallNonvirtualDoubleMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1451   static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1452                                              jvalue* args) {
1453     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1454     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1455     ScopedObjectAccess soa(env);
1456     return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetD();
1457   }
1458 
CallNonvirtualVoidMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1459   static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1460     va_list ap;
1461     va_start(ap, mid);
1462     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1463     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1464     ScopedObjectAccess soa(env);
1465     InvokeWithVarArgs(soa, obj, mid, ap);
1466     va_end(ap);
1467   }
1468 
CallNonvirtualVoidMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1469   static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1470                                         va_list args) {
1471     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1472     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1473     ScopedObjectAccess soa(env);
1474     InvokeWithVarArgs(soa, obj, mid, args);
1475   }
1476 
CallNonvirtualVoidMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1477   static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1478                                         jvalue* args) {
1479     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1480     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1481     ScopedObjectAccess soa(env);
1482     InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
1483   }
1484 
GetFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1485   static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1486     CHECK_NON_NULL_ARGUMENT(java_class);
1487     CHECK_NON_NULL_ARGUMENT(name);
1488     CHECK_NON_NULL_ARGUMENT(sig);
1489     ScopedObjectAccess soa(env);
1490     return FindFieldID(soa, java_class, name, sig, false);
1491   }
1492 
GetStaticFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1493   static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1494                                    const char* sig) {
1495     CHECK_NON_NULL_ARGUMENT(java_class);
1496     CHECK_NON_NULL_ARGUMENT(name);
1497     CHECK_NON_NULL_ARGUMENT(sig);
1498     ScopedObjectAccess soa(env);
1499     return FindFieldID(soa, java_class, name, sig, true);
1500   }
1501 
GetObjectField(JNIEnv * env,jobject obj,jfieldID fid)1502   static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
1503     CHECK_NON_NULL_ARGUMENT(obj);
1504     CHECK_NON_NULL_ARGUMENT(fid);
1505     ScopedObjectAccess soa(env);
1506     mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1507     mirror::ArtField* f = soa.DecodeField(fid);
1508     return soa.AddLocalReference<jobject>(f->GetObject(o));
1509   }
1510 
GetStaticObjectField(JNIEnv * env,jclass,jfieldID fid)1511   static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
1512     CHECK_NON_NULL_ARGUMENT(fid);
1513     ScopedObjectAccess soa(env);
1514     mirror::ArtField* f = soa.DecodeField(fid);
1515     return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1516   }
1517 
SetObjectField(JNIEnv * env,jobject java_object,jfieldID fid,jobject java_value)1518   static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
1519     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1520     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1521     ScopedObjectAccess soa(env);
1522     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1523     mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1524     mirror::ArtField* f = soa.DecodeField(fid);
1525     f->SetObject<false>(o, v);
1526   }
1527 
SetStaticObjectField(JNIEnv * env,jclass,jfieldID fid,jobject java_value)1528   static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
1529     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1530     ScopedObjectAccess soa(env);
1531     mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1532     mirror::ArtField* f = soa.DecodeField(fid);
1533     f->SetObject<false>(f->GetDeclaringClass(), v);
1534   }
1535 
1536 #define GET_PRIMITIVE_FIELD(fn, instance) \
1537   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1538   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1539   ScopedObjectAccess soa(env); \
1540   mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1541   mirror::ArtField* f = soa.DecodeField(fid); \
1542   return f->Get ##fn (o)
1543 
1544 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
1545   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1546   ScopedObjectAccess soa(env); \
1547   mirror::ArtField* f = soa.DecodeField(fid); \
1548   return f->Get ##fn (f->GetDeclaringClass())
1549 
1550 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
1551   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1552   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1553   ScopedObjectAccess soa(env); \
1554   mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1555   mirror::ArtField* f = soa.DecodeField(fid); \
1556   f->Set ##fn <false>(o, value)
1557 
1558 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
1559   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1560   ScopedObjectAccess soa(env); \
1561   mirror::ArtField* f = soa.DecodeField(fid); \
1562   f->Set ##fn <false>(f->GetDeclaringClass(), value)
1563 
GetBooleanField(JNIEnv * env,jobject obj,jfieldID fid)1564   static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1565     GET_PRIMITIVE_FIELD(Boolean, obj);
1566   }
1567 
GetByteField(JNIEnv * env,jobject obj,jfieldID fid)1568   static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1569     GET_PRIMITIVE_FIELD(Byte, obj);
1570   }
1571 
GetCharField(JNIEnv * env,jobject obj,jfieldID fid)1572   static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1573     GET_PRIMITIVE_FIELD(Char, obj);
1574   }
1575 
GetShortField(JNIEnv * env,jobject obj,jfieldID fid)1576   static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1577     GET_PRIMITIVE_FIELD(Short, obj);
1578   }
1579 
GetIntField(JNIEnv * env,jobject obj,jfieldID fid)1580   static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1581     GET_PRIMITIVE_FIELD(Int, obj);
1582   }
1583 
GetLongField(JNIEnv * env,jobject obj,jfieldID fid)1584   static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1585     GET_PRIMITIVE_FIELD(Long, obj);
1586   }
1587 
GetFloatField(JNIEnv * env,jobject obj,jfieldID fid)1588   static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1589     GET_PRIMITIVE_FIELD(Float, obj);
1590   }
1591 
GetDoubleField(JNIEnv * env,jobject obj,jfieldID fid)1592   static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1593     GET_PRIMITIVE_FIELD(Double, obj);
1594   }
1595 
GetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid)1596   static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1597     GET_STATIC_PRIMITIVE_FIELD(Boolean);
1598   }
1599 
GetStaticByteField(JNIEnv * env,jclass,jfieldID fid)1600   static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1601     GET_STATIC_PRIMITIVE_FIELD(Byte);
1602   }
1603 
GetStaticCharField(JNIEnv * env,jclass,jfieldID fid)1604   static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1605     GET_STATIC_PRIMITIVE_FIELD(Char);
1606   }
1607 
GetStaticShortField(JNIEnv * env,jclass,jfieldID fid)1608   static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1609     GET_STATIC_PRIMITIVE_FIELD(Short);
1610   }
1611 
GetStaticIntField(JNIEnv * env,jclass,jfieldID fid)1612   static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1613     GET_STATIC_PRIMITIVE_FIELD(Int);
1614   }
1615 
GetStaticLongField(JNIEnv * env,jclass,jfieldID fid)1616   static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1617     GET_STATIC_PRIMITIVE_FIELD(Long);
1618   }
1619 
GetStaticFloatField(JNIEnv * env,jclass,jfieldID fid)1620   static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1621     GET_STATIC_PRIMITIVE_FIELD(Float);
1622   }
1623 
GetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid)1624   static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1625     GET_STATIC_PRIMITIVE_FIELD(Double);
1626   }
1627 
SetBooleanField(JNIEnv * env,jobject obj,jfieldID fid,jboolean v)1628   static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1629     SET_PRIMITIVE_FIELD(Boolean, obj, v);
1630   }
1631 
SetByteField(JNIEnv * env,jobject obj,jfieldID fid,jbyte v)1632   static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1633     SET_PRIMITIVE_FIELD(Byte, obj, v);
1634   }
1635 
SetCharField(JNIEnv * env,jobject obj,jfieldID fid,jchar v)1636   static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1637     SET_PRIMITIVE_FIELD(Char, obj, v);
1638   }
1639 
SetFloatField(JNIEnv * env,jobject obj,jfieldID fid,jfloat v)1640   static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1641     SET_PRIMITIVE_FIELD(Float, obj, v);
1642   }
1643 
SetDoubleField(JNIEnv * env,jobject obj,jfieldID fid,jdouble v)1644   static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1645     SET_PRIMITIVE_FIELD(Double, obj, v);
1646   }
1647 
SetIntField(JNIEnv * env,jobject obj,jfieldID fid,jint v)1648   static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1649     SET_PRIMITIVE_FIELD(Int, obj, v);
1650   }
1651 
SetLongField(JNIEnv * env,jobject obj,jfieldID fid,jlong v)1652   static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1653     SET_PRIMITIVE_FIELD(Long, obj, v);
1654   }
1655 
SetShortField(JNIEnv * env,jobject obj,jfieldID fid,jshort v)1656   static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1657     SET_PRIMITIVE_FIELD(Short, obj, v);
1658   }
1659 
SetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid,jboolean v)1660   static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1661     SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1662   }
1663 
SetStaticByteField(JNIEnv * env,jclass,jfieldID fid,jbyte v)1664   static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1665     SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1666   }
1667 
SetStaticCharField(JNIEnv * env,jclass,jfieldID fid,jchar v)1668   static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1669     SET_STATIC_PRIMITIVE_FIELD(Char, v);
1670   }
1671 
SetStaticFloatField(JNIEnv * env,jclass,jfieldID fid,jfloat v)1672   static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1673     SET_STATIC_PRIMITIVE_FIELD(Float, v);
1674   }
1675 
SetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid,jdouble v)1676   static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1677     SET_STATIC_PRIMITIVE_FIELD(Double, v);
1678   }
1679 
SetStaticIntField(JNIEnv * env,jclass,jfieldID fid,jint v)1680   static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1681     SET_STATIC_PRIMITIVE_FIELD(Int, v);
1682   }
1683 
SetStaticLongField(JNIEnv * env,jclass,jfieldID fid,jlong v)1684   static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1685     SET_STATIC_PRIMITIVE_FIELD(Long, v);
1686   }
1687 
SetStaticShortField(JNIEnv * env,jclass,jfieldID fid,jshort v)1688   static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1689     SET_STATIC_PRIMITIVE_FIELD(Short, v);
1690   }
1691 
CallStaticObjectMethod(JNIEnv * env,jclass,jmethodID mid,...)1692   static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1693     va_list ap;
1694     va_start(ap, mid);
1695     CHECK_NON_NULL_ARGUMENT(mid);
1696     ScopedObjectAccess soa(env);
1697     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1698     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1699     va_end(ap);
1700     return local_result;
1701   }
1702 
CallStaticObjectMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1703   static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1704     CHECK_NON_NULL_ARGUMENT(mid);
1705     ScopedObjectAccess soa(env);
1706     JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
1707     return soa.AddLocalReference<jobject>(result.GetL());
1708   }
1709 
CallStaticObjectMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1710   static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1711     CHECK_NON_NULL_ARGUMENT(mid);
1712     ScopedObjectAccess soa(env);
1713     JValue result(InvokeWithJValues(soa, nullptr, mid, args));
1714     return soa.AddLocalReference<jobject>(result.GetL());
1715   }
1716 
CallStaticBooleanMethod(JNIEnv * env,jclass,jmethodID mid,...)1717   static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1718     va_list ap;
1719     va_start(ap, mid);
1720     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1721     ScopedObjectAccess soa(env);
1722     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1723     va_end(ap);
1724     return result.GetZ();
1725   }
1726 
CallStaticBooleanMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1727   static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1728     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1729     ScopedObjectAccess soa(env);
1730     return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1731   }
1732 
CallStaticBooleanMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1733   static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1734     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1735     ScopedObjectAccess soa(env);
1736     return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1737   }
1738 
CallStaticByteMethod(JNIEnv * env,jclass,jmethodID mid,...)1739   static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1740     va_list ap;
1741     va_start(ap, mid);
1742     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1743     ScopedObjectAccess soa(env);
1744     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1745     va_end(ap);
1746     return result.GetB();
1747   }
1748 
CallStaticByteMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1749   static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1750     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1751     ScopedObjectAccess soa(env);
1752     return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1753   }
1754 
CallStaticByteMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1755   static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1756     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1757     ScopedObjectAccess soa(env);
1758     return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1759   }
1760 
CallStaticCharMethod(JNIEnv * env,jclass,jmethodID mid,...)1761   static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1762     va_list ap;
1763     va_start(ap, mid);
1764     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1765     ScopedObjectAccess soa(env);
1766     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1767     va_end(ap);
1768     return result.GetC();
1769   }
1770 
CallStaticCharMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1771   static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1772     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1773     ScopedObjectAccess soa(env);
1774     return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1775   }
1776 
CallStaticCharMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1777   static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1778     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1779     ScopedObjectAccess soa(env);
1780     return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1781   }
1782 
CallStaticShortMethod(JNIEnv * env,jclass,jmethodID mid,...)1783   static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1784     va_list ap;
1785     va_start(ap, mid);
1786     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1787     ScopedObjectAccess soa(env);
1788     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1789     va_end(ap);
1790     return result.GetS();
1791   }
1792 
CallStaticShortMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1793   static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1794     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1795     ScopedObjectAccess soa(env);
1796     return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1797   }
1798 
CallStaticShortMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1799   static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1800     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1801     ScopedObjectAccess soa(env);
1802     return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1803   }
1804 
CallStaticIntMethod(JNIEnv * env,jclass,jmethodID mid,...)1805   static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1806     va_list ap;
1807     va_start(ap, mid);
1808     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1809     ScopedObjectAccess soa(env);
1810     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1811     va_end(ap);
1812     return result.GetI();
1813   }
1814 
CallStaticIntMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1815   static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1816     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1817     ScopedObjectAccess soa(env);
1818     return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1819   }
1820 
CallStaticIntMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1821   static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1822     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1823     ScopedObjectAccess soa(env);
1824     return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1825   }
1826 
CallStaticLongMethod(JNIEnv * env,jclass,jmethodID mid,...)1827   static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1828     va_list ap;
1829     va_start(ap, mid);
1830     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1831     ScopedObjectAccess soa(env);
1832     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1833     va_end(ap);
1834     return result.GetJ();
1835   }
1836 
CallStaticLongMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1837   static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1838     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1839     ScopedObjectAccess soa(env);
1840     return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1841   }
1842 
CallStaticLongMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1843   static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1844     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1845     ScopedObjectAccess soa(env);
1846     return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1847   }
1848 
CallStaticFloatMethod(JNIEnv * env,jclass,jmethodID mid,...)1849   static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1850     va_list ap;
1851     va_start(ap, mid);
1852     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1853     ScopedObjectAccess soa(env);
1854     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1855     va_end(ap);
1856     return result.GetF();
1857   }
1858 
CallStaticFloatMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1859   static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1860     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1861     ScopedObjectAccess soa(env);
1862     return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1863   }
1864 
CallStaticFloatMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1865   static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1866     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1867     ScopedObjectAccess soa(env);
1868     return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1869   }
1870 
CallStaticDoubleMethod(JNIEnv * env,jclass,jmethodID mid,...)1871   static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1872     va_list ap;
1873     va_start(ap, mid);
1874     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1875     ScopedObjectAccess soa(env);
1876     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1877     va_end(ap);
1878     return result.GetD();
1879   }
1880 
CallStaticDoubleMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1881   static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1882     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1883     ScopedObjectAccess soa(env);
1884     return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1885   }
1886 
CallStaticDoubleMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1887   static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1888     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1889     ScopedObjectAccess soa(env);
1890     return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1891   }
1892 
CallStaticVoidMethod(JNIEnv * env,jclass,jmethodID mid,...)1893   static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1894     va_list ap;
1895     va_start(ap, mid);
1896     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1897     ScopedObjectAccess soa(env);
1898     InvokeWithVarArgs(soa, nullptr, mid, ap);
1899     va_end(ap);
1900   }
1901 
CallStaticVoidMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1902   static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1903     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1904     ScopedObjectAccess soa(env);
1905     InvokeWithVarArgs(soa, nullptr, mid, args);
1906   }
1907 
CallStaticVoidMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1908   static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1909     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1910     ScopedObjectAccess soa(env);
1911     InvokeWithJValues(soa, nullptr, mid, args);
1912   }
1913 
NewString(JNIEnv * env,const jchar * chars,jsize char_count)1914   static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
1915     if (UNLIKELY(char_count < 0)) {
1916       JniAbortF("NewString", "char_count < 0: %d", char_count);
1917       return nullptr;
1918     }
1919     if (UNLIKELY(chars == nullptr && char_count > 0)) {
1920       JniAbortF("NewString", "chars == null && char_count > 0");
1921       return nullptr;
1922     }
1923     ScopedObjectAccess soa(env);
1924     mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
1925     return soa.AddLocalReference<jstring>(result);
1926   }
1927 
NewStringUTF(JNIEnv * env,const char * utf)1928   static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1929     if (utf == nullptr) {
1930       return nullptr;
1931     }
1932     ScopedObjectAccess soa(env);
1933     mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
1934     return soa.AddLocalReference<jstring>(result);
1935   }
1936 
GetStringLength(JNIEnv * env,jstring java_string)1937   static jsize GetStringLength(JNIEnv* env, jstring java_string) {
1938     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1939     ScopedObjectAccess soa(env);
1940     return soa.Decode<mirror::String*>(java_string)->GetLength();
1941   }
1942 
GetStringUTFLength(JNIEnv * env,jstring java_string)1943   static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
1944     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1945     ScopedObjectAccess soa(env);
1946     return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
1947   }
1948 
GetStringRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,jchar * buf)1949   static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1950                               jchar* buf) {
1951     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1952     ScopedObjectAccess soa(env);
1953     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1954     if (start < 0 || length < 0 || start + length > s->GetLength()) {
1955       ThrowSIOOBE(soa, start, length, s->GetLength());
1956     } else {
1957       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1958       const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1959       memcpy(buf, chars + start, length * sizeof(jchar));
1960     }
1961   }
1962 
GetStringUTFRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,char * buf)1963   static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1964                                  char* buf) {
1965     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1966     ScopedObjectAccess soa(env);
1967     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1968     if (start < 0 || length < 0 || start + length > s->GetLength()) {
1969       ThrowSIOOBE(soa, start, length, s->GetLength());
1970     } else {
1971       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1972       const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1973       ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1974     }
1975   }
1976 
GetStringChars(JNIEnv * env,jstring java_string,jboolean * is_copy)1977   static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1978     CHECK_NON_NULL_ARGUMENT(java_string);
1979     ScopedObjectAccess soa(env);
1980     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1981     mirror::CharArray* chars = s->GetCharArray();
1982     gc::Heap* heap = Runtime::Current()->GetHeap();
1983     if (heap->IsMovableObject(chars)) {
1984       if (is_copy != nullptr) {
1985         *is_copy = JNI_TRUE;
1986       }
1987       int32_t char_count = s->GetLength();
1988       int32_t offset = s->GetOffset();
1989       jchar* bytes = new jchar[char_count];
1990       for (int32_t i = 0; i < char_count; i++) {
1991         bytes[i] = chars->Get(i + offset);
1992       }
1993       return bytes;
1994     } else {
1995       if (is_copy != nullptr) {
1996         *is_copy = JNI_FALSE;
1997       }
1998       return static_cast<jchar*>(chars->GetData() + s->GetOffset());
1999     }
2000   }
2001 
ReleaseStringChars(JNIEnv * env,jstring java_string,const jchar * chars)2002   static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
2003     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2004     ScopedObjectAccess soa(env);
2005     mirror::String* s = soa.Decode<mirror::String*>(java_string);
2006     mirror::CharArray* s_chars = s->GetCharArray();
2007     if (chars != (s_chars->GetData() + s->GetOffset())) {
2008       delete[] chars;
2009     }
2010   }
2011 
GetStringCritical(JNIEnv * env,jstring java_string,jboolean * is_copy)2012   static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2013     CHECK_NON_NULL_ARGUMENT(java_string);
2014     ScopedObjectAccess soa(env);
2015     mirror::String* s = soa.Decode<mirror::String*>(java_string);
2016     mirror::CharArray* chars = s->GetCharArray();
2017     int32_t offset = s->GetOffset();
2018     gc::Heap* heap = Runtime::Current()->GetHeap();
2019     if (heap->IsMovableObject(chars)) {
2020       StackHandleScope<1> hs(soa.Self());
2021       HandleWrapper<mirror::CharArray> h(hs.NewHandleWrapper(&chars));
2022       heap->IncrementDisableMovingGC(soa.Self());
2023     }
2024     if (is_copy != nullptr) {
2025       *is_copy = JNI_FALSE;
2026     }
2027     return static_cast<jchar*>(chars->GetData() + offset);
2028   }
2029 
ReleaseStringCritical(JNIEnv * env,jstring java_string,const jchar * chars)2030   static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
2031     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2032     ScopedObjectAccess soa(env);
2033     gc::Heap* heap = Runtime::Current()->GetHeap();
2034     mirror::String* s = soa.Decode<mirror::String*>(java_string);
2035     mirror::CharArray* s_chars = s->GetCharArray();
2036     if (heap->IsMovableObject(s_chars)) {
2037       heap->DecrementDisableMovingGC(soa.Self());
2038     }
2039   }
2040 
GetStringUTFChars(JNIEnv * env,jstring java_string,jboolean * is_copy)2041   static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2042     if (java_string == nullptr) {
2043       return nullptr;
2044     }
2045     if (is_copy != nullptr) {
2046       *is_copy = JNI_TRUE;
2047     }
2048     ScopedObjectAccess soa(env);
2049     mirror::String* s = soa.Decode<mirror::String*>(java_string);
2050     size_t byte_count = s->GetUtfLength();
2051     char* bytes = new char[byte_count + 1];
2052     CHECK(bytes != nullptr);  // bionic aborts anyway.
2053     const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
2054     ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
2055     bytes[byte_count] = '\0';
2056     return bytes;
2057   }
2058 
ReleaseStringUTFChars(JNIEnv * env,jstring,const char * chars)2059   static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
2060     delete[] chars;
2061   }
2062 
GetArrayLength(JNIEnv * env,jarray java_array)2063   static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
2064     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
2065     ScopedObjectAccess soa(env);
2066     mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
2067     if (UNLIKELY(!obj->IsArrayInstance())) {
2068       JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
2069     }
2070     mirror::Array* array = obj->AsArray();
2071     return array->GetLength();
2072   }
2073 
GetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index)2074   static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
2075     CHECK_NON_NULL_ARGUMENT(java_array);
2076     ScopedObjectAccess soa(env);
2077     mirror::ObjectArray<mirror::Object>* array =
2078         soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
2079     return soa.AddLocalReference<jobject>(array->Get(index));
2080   }
2081 
SetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index,jobject java_value)2082   static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2083                                     jobject java_value) {
2084     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2085     ScopedObjectAccess soa(env);
2086     mirror::ObjectArray<mirror::Object>* array =
2087         soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
2088     mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
2089     array->Set<false>(index, value);
2090   }
2091 
NewBooleanArray(JNIEnv * env,jsize length)2092   static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
2093     return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
2094   }
2095 
NewByteArray(JNIEnv * env,jsize length)2096   static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
2097     return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
2098   }
2099 
NewCharArray(JNIEnv * env,jsize length)2100   static jcharArray NewCharArray(JNIEnv* env, jsize length) {
2101     return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
2102   }
2103 
NewDoubleArray(JNIEnv * env,jsize length)2104   static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
2105     return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
2106   }
2107 
NewFloatArray(JNIEnv * env,jsize length)2108   static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
2109     return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
2110   }
2111 
NewIntArray(JNIEnv * env,jsize length)2112   static jintArray NewIntArray(JNIEnv* env, jsize length) {
2113     return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
2114   }
2115 
NewLongArray(JNIEnv * env,jsize length)2116   static jlongArray NewLongArray(JNIEnv* env, jsize length) {
2117     return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
2118   }
2119 
NewObjectArray(JNIEnv * env,jsize length,jclass element_jclass,jobject initial_element)2120   static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
2121                                      jobject initial_element) {
2122     if (UNLIKELY(length < 0)) {
2123       JniAbortF("NewObjectArray", "negative array length: %d", length);
2124       return nullptr;
2125     }
2126     CHECK_NON_NULL_ARGUMENT(element_jclass);
2127 
2128     // Compute the array class corresponding to the given element class.
2129     ScopedObjectAccess soa(env);
2130     mirror::Class* array_class;
2131     {
2132       mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
2133       if (UNLIKELY(element_class->IsPrimitive())) {
2134         JniAbortF("NewObjectArray", "not an object type: %s",
2135                   PrettyDescriptor(element_class).c_str());
2136         return nullptr;
2137       }
2138       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2139       array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
2140       if (UNLIKELY(array_class == nullptr)) {
2141         return nullptr;
2142       }
2143     }
2144 
2145     // Allocate and initialize if necessary.
2146     mirror::ObjectArray<mirror::Object>* result =
2147         mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
2148     if (result != nullptr && initial_element != nullptr) {
2149       mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
2150       if (initial_object != nullptr) {
2151         mirror::Class* element_class = result->GetClass()->GetComponentType();
2152         if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
2153           JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with element "
2154                     "type of '%s'", PrettyDescriptor(initial_object->GetClass()).c_str(),
2155                     PrettyDescriptor(element_class).c_str());
2156 
2157         } else {
2158           for (jsize i = 0; i < length; ++i) {
2159             result->SetWithoutChecks<false>(i, initial_object);
2160           }
2161         }
2162       }
2163     }
2164     return soa.AddLocalReference<jobjectArray>(result);
2165   }
2166 
NewShortArray(JNIEnv * env,jsize length)2167   static jshortArray NewShortArray(JNIEnv* env, jsize length) {
2168     return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
2169   }
2170 
GetPrimitiveArrayCritical(JNIEnv * env,jarray java_array,jboolean * is_copy)2171   static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
2172     CHECK_NON_NULL_ARGUMENT(java_array);
2173     ScopedObjectAccess soa(env);
2174     mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
2175     if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2176       JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
2177                 PrettyDescriptor(array->GetClass()).c_str());
2178       return nullptr;
2179     }
2180     gc::Heap* heap = Runtime::Current()->GetHeap();
2181     if (heap->IsMovableObject(array)) {
2182       heap->IncrementDisableMovingGC(soa.Self());
2183       // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
2184       array = soa.Decode<mirror::Array*>(java_array);
2185     }
2186     if (is_copy != nullptr) {
2187       *is_copy = JNI_FALSE;
2188     }
2189     return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
2190   }
2191 
ReleasePrimitiveArrayCritical(JNIEnv * env,jarray java_array,void * elements,jint mode)2192   static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
2193                                             jint mode) {
2194     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2195     ScopedObjectAccess soa(env);
2196     mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
2197     if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2198       JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
2199                 PrettyDescriptor(array->GetClass()).c_str());
2200       return;
2201     }
2202     const size_t component_size = array->GetClass()->GetComponentSize();
2203     ReleasePrimitiveArray(soa, array, component_size, elements, mode);
2204   }
2205 
GetBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * is_copy)2206   static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
2207     return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
2208   }
2209 
GetByteArrayElements(JNIEnv * env,jbyteArray array,jboolean * is_copy)2210   static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
2211     return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
2212   }
2213 
GetCharArrayElements(JNIEnv * env,jcharArray array,jboolean * is_copy)2214   static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
2215     return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
2216   }
2217 
GetDoubleArrayElements(JNIEnv * env,jdoubleArray array,jboolean * is_copy)2218   static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
2219     return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
2220   }
2221 
GetFloatArrayElements(JNIEnv * env,jfloatArray array,jboolean * is_copy)2222   static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
2223     return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
2224   }
2225 
GetIntArrayElements(JNIEnv * env,jintArray array,jboolean * is_copy)2226   static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
2227     return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
2228   }
2229 
GetLongArrayElements(JNIEnv * env,jlongArray array,jboolean * is_copy)2230   static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
2231     return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
2232   }
2233 
GetShortArrayElements(JNIEnv * env,jshortArray array,jboolean * is_copy)2234   static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
2235     return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
2236   }
2237 
ReleaseBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * elements,jint mode)2238   static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2239                                           jint mode) {
2240     ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2241                                                                          mode);
2242   }
2243 
ReleaseByteArrayElements(JNIEnv * env,jbyteArray array,jbyte * elements,jint mode)2244   static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
2245     ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
2246   }
2247 
ReleaseCharArrayElements(JNIEnv * env,jcharArray array,jchar * elements,jint mode)2248   static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
2249     ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
2250   }
2251 
ReleaseDoubleArrayElements(JNIEnv * env,jdoubleArray array,jdouble * elements,jint mode)2252   static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2253                                          jint mode) {
2254     ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
2255   }
2256 
ReleaseFloatArrayElements(JNIEnv * env,jfloatArray array,jfloat * elements,jint mode)2257   static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2258                                         jint mode) {
2259     ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
2260   }
2261 
ReleaseIntArrayElements(JNIEnv * env,jintArray array,jint * elements,jint mode)2262   static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
2263     ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
2264   }
2265 
ReleaseLongArrayElements(JNIEnv * env,jlongArray array,jlong * elements,jint mode)2266   static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
2267     ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
2268   }
2269 
ReleaseShortArrayElements(JNIEnv * env,jshortArray array,jshort * elements,jint mode)2270   static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2271                                         jint mode) {
2272     ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
2273   }
2274 
GetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,jboolean * buf)2275   static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2276                                     jboolean* buf) {
2277     GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2278                                                                            length, buf);
2279   }
2280 
GetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,jbyte * buf)2281   static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2282                                  jbyte* buf) {
2283     GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2284   }
2285 
GetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,jchar * buf)2286   static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2287                                  jchar* buf) {
2288     GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2289   }
2290 
GetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,jdouble * buf)2291   static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2292                                    jdouble* buf) {
2293     GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2294                                                                         buf);
2295   }
2296 
GetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,jfloat * buf)2297   static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2298                                   jfloat* buf) {
2299     GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2300                                                                      buf);
2301   }
2302 
GetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,jint * buf)2303   static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2304                                 jint* buf) {
2305     GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2306   }
2307 
GetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,jlong * buf)2308   static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2309                                  jlong* buf) {
2310     GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2311   }
2312 
GetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,jshort * buf)2313   static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2314                                   jshort* buf) {
2315     GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2316                                                                      buf);
2317   }
2318 
SetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,const jboolean * buf)2319   static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2320                                     const jboolean* buf) {
2321     SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2322                                                                            length, buf);
2323   }
2324 
SetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,const jbyte * buf)2325   static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2326                                  const jbyte* buf) {
2327     SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2328   }
2329 
SetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,const jchar * buf)2330   static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2331                                  const jchar* buf) {
2332     SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2333   }
2334 
SetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,const jdouble * buf)2335   static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2336                                    const jdouble* buf) {
2337     SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2338                                                                         buf);
2339   }
2340 
SetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,const jfloat * buf)2341   static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2342                                   const jfloat* buf) {
2343     SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2344                                                                      buf);
2345   }
2346 
SetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,const jint * buf)2347   static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2348                                 const jint* buf) {
2349     SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2350   }
2351 
SetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,const jlong * buf)2352   static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2353                                  const jlong* buf) {
2354     SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2355   }
2356 
SetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,const jshort * buf)2357   static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2358                                   const jshort* buf) {
2359     SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2360                                                                      buf);
2361   }
2362 
RegisterNatives(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count)2363   static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2364                               jint method_count) {
2365     return RegisterNativeMethods(env, java_class, methods, method_count, true);
2366   }
2367 
RegisterNativeMethods(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count,bool return_errors)2368   static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2369                                     jint method_count, bool return_errors) {
2370     if (UNLIKELY(method_count < 0)) {
2371       JniAbortF("RegisterNatives", "negative method count: %d", method_count);
2372       return JNI_ERR;  // Not reached.
2373     }
2374     CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
2375     ScopedObjectAccess soa(env);
2376     mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2377     if (UNLIKELY(method_count == 0)) {
2378       LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2379           << PrettyDescriptor(c);
2380       return JNI_OK;
2381     }
2382     CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2383     for (jint i = 0; i < method_count; ++i) {
2384       const char* name = methods[i].name;
2385       const char* sig = methods[i].signature;
2386       const void* fnPtr = methods[i].fnPtr;
2387       if (UNLIKELY(name == nullptr)) {
2388         ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2389         return JNI_ERR;
2390       } else if (UNLIKELY(sig == nullptr)) {
2391         ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2392         return JNI_ERR;
2393       } else if (UNLIKELY(fnPtr == nullptr)) {
2394         ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2395         return JNI_ERR;
2396       }
2397       bool is_fast = false;
2398       if (*sig == '!') {
2399         is_fast = true;
2400         ++sig;
2401       }
2402 
2403       mirror::ArtMethod* m = c->FindDirectMethod(name, sig);
2404       if (m == nullptr) {
2405         m = c->FindVirtualMethod(name, sig);
2406       }
2407       if (m == nullptr) {
2408         c->DumpClass(LOG(ERROR), mirror::Class::kDumpClassFullDetail);
2409         LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
2410             << PrettyDescriptor(c) << "." << name << sig << " in "
2411             << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
2412         ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2413         return JNI_ERR;
2414       } else if (!m->IsNative()) {
2415         LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2416             << PrettyDescriptor(c) << "." << name << sig
2417             << " as native";
2418         ThrowNoSuchMethodError(soa, c, name, sig, "native");
2419         return JNI_ERR;
2420       }
2421 
2422       VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
2423 
2424       m->RegisterNative(soa.Self(), fnPtr, is_fast);
2425     }
2426     return JNI_OK;
2427   }
2428 
UnregisterNatives(JNIEnv * env,jclass java_class)2429   static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
2430     CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
2431     ScopedObjectAccess soa(env);
2432     mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2433 
2434     VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
2435 
2436     size_t unregistered_count = 0;
2437     for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
2438       mirror::ArtMethod* m = c->GetDirectMethod(i);
2439       if (m->IsNative()) {
2440         m->UnregisterNative(soa.Self());
2441         unregistered_count++;
2442       }
2443     }
2444     for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
2445       mirror::ArtMethod* m = c->GetVirtualMethod(i);
2446       if (m->IsNative()) {
2447         m->UnregisterNative(soa.Self());
2448         unregistered_count++;
2449       }
2450     }
2451 
2452     if (unregistered_count == 0) {
2453       LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2454           << PrettyDescriptor(c) << "' that contains no native methods";
2455     }
2456     return JNI_OK;
2457   }
2458 
MonitorEnter(JNIEnv * env,jobject java_object)2459   static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2460     CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2461     ScopedObjectAccess soa(env);
2462     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2463     o = o->MonitorEnter(soa.Self());
2464     if (soa.Self()->IsExceptionPending()) {
2465       return JNI_ERR;
2466     }
2467     soa.Env()->monitors.Add(o);
2468     return JNI_OK;
2469   }
2470 
MonitorExit(JNIEnv * env,jobject java_object)2471   static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2472     CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2473     ScopedObjectAccess soa(env);
2474     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2475     o->MonitorExit(soa.Self());
2476     if (soa.Self()->IsExceptionPending()) {
2477       return JNI_ERR;
2478     }
2479     soa.Env()->monitors.Remove(o);
2480     return JNI_OK;
2481   }
2482 
GetJavaVM(JNIEnv * env,JavaVM ** vm)2483   static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
2484     CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2485     Runtime* runtime = Runtime::Current();
2486     if (runtime != nullptr) {
2487       *vm = runtime->GetJavaVM();
2488     } else {
2489       *vm = nullptr;
2490     }
2491     return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2492   }
2493 
NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)2494   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
2495     if (capacity < 0) {
2496       JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64, capacity);
2497       return nullptr;
2498     }
2499     if (address == nullptr && capacity != 0) {
2500       JniAbortF("NewDirectByteBuffer", "non-zero capacity for nullptr pointer: %" PRId64, capacity);
2501       return nullptr;
2502     }
2503 
2504     // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
2505     if (capacity > INT_MAX) {
2506       JniAbortF("NewDirectByteBuffer", "buffer capacity greater than maximum jint: %" PRId64, capacity);
2507       return nullptr;
2508     }
2509     jlong address_arg = reinterpret_cast<jlong>(address);
2510     jint capacity_arg = static_cast<jint>(capacity);
2511 
2512     jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2513                                     WellKnownClasses::java_nio_DirectByteBuffer_init,
2514                                     address_arg, capacity_arg);
2515     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
2516   }
2517 
GetDirectBufferAddress(JNIEnv * env,jobject java_buffer)2518   static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2519     return reinterpret_cast<void*>(env->GetLongField(
2520         java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2521   }
2522 
GetDirectBufferCapacity(JNIEnv * env,jobject java_buffer)2523   static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2524     return static_cast<jlong>(env->GetIntField(
2525         java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2526   }
2527 
GetObjectRefType(JNIEnv * env,jobject java_object)2528   static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
2529     if (java_object == nullptr) {
2530       return JNIInvalidRefType;
2531     }
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, RootInfo(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