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