Home | History | Annotate | Download | only in runtime
      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 
     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 
     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").
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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:
    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 
    363   mirror::Object* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    364     return class_loader_.Read();
    365   }
    366 
    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    */
    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 
    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 
    415   void SetNeedsNativeBridge() {
    416     needs_native_bridge_ = true;
    417   }
    418 
    419   bool NeedsNativeBridge() const {
    420     return needs_native_bridge_;
    421   }
    422 
    423   void* FindSymbol(const std::string& symbol_name) {
    424     return dlsym(handle_, symbol_name.c_str());
    425   }
    426 
    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 
    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:
    475   Libraries() {
    476   }
    477 
    478   ~Libraries() {
    479     STLDeleteValues(&libraries_);
    480   }
    481 
    482   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 
    493   size_t size() const {
    494     return libraries_.size();
    495   }
    496 
    497   SharedLibrary* Get(const std::string& path) {
    498     auto it = libraries_.find(path);
    499     return (it == libraries_.end()) ? nullptr : it->second;
    500   }
    501 
    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.
    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 
    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:
    580   static jint GetVersion(JNIEnv*) {
    581     return JNI_VERSION_1_6;
    582   }
    583 
    584   static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
    585     LOG(WARNING) << "JNI DefineClass is not supported";
    586     return nullptr;
    587   }
    588 
    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 
    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 
    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 
    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 
    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 
    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 
    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.
    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 
    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 
    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 
    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 
    706   static jboolean ExceptionCheck(JNIEnv* env) {
    707     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
    708   }
    709 
    710   static void ExceptionClear(JNIEnv* env) {
    711     ScopedObjectAccess soa(env);
    712     soa.Self()->ClearException();
    713   }
    714 
    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 
    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 
    768   static void FatalError(JNIEnv*, const char* msg) {
    769     LOG(FATAL) << "JNI FatalError called: " << msg;
    770   }
    771 
    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 
    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 
    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 
    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 
    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 
    824   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
    825     ScopedObjectAccess soa(env);
    826     return AddWeakGlobalReference(soa, soa.Decode<mirror::Object*>(obj));
    827   }
    828 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   1564   static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
   1565     GET_PRIMITIVE_FIELD(Boolean, obj);
   1566   }
   1567 
   1568   static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
   1569     GET_PRIMITIVE_FIELD(Byte, obj);
   1570   }
   1571 
   1572   static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
   1573     GET_PRIMITIVE_FIELD(Char, obj);
   1574   }
   1575 
   1576   static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
   1577     GET_PRIMITIVE_FIELD(Short, obj);
   1578   }
   1579 
   1580   static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
   1581     GET_PRIMITIVE_FIELD(Int, obj);
   1582   }
   1583 
   1584   static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
   1585     GET_PRIMITIVE_FIELD(Long, obj);
   1586   }
   1587 
   1588   static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
   1589     GET_PRIMITIVE_FIELD(Float, obj);
   1590   }
   1591 
   1592   static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
   1593     GET_PRIMITIVE_FIELD(Double, obj);
   1594   }
   1595 
   1596   static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
   1597     GET_STATIC_PRIMITIVE_FIELD(Boolean);
   1598   }
   1599 
   1600   static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
   1601     GET_STATIC_PRIMITIVE_FIELD(Byte);
   1602   }
   1603 
   1604   static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
   1605     GET_STATIC_PRIMITIVE_FIELD(Char);
   1606   }
   1607 
   1608   static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
   1609     GET_STATIC_PRIMITIVE_FIELD(Short);
   1610   }
   1611 
   1612   static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
   1613     GET_STATIC_PRIMITIVE_FIELD(Int);
   1614   }
   1615 
   1616   static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
   1617     GET_STATIC_PRIMITIVE_FIELD(Long);
   1618   }
   1619 
   1620   static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
   1621     GET_STATIC_PRIMITIVE_FIELD(Float);
   1622   }
   1623 
   1624   static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
   1625     GET_STATIC_PRIMITIVE_FIELD(Double);
   1626   }
   1627 
   1628   static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
   1629     SET_PRIMITIVE_FIELD(Boolean, obj, v);
   1630   }
   1631 
   1632   static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
   1633     SET_PRIMITIVE_FIELD(Byte, obj, v);
   1634   }
   1635 
   1636   static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
   1637     SET_PRIMITIVE_FIELD(Char, obj, v);
   1638   }
   1639 
   1640   static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
   1641     SET_PRIMITIVE_FIELD(Float, obj, v);
   1642   }
   1643 
   1644   static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
   1645     SET_PRIMITIVE_FIELD(Double, obj, v);
   1646   }
   1647 
   1648   static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
   1649     SET_PRIMITIVE_FIELD(Int, obj, v);
   1650   }
   1651 
   1652   static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
   1653     SET_PRIMITIVE_FIELD(Long, obj, v);
   1654   }
   1655 
   1656   static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
   1657     SET_PRIMITIVE_FIELD(Short, obj, v);
   1658   }
   1659 
   1660   static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
   1661     SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
   1662   }
   1663 
   1664   static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
   1665     SET_STATIC_PRIMITIVE_FIELD(Byte, v);
   1666   }
   1667 
   1668   static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
   1669     SET_STATIC_PRIMITIVE_FIELD(Char, v);
   1670   }
   1671 
   1672   static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
   1673     SET_STATIC_PRIMITIVE_FIELD(Float, v);
   1674   }
   1675 
   1676   static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
   1677     SET_STATIC_PRIMITIVE_FIELD(Double, v);
   1678   }
   1679 
   1680   static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
   1681     SET_STATIC_PRIMITIVE_FIELD(Int, v);
   1682   }
   1683 
   1684   static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
   1685     SET_STATIC_PRIMITIVE_FIELD(Long, v);
   1686   }
   1687 
   1688   static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
   1689     SET_STATIC_PRIMITIVE_FIELD(Short, v);
   1690   }
   1691 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   2059   static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
   2060     delete[] chars;
   2061   }
   2062 
   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 
   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 
   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 
   2092   static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
   2093     return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
   2094   }
   2095 
   2096   static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
   2097     return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
   2098   }
   2099 
   2100   static jcharArray NewCharArray(JNIEnv* env, jsize length) {
   2101     return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
   2102   }
   2103 
   2104   static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
   2105     return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
   2106   }
   2107 
   2108   static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
   2109     return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
   2110   }
   2111 
   2112   static jintArray NewIntArray(JNIEnv* env, jsize length) {
   2113     return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
   2114   }
   2115 
   2116   static jlongArray NewLongArray(JNIEnv* env, jsize length) {
   2117     return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
   2118   }
   2119 
   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 
   2167   static jshortArray NewShortArray(JNIEnv* env, jsize length) {
   2168     return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
   2169   }
   2170 
   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 
   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 
   2206   static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
   2207     return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
   2208   }
   2209 
   2210   static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
   2211     return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
   2212   }
   2213 
   2214   static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
   2215     return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
   2216   }
   2217 
   2218   static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
   2219     return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
   2220   }
   2221 
   2222   static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
   2223     return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
   2224   }
   2225 
   2226   static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
   2227     return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
   2228   }
   2229 
   2230   static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
   2231     return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
   2232   }
   2233 
   2234   static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
   2235     return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
   2236   }
   2237 
   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 
   2244   static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
   2245     ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
   2246   }
   2247 
   2248   static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
   2249     ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
   2250   }
   2251 
   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 
   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 
   2262   static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
   2263     ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
   2264   }
   2265 
   2266   static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
   2267     ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
   2268   }
   2269 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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:
   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>
   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>
   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>
   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>
   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 
   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>
   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>
   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 
   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 
   2969 JNIEnvExt::~JNIEnvExt() {
   2970 }
   2971 
   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 
   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 }
   2984 void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
   2985   check_jni = enabled;
   2986   functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
   2987 }
   2988 
   2989 void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
   2990   locals.Dump(os);
   2991   monitors.Dump(os);
   2992 }
   2993 
   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 
   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 
   3007 Offset JNIEnvExt::SegmentStateOffset() {
   3008   return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
   3009                 IndirectReferenceTable::SegmentStateOffset().Int32Value());
   3010 }
   3011 
   3012 // JNI Invocation interface.
   3013 
   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 
   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.
   3054 extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
   3055   return JNI_ERR;
   3056 }
   3057 
   3058 class JII {
   3059  public:
   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 
   3069   static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
   3070     return JII_AttachCurrentThread(vm, p_env, thr_args, false);
   3071   }
   3072 
   3073   static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
   3074     return JII_AttachCurrentThread(vm, p_env, thr_args, true);
   3075   }
   3076 
   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 
   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 
   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 
   3140 JavaVMExt::~JavaVMExt() {
   3141   delete libraries;
   3142 }
   3143 
   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 
   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 
   3164 void JavaVMExt::SetCheckJniEnabled(bool enabled) {
   3165   check_jni = enabled;
   3166   functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
   3167 }
   3168 
   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 
   3193 void JavaVMExt::DisallowNewWeakGlobals() {
   3194   MutexLock mu(Thread::Current(), weak_globals_lock_);
   3195   allow_new_weak_globals_ = false;
   3196 }
   3197 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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