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 "art_field-inl.h"
     27 #include "art_method-inl.h"
     28 #include "atomic.h"
     29 #include "base/allocator.h"
     30 #include "base/enums.h"
     31 #include "base/logging.h"
     32 #include "base/mutex.h"
     33 #include "base/stl_util.h"
     34 #include "class_linker-inl.h"
     35 #include "dex_file-inl.h"
     36 #include "fault_handler.h"
     37 #include "gc_root.h"
     38 #include "gc/accounting/card_table-inl.h"
     39 #include "indirect_reference_table-inl.h"
     40 #include "interpreter/interpreter.h"
     41 #include "jni_env_ext.h"
     42 #include "java_vm_ext.h"
     43 #include "mirror/class-inl.h"
     44 #include "mirror/class_loader.h"
     45 #include "mirror/field-inl.h"
     46 #include "mirror/method.h"
     47 #include "mirror/object-inl.h"
     48 #include "mirror/object_array-inl.h"
     49 #include "mirror/string-inl.h"
     50 #include "mirror/throwable.h"
     51 #include "parsed_options.h"
     52 #include "reflection.h"
     53 #include "runtime.h"
     54 #include "safe_map.h"
     55 #include "scoped_thread_state_change-inl.h"
     56 #include "ScopedLocalRef.h"
     57 #include "thread.h"
     58 #include "utf.h"
     59 #include "well_known_classes.h"
     60 
     61 namespace art {
     62 
     63 // Consider turning this on when there is errors which could be related to JNI array copies such as
     64 // things not rendering correctly. E.g. b/16858794
     65 static constexpr bool kWarnJniAbort = false;
     66 
     67 // Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
     68 // separated with slashes but aren't wrapped with "L;" like regular descriptors
     69 // (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
     70 // exception; there the "L;" must be present ("[La/b/C;"). Historically we've
     71 // supported names with dots too (such as "a.b.C").
     72 static std::string NormalizeJniClassDescriptor(const char* name) {
     73   std::string result;
     74   // Add the missing "L;" if necessary.
     75   if (name[0] == '[') {
     76     result = name;
     77   } else {
     78     result += 'L';
     79     result += name;
     80     result += ';';
     81   }
     82   // Rewrite '.' as '/' for backwards compatibility.
     83   if (result.find('.') != std::string::npos) {
     84     LOG(WARNING) << "Call to JNI FindClass with dots in name: "
     85                  << "\"" << name << "\"";
     86     std::replace(result.begin(), result.end(), '.', '/');
     87   }
     88   return result;
     89 }
     90 
     91 static void ThrowNoSuchMethodError(ScopedObjectAccess& soa,
     92                                    ObjPtr<mirror::Class> c,
     93                                    const char* name,
     94                                    const char* sig,
     95                                    const char* kind)
     96     REQUIRES_SHARED(Locks::mutator_lock_) {
     97   std::string temp;
     98   soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
     99                                  "no %s method \"%s.%s%s\"",
    100                                  kind,
    101                                  c->GetDescriptor(&temp),
    102                                  name,
    103                                  sig);
    104 }
    105 
    106 static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa,
    107                                          ObjPtr<mirror::Class> c,
    108                                          const char* kind,
    109                                          jint idx,
    110                                          bool return_errors)
    111     REQUIRES_SHARED(Locks::mutator_lock_) {
    112   LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
    113       << "Failed to register native method in " << c->PrettyDescriptor()
    114       << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
    115       << ": " << kind << " is null at index " << idx;
    116   soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
    117                                  "%s is null at index %d",
    118                                  kind,
    119                                  idx);
    120 }
    121 
    122 static ObjPtr<mirror::Class> EnsureInitialized(Thread* self, ObjPtr<mirror::Class> klass)
    123     REQUIRES_SHARED(Locks::mutator_lock_) {
    124   if (LIKELY(klass->IsInitialized())) {
    125     return klass;
    126   }
    127   StackHandleScope<1> hs(self);
    128   Handle<mirror::Class> h_klass(hs.NewHandle(klass));
    129   if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
    130     return nullptr;
    131   }
    132   return h_klass.Get();
    133 }
    134 
    135 static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
    136                               const char* name, const char* sig, bool is_static)
    137     REQUIRES_SHARED(Locks::mutator_lock_) {
    138   ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class));
    139   if (c == nullptr) {
    140     return nullptr;
    141   }
    142   ArtMethod* method = nullptr;
    143   auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
    144   if (is_static) {
    145     method = c->FindDirectMethod(name, sig, pointer_size);
    146   } else if (c->IsInterface()) {
    147     method = c->FindInterfaceMethod(name, sig, pointer_size);
    148   } else {
    149     method = c->FindVirtualMethod(name, sig, pointer_size);
    150     if (method == nullptr) {
    151       // No virtual method matching the signature.  Search declared
    152       // private methods and constructors.
    153       method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
    154     }
    155   }
    156   if (method == nullptr || method->IsStatic() != is_static) {
    157     ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
    158     return nullptr;
    159   }
    160   return jni::EncodeArtMethod(method);
    161 }
    162 
    163 static ObjPtr<mirror::ClassLoader> GetClassLoader(const ScopedObjectAccess& soa)
    164     REQUIRES_SHARED(Locks::mutator_lock_) {
    165   ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
    166   // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
    167   if (method == jni::DecodeArtMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
    168     return soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
    169   }
    170   // If we have a method, use its ClassLoader for context.
    171   if (method != nullptr) {
    172     return method->GetDeclaringClass()->GetClassLoader();
    173   }
    174   // We don't have a method, so try to use the system ClassLoader.
    175   ObjPtr<mirror::ClassLoader> class_loader =
    176       soa.Decode<mirror::ClassLoader>(Runtime::Current()->GetSystemClassLoader());
    177   if (class_loader != nullptr) {
    178     return class_loader;
    179   }
    180   // See if the override ClassLoader is set for gtests.
    181   class_loader = soa.Decode<mirror::ClassLoader>(soa.Self()->GetClassLoaderOverride());
    182   if (class_loader != nullptr) {
    183     // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
    184     // image.
    185     CHECK(Runtime::Current()->IsAotCompiler());
    186     CHECK(!Runtime::Current()->IsCompilingBootImage());
    187     return class_loader;
    188   }
    189   // Use the BOOTCLASSPATH.
    190   return nullptr;
    191 }
    192 
    193 static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
    194                             const char* sig, bool is_static)
    195     REQUIRES_SHARED(Locks::mutator_lock_) {
    196   StackHandleScope<2> hs(soa.Self());
    197   Handle<mirror::Class> c(
    198       hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(jni_class))));
    199   if (c == nullptr) {
    200     return nullptr;
    201   }
    202   ArtField* field = nullptr;
    203   mirror::Class* field_type;
    204   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    205   if (sig[1] != '\0') {
    206     Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
    207     field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
    208   } else {
    209     field_type = class_linker->FindPrimitiveClass(*sig);
    210   }
    211   if (field_type == nullptr) {
    212     // Failed to find type from the signature of the field.
    213     DCHECK(soa.Self()->IsExceptionPending());
    214     StackHandleScope<1> hs2(soa.Self());
    215     Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
    216     soa.Self()->ClearException();
    217     std::string temp;
    218     soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
    219                                    "no type \"%s\" found and so no field \"%s\" "
    220                                    "could be found in class \"%s\" or its superclasses", sig, name,
    221                                    c->GetDescriptor(&temp));
    222     soa.Self()->GetException()->SetCause(cause.Get());
    223     return nullptr;
    224   }
    225   std::string temp;
    226   if (is_static) {
    227     field = mirror::Class::FindStaticField(
    228         soa.Self(), c.Get(), name, field_type->GetDescriptor(&temp));
    229   } else {
    230     field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
    231   }
    232   if (field == nullptr) {
    233     soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
    234                                    "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
    235                                    sig, name, c->GetDescriptor(&temp));
    236     return nullptr;
    237   }
    238   return jni::EncodeArtField(field);
    239 }
    240 
    241 static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
    242                         jsize length, const char* identifier)
    243     REQUIRES_SHARED(Locks::mutator_lock_) {
    244   std::string type(array->PrettyTypeOf());
    245   soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
    246                                  "%s offset=%d length=%d %s.length=%d",
    247                                  type.c_str(), start, length, identifier, array->GetLength());
    248 }
    249 
    250 static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
    251                         jsize array_length)
    252     REQUIRES_SHARED(Locks::mutator_lock_) {
    253   soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
    254                                  "offset=%d length=%d string.length()=%d", start, length,
    255                                  array_length);
    256 }
    257 
    258 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
    259     REQUIRES(!Locks::mutator_lock_) {
    260   // Turn the const char* into a java.lang.String.
    261   ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
    262   if (msg != nullptr && s.get() == nullptr) {
    263     return JNI_ERR;
    264   }
    265 
    266   // Choose an appropriate constructor and set up the arguments.
    267   jvalue args[2];
    268   const char* signature;
    269   if (msg == nullptr && cause == nullptr) {
    270     signature = "()V";
    271   } else if (msg != nullptr && cause == nullptr) {
    272     signature = "(Ljava/lang/String;)V";
    273     args[0].l = s.get();
    274   } else if (msg == nullptr && cause != nullptr) {
    275     signature = "(Ljava/lang/Throwable;)V";
    276     args[0].l = cause;
    277   } else {
    278     signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
    279     args[0].l = s.get();
    280     args[1].l = cause;
    281   }
    282   jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
    283   if (mid == nullptr) {
    284     ScopedObjectAccess soa(env);
    285     LOG(ERROR) << "No <init>" << signature << " in "
    286         << mirror::Class::PrettyClass(soa.Decode<mirror::Class>(exception_class));
    287     return JNI_ERR;
    288   }
    289 
    290   ScopedLocalRef<jthrowable> exception(
    291       env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
    292   if (exception.get() == nullptr) {
    293     return JNI_ERR;
    294   }
    295   ScopedObjectAccess soa(env);
    296   soa.Self()->SetException(soa.Decode<mirror::Throwable>(exception.get()));
    297   return JNI_OK;
    298 }
    299 
    300 static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
    301   return reinterpret_cast<JNIEnvExt*>(env)->vm;
    302 }
    303 
    304 #define CHECK_NON_NULL_ARGUMENT(value) \
    305     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
    306 
    307 #define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
    308     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
    309 
    310 #define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
    311     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
    312 
    313 #define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
    314     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
    315 
    316 #define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
    317   if (UNLIKELY((value) == nullptr)) { \
    318     JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
    319     return return_val; \
    320   }
    321 
    322 #define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
    323   if (UNLIKELY((length) != 0 && (value) == nullptr)) { \
    324     JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
    325     return; \
    326   }
    327 
    328 template <bool kNative>
    329 static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
    330     REQUIRES_SHARED(Locks::mutator_lock_) {
    331   auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
    332   for (auto& method : c->GetMethods(pointer_size)) {
    333     if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
    334       return &method;
    335     }
    336   }
    337   return nullptr;
    338 }
    339 
    340 class JNI {
    341  public:
    342   static jint GetVersion(JNIEnv*) {
    343     return JNI_VERSION_1_6;
    344   }
    345 
    346   static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
    347     LOG(WARNING) << "JNI DefineClass is not supported";
    348     return nullptr;
    349   }
    350 
    351   static jclass FindClass(JNIEnv* env, const char* name) {
    352     CHECK_NON_NULL_ARGUMENT(name);
    353     Runtime* runtime = Runtime::Current();
    354     ClassLinker* class_linker = runtime->GetClassLinker();
    355     std::string descriptor(NormalizeJniClassDescriptor(name));
    356     ScopedObjectAccess soa(env);
    357     mirror::Class* c = nullptr;
    358     if (runtime->IsStarted()) {
    359       StackHandleScope<1> hs(soa.Self());
    360       Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
    361       c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
    362     } else {
    363       c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
    364     }
    365     return soa.AddLocalReference<jclass>(c);
    366   }
    367 
    368   static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
    369     CHECK_NON_NULL_ARGUMENT(jlr_method);
    370     ScopedObjectAccess soa(env);
    371     return jni::EncodeArtMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
    372   }
    373 
    374   static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
    375     CHECK_NON_NULL_ARGUMENT(jlr_field);
    376     ScopedObjectAccess soa(env);
    377     ObjPtr<mirror::Object> obj_field = soa.Decode<mirror::Object>(jlr_field);
    378     if (obj_field->GetClass() != mirror::Field::StaticClass()) {
    379       // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
    380       return nullptr;
    381     }
    382     ObjPtr<mirror::Field> field = ObjPtr<mirror::Field>::DownCast(obj_field);
    383     return jni::EncodeArtField(field->GetArtField());
    384   }
    385 
    386   static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
    387     CHECK_NON_NULL_ARGUMENT(mid);
    388     ScopedObjectAccess soa(env);
    389     ArtMethod* m = jni::DecodeArtMethod(mid);
    390     mirror::Executable* method;
    391     DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
    392     DCHECK(!Runtime::Current()->IsActiveTransaction());
    393     if (m->IsConstructor()) {
    394       method = mirror::Constructor::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
    395     } else {
    396       method = mirror::Method::CreateFromArtMethod<kRuntimePointerSize, false>(soa.Self(), m);
    397     }
    398     return soa.AddLocalReference<jobject>(method);
    399   }
    400 
    401   static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
    402     CHECK_NON_NULL_ARGUMENT(fid);
    403     ScopedObjectAccess soa(env);
    404     ArtField* f = jni::DecodeArtField(fid);
    405     return soa.AddLocalReference<jobject>(
    406         mirror::Field::CreateFromArtField<kRuntimePointerSize>(soa.Self(), f, true));
    407   }
    408 
    409   static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
    410     CHECK_NON_NULL_ARGUMENT(java_object);
    411     ScopedObjectAccess soa(env);
    412     ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
    413     return soa.AddLocalReference<jclass>(o->GetClass());
    414   }
    415 
    416   static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
    417     CHECK_NON_NULL_ARGUMENT(java_class);
    418     ScopedObjectAccess soa(env);
    419     ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
    420     return soa.AddLocalReference<jclass>(c->IsInterface() ? nullptr : c->GetSuperClass());
    421   }
    422 
    423   // Note: java_class1 should be safely castable to java_class2, and
    424   // not the other way around.
    425   static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
    426     CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
    427     CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
    428     ScopedObjectAccess soa(env);
    429     ObjPtr<mirror::Class> c1 = soa.Decode<mirror::Class>(java_class1);
    430     ObjPtr<mirror::Class> c2 = soa.Decode<mirror::Class>(java_class2);
    431     return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
    432   }
    433 
    434   static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
    435     CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
    436     if (jobj == nullptr) {
    437       // Note: JNI is different from regular Java instanceof in this respect
    438       return JNI_TRUE;
    439     } else {
    440       ScopedObjectAccess soa(env);
    441       ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(jobj);
    442       ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
    443       return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
    444     }
    445   }
    446 
    447   static jint Throw(JNIEnv* env, jthrowable java_exception) {
    448     ScopedObjectAccess soa(env);
    449     ObjPtr<mirror::Throwable> exception = soa.Decode<mirror::Throwable>(java_exception);
    450     if (exception == nullptr) {
    451       return JNI_ERR;
    452     }
    453     soa.Self()->SetException(exception);
    454     return JNI_OK;
    455   }
    456 
    457   static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
    458     CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
    459     return ThrowNewException(env, c, msg, nullptr);
    460   }
    461 
    462   static jboolean ExceptionCheck(JNIEnv* env) {
    463     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
    464   }
    465 
    466   static void ExceptionClear(JNIEnv* env) {
    467     ScopedObjectAccess soa(env);
    468     soa.Self()->ClearException();
    469   }
    470 
    471   static void ExceptionDescribe(JNIEnv* env) {
    472     ScopedObjectAccess soa(env);
    473 
    474     // If we have no exception to describe, pass through.
    475     if (!soa.Self()->GetException()) {
    476       return;
    477     }
    478 
    479     StackHandleScope<1> hs(soa.Self());
    480     Handle<mirror::Throwable> old_exception(
    481         hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
    482     soa.Self()->ClearException();
    483     ScopedLocalRef<jthrowable> exception(env,
    484                                          soa.AddLocalReference<jthrowable>(old_exception.Get()));
    485     ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
    486     jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
    487     if (mid == nullptr) {
    488       LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
    489                    << mirror::Object::PrettyTypeOf(old_exception.Get());
    490     } else {
    491       env->CallVoidMethod(exception.get(), mid);
    492       if (soa.Self()->IsExceptionPending()) {
    493         LOG(WARNING) << "JNI WARNING: " << mirror::Object::PrettyTypeOf(soa.Self()->GetException())
    494                      << " thrown while calling printStackTrace";
    495         soa.Self()->ClearException();
    496       }
    497     }
    498     soa.Self()->SetException(old_exception.Get());
    499   }
    500 
    501   static jthrowable ExceptionOccurred(JNIEnv* env) {
    502     ScopedObjectAccess soa(env);
    503     mirror::Object* exception = soa.Self()->GetException();
    504     return soa.AddLocalReference<jthrowable>(exception);
    505   }
    506 
    507   static void FatalError(JNIEnv*, const char* msg) {
    508     LOG(FATAL) << "JNI FatalError called: " << msg;
    509   }
    510 
    511   static jint PushLocalFrame(JNIEnv* env, jint capacity) {
    512     // TODO: SOA may not be necessary but I do it to please lock annotations.
    513     ScopedObjectAccess soa(env);
    514     if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
    515       return JNI_ERR;
    516     }
    517     down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
    518     return JNI_OK;
    519   }
    520 
    521   static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
    522     ScopedObjectAccess soa(env);
    523     ObjPtr<mirror::Object> survivor = soa.Decode<mirror::Object>(java_survivor);
    524     soa.Env()->PopFrame();
    525     return soa.AddLocalReference<jobject>(survivor);
    526   }
    527 
    528   static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
    529     // TODO: SOA may not be necessary but I do it to please lock annotations.
    530     ScopedObjectAccess soa(env);
    531     return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
    532   }
    533 
    534   static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
    535     ScopedObjectAccess soa(env);
    536     ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
    537     return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
    538   }
    539 
    540   static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
    541     JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
    542     Thread* self = down_cast<JNIEnvExt*>(env)->self;
    543     vm->DeleteGlobalRef(self, obj);
    544   }
    545 
    546   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
    547     ScopedObjectAccess soa(env);
    548     ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
    549     return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
    550   }
    551 
    552   static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
    553     JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
    554     Thread* self = down_cast<JNIEnvExt*>(env)->self;
    555     vm->DeleteWeakGlobalRef(self, obj);
    556   }
    557 
    558   static jobject NewLocalRef(JNIEnv* env, jobject obj) {
    559     ScopedObjectAccess soa(env);
    560     ObjPtr<mirror::Object> decoded_obj = soa.Decode<mirror::Object>(obj);
    561     // Check for null after decoding the object to handle cleared weak globals.
    562     if (decoded_obj == nullptr) {
    563       return nullptr;
    564     }
    565     return soa.AddLocalReference<jobject>(decoded_obj);
    566   }
    567 
    568   static void DeleteLocalRef(JNIEnv* env, jobject obj) {
    569     if (obj == nullptr) {
    570       return;
    571     }
    572     // SOA is only necessary to have exclusion between GC root marking and removing.
    573     // We don't want to have the GC attempt to mark a null root if we just removed
    574     // it. b/22119403
    575     ScopedObjectAccess soa(env);
    576     auto* ext_env = down_cast<JNIEnvExt*>(env);
    577     if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
    578       // Attempting to delete a local reference that is not in the
    579       // topmost local reference frame is a no-op.  DeleteLocalRef returns
    580       // void and doesn't throw any exceptions, but we should probably
    581       // complain about it so the user will notice that things aren't
    582       // going quite the way they expect.
    583       LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
    584                    << "failed to find entry";
    585     }
    586   }
    587 
    588   static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
    589     if (obj1 == obj2) {
    590       return JNI_TRUE;
    591     } else {
    592       ScopedObjectAccess soa(env);
    593       return (soa.Decode<mirror::Object>(obj1) == soa.Decode<mirror::Object>(obj2))
    594               ? JNI_TRUE : JNI_FALSE;
    595     }
    596   }
    597 
    598   static jobject AllocObject(JNIEnv* env, jclass java_class) {
    599     CHECK_NON_NULL_ARGUMENT(java_class);
    600     ScopedObjectAccess soa(env);
    601     ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class>(java_class));
    602     if (c == nullptr) {
    603       return nullptr;
    604     }
    605     if (c->IsStringClass()) {
    606       gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
    607       return soa.AddLocalReference<jobject>(mirror::String::AllocEmptyString<true>(soa.Self(),
    608                                                                               allocator_type));
    609     }
    610     return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
    611   }
    612 
    613   static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
    614     va_list args;
    615     va_start(args, mid);
    616     CHECK_NON_NULL_ARGUMENT(java_class);
    617     CHECK_NON_NULL_ARGUMENT(mid);
    618     jobject result = NewObjectV(env, java_class, mid, args);
    619     va_end(args);
    620     return result;
    621   }
    622 
    623   static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
    624     CHECK_NON_NULL_ARGUMENT(java_class);
    625     CHECK_NON_NULL_ARGUMENT(mid);
    626     ScopedObjectAccess soa(env);
    627     ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
    628                                                 soa.Decode<mirror::Class>(java_class));
    629     if (c == nullptr) {
    630       return nullptr;
    631     }
    632     if (c->IsStringClass()) {
    633       // Replace calls to String.<init> with equivalent StringFactory call.
    634       jmethodID sf_mid = jni::EncodeArtMethod(
    635           WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
    636       return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
    637     }
    638     ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
    639     if (result == nullptr) {
    640       return nullptr;
    641     }
    642     jobject local_result = soa.AddLocalReference<jobject>(result);
    643     CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
    644     if (soa.Self()->IsExceptionPending()) {
    645       return nullptr;
    646     }
    647     return local_result;
    648   }
    649 
    650   static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
    651     CHECK_NON_NULL_ARGUMENT(java_class);
    652     CHECK_NON_NULL_ARGUMENT(mid);
    653     ScopedObjectAccess soa(env);
    654     ObjPtr<mirror::Class> c = EnsureInitialized(soa.Self(),
    655                                                 soa.Decode<mirror::Class>(java_class));
    656     if (c == nullptr) {
    657       return nullptr;
    658     }
    659     if (c->IsStringClass()) {
    660       // Replace calls to String.<init> with equivalent StringFactory call.
    661       jmethodID sf_mid = jni::EncodeArtMethod(
    662           WellKnownClasses::StringInitToStringFactory(jni::DecodeArtMethod(mid)));
    663       return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
    664     }
    665     ObjPtr<mirror::Object> result = c->AllocObject(soa.Self());
    666     if (result == nullptr) {
    667       return nullptr;
    668     }
    669     jobject local_result = soa.AddLocalReference<jobjectArray>(result);
    670     CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
    671     if (soa.Self()->IsExceptionPending()) {
    672       return nullptr;
    673     }
    674     return local_result;
    675   }
    676 
    677   static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
    678     CHECK_NON_NULL_ARGUMENT(java_class);
    679     CHECK_NON_NULL_ARGUMENT(name);
    680     CHECK_NON_NULL_ARGUMENT(sig);
    681     ScopedObjectAccess soa(env);
    682     return FindMethodID(soa, java_class, name, sig, false);
    683   }
    684 
    685   static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
    686                                      const char* sig) {
    687     CHECK_NON_NULL_ARGUMENT(java_class);
    688     CHECK_NON_NULL_ARGUMENT(name);
    689     CHECK_NON_NULL_ARGUMENT(sig);
    690     ScopedObjectAccess soa(env);
    691     return FindMethodID(soa, java_class, name, sig, true);
    692   }
    693 
    694   static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    695     va_list ap;
    696     va_start(ap, mid);
    697     CHECK_NON_NULL_ARGUMENT(obj);
    698     CHECK_NON_NULL_ARGUMENT(mid);
    699     ScopedObjectAccess soa(env);
    700     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    701     va_end(ap);
    702     return soa.AddLocalReference<jobject>(result.GetL());
    703   }
    704 
    705   static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    706     CHECK_NON_NULL_ARGUMENT(obj);
    707     CHECK_NON_NULL_ARGUMENT(mid);
    708     ScopedObjectAccess soa(env);
    709     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
    710     return soa.AddLocalReference<jobject>(result.GetL());
    711   }
    712 
    713   static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    714     CHECK_NON_NULL_ARGUMENT(obj);
    715     CHECK_NON_NULL_ARGUMENT(mid);
    716     ScopedObjectAccess soa(env);
    717     JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
    718     return soa.AddLocalReference<jobject>(result.GetL());
    719   }
    720 
    721   static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    722     va_list ap;
    723     va_start(ap, mid);
    724     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    725     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    726     ScopedObjectAccess soa(env);
    727     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    728     va_end(ap);
    729     return result.GetZ();
    730   }
    731 
    732   static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    733     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    734     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    735     ScopedObjectAccess soa(env);
    736     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
    737   }
    738 
    739   static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    740     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    741     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    742     ScopedObjectAccess soa(env);
    743     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
    744   }
    745 
    746   static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    747     va_list ap;
    748     va_start(ap, mid);
    749     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    750     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    751     ScopedObjectAccess soa(env);
    752     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    753     va_end(ap);
    754     return result.GetB();
    755   }
    756 
    757   static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    758     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    759     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    760     ScopedObjectAccess soa(env);
    761     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
    762   }
    763 
    764   static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    765     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    766     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    767     ScopedObjectAccess soa(env);
    768     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
    769   }
    770 
    771   static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    772     va_list ap;
    773     va_start(ap, mid);
    774     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    775     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    776     ScopedObjectAccess soa(env);
    777     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    778     va_end(ap);
    779     return result.GetC();
    780   }
    781 
    782   static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    783     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    784     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    785     ScopedObjectAccess soa(env);
    786     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
    787   }
    788 
    789   static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    790     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    791     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    792     ScopedObjectAccess soa(env);
    793     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
    794   }
    795 
    796   static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    797     va_list ap;
    798     va_start(ap, mid);
    799     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    800     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    801     ScopedObjectAccess soa(env);
    802     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    803     va_end(ap);
    804     return result.GetD();
    805   }
    806 
    807   static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    808     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    809     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    810     ScopedObjectAccess soa(env);
    811     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
    812   }
    813 
    814   static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    815     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    816     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    817     ScopedObjectAccess soa(env);
    818     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
    819   }
    820 
    821   static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    822     va_list ap;
    823     va_start(ap, mid);
    824     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    825     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    826     ScopedObjectAccess soa(env);
    827     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    828     va_end(ap);
    829     return result.GetF();
    830   }
    831 
    832   static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    833     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    834     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    835     ScopedObjectAccess soa(env);
    836     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
    837   }
    838 
    839   static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    840     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    841     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    842     ScopedObjectAccess soa(env);
    843     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
    844   }
    845 
    846   static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    847     va_list ap;
    848     va_start(ap, mid);
    849     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    850     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    851     ScopedObjectAccess soa(env);
    852     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    853     va_end(ap);
    854     return result.GetI();
    855   }
    856 
    857   static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    858     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    859     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    860     ScopedObjectAccess soa(env);
    861     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
    862   }
    863 
    864   static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    865     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    866     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    867     ScopedObjectAccess soa(env);
    868     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
    869   }
    870 
    871   static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    872     va_list ap;
    873     va_start(ap, mid);
    874     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    875     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    876     ScopedObjectAccess soa(env);
    877     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    878     va_end(ap);
    879     return result.GetJ();
    880   }
    881 
    882   static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    883     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    884     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    885     ScopedObjectAccess soa(env);
    886     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
    887   }
    888 
    889   static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    890     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    891     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    892     ScopedObjectAccess soa(env);
    893     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
    894   }
    895 
    896   static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    897     va_list ap;
    898     va_start(ap, mid);
    899     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    900     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    901     ScopedObjectAccess soa(env);
    902     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    903     va_end(ap);
    904     return result.GetS();
    905   }
    906 
    907   static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    908     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    909     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    910     ScopedObjectAccess soa(env);
    911     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
    912   }
    913 
    914   static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    915     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    916     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    917     ScopedObjectAccess soa(env);
    918     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
    919   }
    920 
    921   static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    922     va_list ap;
    923     va_start(ap, mid);
    924     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
    925     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
    926     ScopedObjectAccess soa(env);
    927     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
    928     va_end(ap);
    929   }
    930 
    931   static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    932     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
    933     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
    934     ScopedObjectAccess soa(env);
    935     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
    936   }
    937 
    938   static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
    939     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
    940     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
    941     ScopedObjectAccess soa(env);
    942     InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
    943   }
    944 
    945   static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
    946     va_list ap;
    947     va_start(ap, mid);
    948     CHECK_NON_NULL_ARGUMENT(obj);
    949     CHECK_NON_NULL_ARGUMENT(mid);
    950     ScopedObjectAccess soa(env);
    951     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    952     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
    953     va_end(ap);
    954     return local_result;
    955   }
    956 
    957   static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
    958                                              va_list args) {
    959     CHECK_NON_NULL_ARGUMENT(obj);
    960     CHECK_NON_NULL_ARGUMENT(mid);
    961     ScopedObjectAccess soa(env);
    962     JValue result(InvokeWithVarArgs(soa, obj, mid, args));
    963     return soa.AddLocalReference<jobject>(result.GetL());
    964   }
    965 
    966   static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
    967                                              jvalue* args) {
    968     CHECK_NON_NULL_ARGUMENT(obj);
    969     CHECK_NON_NULL_ARGUMENT(mid);
    970     ScopedObjectAccess soa(env);
    971     JValue result(InvokeWithJValues(soa, obj, mid, args));
    972     return soa.AddLocalReference<jobject>(result.GetL());
    973   }
    974 
    975   static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
    976                                               ...) {
    977     va_list ap;
    978     va_start(ap, mid);
    979     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    980     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    981     ScopedObjectAccess soa(env);
    982     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
    983     va_end(ap);
    984     return result.GetZ();
    985   }
    986 
    987   static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
    988                                                va_list args) {
    989     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    990     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    991     ScopedObjectAccess soa(env);
    992     return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
    993   }
    994 
    995   static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
    996                                                jvalue* args) {
    997     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
    998     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
    999     ScopedObjectAccess soa(env);
   1000     return InvokeWithJValues(soa, obj, mid, args).GetZ();
   1001   }
   1002 
   1003   static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1004     va_list ap;
   1005     va_start(ap, mid);
   1006     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1007     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1008     ScopedObjectAccess soa(env);
   1009     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1010     va_end(ap);
   1011     return result.GetB();
   1012   }
   1013 
   1014   static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1015                                          va_list args) {
   1016     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1017     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1018     ScopedObjectAccess soa(env);
   1019     return InvokeWithVarArgs(soa, obj, mid, args).GetB();
   1020   }
   1021 
   1022   static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1023                                          jvalue* args) {
   1024     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1025     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1026     ScopedObjectAccess soa(env);
   1027     return InvokeWithJValues(soa, obj, mid, args).GetB();
   1028   }
   1029 
   1030   static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1031     va_list ap;
   1032     va_start(ap, mid);
   1033     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1034     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1035     ScopedObjectAccess soa(env);
   1036     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1037     va_end(ap);
   1038     return result.GetC();
   1039   }
   1040 
   1041   static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1042                                          va_list args) {
   1043     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1044     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1045     ScopedObjectAccess soa(env);
   1046     return InvokeWithVarArgs(soa, obj, mid, args).GetC();
   1047   }
   1048 
   1049   static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1050                                          jvalue* args) {
   1051     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1052     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1053     ScopedObjectAccess soa(env);
   1054     return InvokeWithJValues(soa, obj, mid, args).GetC();
   1055   }
   1056 
   1057   static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1058     va_list ap;
   1059     va_start(ap, mid);
   1060     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1061     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1062     ScopedObjectAccess soa(env);
   1063     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1064     va_end(ap);
   1065     return result.GetS();
   1066   }
   1067 
   1068   static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1069                                            va_list args) {
   1070     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1071     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1072     ScopedObjectAccess soa(env);
   1073     return InvokeWithVarArgs(soa, obj, mid, args).GetS();
   1074   }
   1075 
   1076   static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1077                                            jvalue* args) {
   1078     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1079     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1080     ScopedObjectAccess soa(env);
   1081     return InvokeWithJValues(soa, obj, mid, args).GetS();
   1082   }
   1083 
   1084   static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1085     va_list ap;
   1086     va_start(ap, mid);
   1087     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1088     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1089     ScopedObjectAccess soa(env);
   1090     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1091     va_end(ap);
   1092     return result.GetI();
   1093   }
   1094 
   1095   static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1096                                        va_list args) {
   1097     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1098     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1099     ScopedObjectAccess soa(env);
   1100     return InvokeWithVarArgs(soa, obj, mid, args).GetI();
   1101   }
   1102 
   1103   static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1104                                        jvalue* args) {
   1105     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1106     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1107     ScopedObjectAccess soa(env);
   1108     return InvokeWithJValues(soa, obj, mid, args).GetI();
   1109   }
   1110 
   1111   static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1112     va_list ap;
   1113     va_start(ap, mid);
   1114     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1115     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1116     ScopedObjectAccess soa(env);
   1117     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1118     va_end(ap);
   1119     return result.GetJ();
   1120   }
   1121 
   1122   static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1123                                          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 InvokeWithVarArgs(soa, obj, mid, args).GetJ();
   1128   }
   1129 
   1130   static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1131                                          jvalue* args) {
   1132     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1133     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1134     ScopedObjectAccess soa(env);
   1135     return InvokeWithJValues(soa, obj, mid, args).GetJ();
   1136   }
   1137 
   1138   static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, 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(InvokeWithVarArgs(soa, obj, mid, ap));
   1145     va_end(ap);
   1146     return result.GetF();
   1147   }
   1148 
   1149   static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1150                                            va_list args) {
   1151     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1152     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1153     ScopedObjectAccess soa(env);
   1154     return InvokeWithVarArgs(soa, obj, mid, args).GetF();
   1155   }
   1156 
   1157   static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1158                                            jvalue* args) {
   1159     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1160     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1161     ScopedObjectAccess soa(env);
   1162     return InvokeWithJValues(soa, obj, mid, args).GetF();
   1163   }
   1164 
   1165   static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1166     va_list ap;
   1167     va_start(ap, mid);
   1168     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1169     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1170     ScopedObjectAccess soa(env);
   1171     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1172     va_end(ap);
   1173     return result.GetD();
   1174   }
   1175 
   1176   static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1177                                              va_list args) {
   1178     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1179     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1180     ScopedObjectAccess soa(env);
   1181     return InvokeWithVarArgs(soa, obj, mid, args).GetD();
   1182   }
   1183 
   1184   static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1185                                              jvalue* args) {
   1186     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
   1187     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1188     ScopedObjectAccess soa(env);
   1189     return InvokeWithJValues(soa, obj, mid, args).GetD();
   1190   }
   1191 
   1192   static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1193     va_list ap;
   1194     va_start(ap, mid);
   1195     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
   1196     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
   1197     ScopedObjectAccess soa(env);
   1198     InvokeWithVarArgs(soa, obj, mid, ap);
   1199     va_end(ap);
   1200   }
   1201 
   1202   static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1203                                         va_list args) {
   1204     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
   1205     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
   1206     ScopedObjectAccess soa(env);
   1207     InvokeWithVarArgs(soa, obj, mid, args);
   1208   }
   1209 
   1210   static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1211                                         jvalue* args) {
   1212     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
   1213     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
   1214     ScopedObjectAccess soa(env);
   1215     InvokeWithJValues(soa, obj, mid, args);
   1216   }
   1217 
   1218   static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
   1219     CHECK_NON_NULL_ARGUMENT(java_class);
   1220     CHECK_NON_NULL_ARGUMENT(name);
   1221     CHECK_NON_NULL_ARGUMENT(sig);
   1222     ScopedObjectAccess soa(env);
   1223     return FindFieldID(soa, java_class, name, sig, false);
   1224   }
   1225 
   1226   static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
   1227                                    const char* sig) {
   1228     CHECK_NON_NULL_ARGUMENT(java_class);
   1229     CHECK_NON_NULL_ARGUMENT(name);
   1230     CHECK_NON_NULL_ARGUMENT(sig);
   1231     ScopedObjectAccess soa(env);
   1232     return FindFieldID(soa, java_class, name, sig, true);
   1233   }
   1234 
   1235   static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
   1236     CHECK_NON_NULL_ARGUMENT(obj);
   1237     CHECK_NON_NULL_ARGUMENT(fid);
   1238     ScopedObjectAccess soa(env);
   1239     ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(obj);
   1240     ArtField* f = jni::DecodeArtField(fid);
   1241     return soa.AddLocalReference<jobject>(f->GetObject(o));
   1242   }
   1243 
   1244   static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
   1245     CHECK_NON_NULL_ARGUMENT(fid);
   1246     ScopedObjectAccess soa(env);
   1247     ArtField* f = jni::DecodeArtField(fid);
   1248     return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
   1249   }
   1250 
   1251   static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
   1252     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
   1253     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
   1254     ScopedObjectAccess soa(env);
   1255     ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
   1256     ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
   1257     ArtField* f = jni::DecodeArtField(fid);
   1258     f->SetObject<false>(o, v);
   1259   }
   1260 
   1261   static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
   1262     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
   1263     ScopedObjectAccess soa(env);
   1264     ObjPtr<mirror::Object> v = soa.Decode<mirror::Object>(java_value);
   1265     ArtField* f = jni::DecodeArtField(fid);
   1266     f->SetObject<false>(f->GetDeclaringClass(), v);
   1267   }
   1268 
   1269 #define GET_PRIMITIVE_FIELD(fn, instance) \
   1270   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
   1271   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
   1272   ScopedObjectAccess soa(env); \
   1273   ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
   1274   ArtField* f = jni::DecodeArtField(fid); \
   1275   return f->Get ##fn (o)
   1276 
   1277 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
   1278   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
   1279   ScopedObjectAccess soa(env); \
   1280   ArtField* f = jni::DecodeArtField(fid); \
   1281   return f->Get ##fn (f->GetDeclaringClass())
   1282 
   1283 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
   1284   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
   1285   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
   1286   ScopedObjectAccess soa(env); \
   1287   ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(instance); \
   1288   ArtField* f = jni::DecodeArtField(fid); \
   1289   f->Set ##fn <false>(o, value)
   1290 
   1291 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
   1292   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
   1293   ScopedObjectAccess soa(env); \
   1294   ArtField* f = jni::DecodeArtField(fid); \
   1295   f->Set ##fn <false>(f->GetDeclaringClass(), value)
   1296 
   1297   static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
   1298     GET_PRIMITIVE_FIELD(Boolean, obj);
   1299   }
   1300 
   1301   static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
   1302     GET_PRIMITIVE_FIELD(Byte, obj);
   1303   }
   1304 
   1305   static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
   1306     GET_PRIMITIVE_FIELD(Char, obj);
   1307   }
   1308 
   1309   static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
   1310     GET_PRIMITIVE_FIELD(Short, obj);
   1311   }
   1312 
   1313   static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
   1314     GET_PRIMITIVE_FIELD(Int, obj);
   1315   }
   1316 
   1317   static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
   1318     GET_PRIMITIVE_FIELD(Long, obj);
   1319   }
   1320 
   1321   static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
   1322     GET_PRIMITIVE_FIELD(Float, obj);
   1323   }
   1324 
   1325   static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
   1326     GET_PRIMITIVE_FIELD(Double, obj);
   1327   }
   1328 
   1329   static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
   1330     GET_STATIC_PRIMITIVE_FIELD(Boolean);
   1331   }
   1332 
   1333   static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
   1334     GET_STATIC_PRIMITIVE_FIELD(Byte);
   1335   }
   1336 
   1337   static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
   1338     GET_STATIC_PRIMITIVE_FIELD(Char);
   1339   }
   1340 
   1341   static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
   1342     GET_STATIC_PRIMITIVE_FIELD(Short);
   1343   }
   1344 
   1345   static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
   1346     GET_STATIC_PRIMITIVE_FIELD(Int);
   1347   }
   1348 
   1349   static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
   1350     GET_STATIC_PRIMITIVE_FIELD(Long);
   1351   }
   1352 
   1353   static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
   1354     GET_STATIC_PRIMITIVE_FIELD(Float);
   1355   }
   1356 
   1357   static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
   1358     GET_STATIC_PRIMITIVE_FIELD(Double);
   1359   }
   1360 
   1361   static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
   1362     SET_PRIMITIVE_FIELD(Boolean, obj, v);
   1363   }
   1364 
   1365   static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
   1366     SET_PRIMITIVE_FIELD(Byte, obj, v);
   1367   }
   1368 
   1369   static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
   1370     SET_PRIMITIVE_FIELD(Char, obj, v);
   1371   }
   1372 
   1373   static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
   1374     SET_PRIMITIVE_FIELD(Float, obj, v);
   1375   }
   1376 
   1377   static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
   1378     SET_PRIMITIVE_FIELD(Double, obj, v);
   1379   }
   1380 
   1381   static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
   1382     SET_PRIMITIVE_FIELD(Int, obj, v);
   1383   }
   1384 
   1385   static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
   1386     SET_PRIMITIVE_FIELD(Long, obj, v);
   1387   }
   1388 
   1389   static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
   1390     SET_PRIMITIVE_FIELD(Short, obj, v);
   1391   }
   1392 
   1393   static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
   1394     SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
   1395   }
   1396 
   1397   static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
   1398     SET_STATIC_PRIMITIVE_FIELD(Byte, v);
   1399   }
   1400 
   1401   static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
   1402     SET_STATIC_PRIMITIVE_FIELD(Char, v);
   1403   }
   1404 
   1405   static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
   1406     SET_STATIC_PRIMITIVE_FIELD(Float, v);
   1407   }
   1408 
   1409   static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
   1410     SET_STATIC_PRIMITIVE_FIELD(Double, v);
   1411   }
   1412 
   1413   static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
   1414     SET_STATIC_PRIMITIVE_FIELD(Int, v);
   1415   }
   1416 
   1417   static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
   1418     SET_STATIC_PRIMITIVE_FIELD(Long, v);
   1419   }
   1420 
   1421   static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
   1422     SET_STATIC_PRIMITIVE_FIELD(Short, v);
   1423   }
   1424 
   1425   static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1426     va_list ap;
   1427     va_start(ap, mid);
   1428     CHECK_NON_NULL_ARGUMENT(mid);
   1429     ScopedObjectAccess soa(env);
   1430     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1431     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
   1432     va_end(ap);
   1433     return local_result;
   1434   }
   1435 
   1436   static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1437     CHECK_NON_NULL_ARGUMENT(mid);
   1438     ScopedObjectAccess soa(env);
   1439     JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
   1440     return soa.AddLocalReference<jobject>(result.GetL());
   1441   }
   1442 
   1443   static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1444     CHECK_NON_NULL_ARGUMENT(mid);
   1445     ScopedObjectAccess soa(env);
   1446     JValue result(InvokeWithJValues(soa, nullptr, mid, args));
   1447     return soa.AddLocalReference<jobject>(result.GetL());
   1448   }
   1449 
   1450   static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1451     va_list ap;
   1452     va_start(ap, mid);
   1453     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1454     ScopedObjectAccess soa(env);
   1455     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1456     va_end(ap);
   1457     return result.GetZ();
   1458   }
   1459 
   1460   static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1461     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1462     ScopedObjectAccess soa(env);
   1463     return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
   1464   }
   1465 
   1466   static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1467     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1468     ScopedObjectAccess soa(env);
   1469     return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
   1470   }
   1471 
   1472   static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1473     va_list ap;
   1474     va_start(ap, mid);
   1475     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1476     ScopedObjectAccess soa(env);
   1477     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1478     va_end(ap);
   1479     return result.GetB();
   1480   }
   1481 
   1482   static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1483     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1484     ScopedObjectAccess soa(env);
   1485     return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
   1486   }
   1487 
   1488   static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1489     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1490     ScopedObjectAccess soa(env);
   1491     return InvokeWithJValues(soa, nullptr, mid, args).GetB();
   1492   }
   1493 
   1494   static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1495     va_list ap;
   1496     va_start(ap, mid);
   1497     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1498     ScopedObjectAccess soa(env);
   1499     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1500     va_end(ap);
   1501     return result.GetC();
   1502   }
   1503 
   1504   static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1505     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1506     ScopedObjectAccess soa(env);
   1507     return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
   1508   }
   1509 
   1510   static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1511     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1512     ScopedObjectAccess soa(env);
   1513     return InvokeWithJValues(soa, nullptr, mid, args).GetC();
   1514   }
   1515 
   1516   static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1517     va_list ap;
   1518     va_start(ap, mid);
   1519     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1520     ScopedObjectAccess soa(env);
   1521     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1522     va_end(ap);
   1523     return result.GetS();
   1524   }
   1525 
   1526   static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1527     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1528     ScopedObjectAccess soa(env);
   1529     return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
   1530   }
   1531 
   1532   static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1533     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1534     ScopedObjectAccess soa(env);
   1535     return InvokeWithJValues(soa, nullptr, mid, args).GetS();
   1536   }
   1537 
   1538   static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1539     va_list ap;
   1540     va_start(ap, mid);
   1541     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1542     ScopedObjectAccess soa(env);
   1543     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1544     va_end(ap);
   1545     return result.GetI();
   1546   }
   1547 
   1548   static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1549     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1550     ScopedObjectAccess soa(env);
   1551     return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
   1552   }
   1553 
   1554   static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1555     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1556     ScopedObjectAccess soa(env);
   1557     return InvokeWithJValues(soa, nullptr, mid, args).GetI();
   1558   }
   1559 
   1560   static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1561     va_list ap;
   1562     va_start(ap, mid);
   1563     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1564     ScopedObjectAccess soa(env);
   1565     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1566     va_end(ap);
   1567     return result.GetJ();
   1568   }
   1569 
   1570   static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1571     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1572     ScopedObjectAccess soa(env);
   1573     return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
   1574   }
   1575 
   1576   static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1577     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1578     ScopedObjectAccess soa(env);
   1579     return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
   1580   }
   1581 
   1582   static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1583     va_list ap;
   1584     va_start(ap, mid);
   1585     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1586     ScopedObjectAccess soa(env);
   1587     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1588     va_end(ap);
   1589     return result.GetF();
   1590   }
   1591 
   1592   static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1593     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1594     ScopedObjectAccess soa(env);
   1595     return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
   1596   }
   1597 
   1598   static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1599     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1600     ScopedObjectAccess soa(env);
   1601     return InvokeWithJValues(soa, nullptr, mid, args).GetF();
   1602   }
   1603 
   1604   static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1605     va_list ap;
   1606     va_start(ap, mid);
   1607     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1608     ScopedObjectAccess soa(env);
   1609     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
   1610     va_end(ap);
   1611     return result.GetD();
   1612   }
   1613 
   1614   static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1615     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1616     ScopedObjectAccess soa(env);
   1617     return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
   1618   }
   1619 
   1620   static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1621     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
   1622     ScopedObjectAccess soa(env);
   1623     return InvokeWithJValues(soa, nullptr, mid, args).GetD();
   1624   }
   1625 
   1626   static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1627     va_list ap;
   1628     va_start(ap, mid);
   1629     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
   1630     ScopedObjectAccess soa(env);
   1631     InvokeWithVarArgs(soa, nullptr, mid, ap);
   1632     va_end(ap);
   1633   }
   1634 
   1635   static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1636     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
   1637     ScopedObjectAccess soa(env);
   1638     InvokeWithVarArgs(soa, nullptr, mid, args);
   1639   }
   1640 
   1641   static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1642     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
   1643     ScopedObjectAccess soa(env);
   1644     InvokeWithJValues(soa, nullptr, mid, args);
   1645   }
   1646 
   1647   static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
   1648     if (UNLIKELY(char_count < 0)) {
   1649       JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
   1650       return nullptr;
   1651     }
   1652     if (UNLIKELY(chars == nullptr && char_count > 0)) {
   1653       JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
   1654       return nullptr;
   1655     }
   1656     ScopedObjectAccess soa(env);
   1657     mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
   1658     return soa.AddLocalReference<jstring>(result);
   1659   }
   1660 
   1661   static jstring NewStringUTF(JNIEnv* env, const char* utf) {
   1662     if (utf == nullptr) {
   1663       return nullptr;
   1664     }
   1665     ScopedObjectAccess soa(env);
   1666     mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
   1667     return soa.AddLocalReference<jstring>(result);
   1668   }
   1669 
   1670   static jsize GetStringLength(JNIEnv* env, jstring java_string) {
   1671     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
   1672     ScopedObjectAccess soa(env);
   1673     return soa.Decode<mirror::String>(java_string)->GetLength();
   1674   }
   1675 
   1676   static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
   1677     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
   1678     ScopedObjectAccess soa(env);
   1679     return soa.Decode<mirror::String>(java_string)->GetUtfLength();
   1680   }
   1681 
   1682   static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
   1683                               jchar* buf) {
   1684     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
   1685     ScopedObjectAccess soa(env);
   1686     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1687     if (start < 0 || length < 0 || length > s->GetLength() - start) {
   1688       ThrowSIOOBE(soa, start, length, s->GetLength());
   1689     } else {
   1690       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
   1691       if (s->IsCompressed()) {
   1692         for (int i = 0; i < length; ++i) {
   1693           buf[i] = static_cast<jchar>(s->CharAt(start+i));
   1694         }
   1695       } else {
   1696         const jchar* chars = static_cast<jchar*>(s->GetValue());
   1697         memcpy(buf, chars + start, length * sizeof(jchar));
   1698       }
   1699     }
   1700   }
   1701 
   1702   static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
   1703                                  char* buf) {
   1704     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
   1705     ScopedObjectAccess soa(env);
   1706     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1707     if (start < 0 || length < 0 || length > s->GetLength() - start) {
   1708       ThrowSIOOBE(soa, start, length, s->GetLength());
   1709     } else {
   1710       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
   1711       if (s->IsCompressed()) {
   1712         for (int i = 0; i < length; ++i) {
   1713           buf[i] = s->CharAt(start+i);
   1714         }
   1715       } else {
   1716         const jchar* chars = s->GetValue();
   1717         size_t bytes = CountUtf8Bytes(chars + start, length);
   1718         ConvertUtf16ToModifiedUtf8(buf, bytes, chars + start, length);
   1719       }
   1720     }
   1721   }
   1722 
   1723   static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
   1724     CHECK_NON_NULL_ARGUMENT(java_string);
   1725     ScopedObjectAccess soa(env);
   1726     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1727     gc::Heap* heap = Runtime::Current()->GetHeap();
   1728     if (heap->IsMovableObject(s) || s->IsCompressed()) {
   1729       jchar* chars = new jchar[s->GetLength()];
   1730       if (s->IsCompressed()) {
   1731         int32_t length = s->GetLength();
   1732         for (int i = 0; i < length; ++i) {
   1733           chars[i] = s->CharAt(i);
   1734         }
   1735       } else {
   1736         memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
   1737       }
   1738       if (is_copy != nullptr) {
   1739         *is_copy = JNI_TRUE;
   1740       }
   1741       return chars;
   1742     }
   1743     if (is_copy != nullptr) {
   1744       *is_copy = JNI_FALSE;
   1745     }
   1746     return static_cast<jchar*>(s->GetValue());
   1747   }
   1748 
   1749   static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
   1750     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
   1751     ScopedObjectAccess soa(env);
   1752     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1753     if (s->IsCompressed() || (s->IsCompressed() == false && chars != s->GetValue())) {
   1754       delete[] chars;
   1755     }
   1756   }
   1757 
   1758   static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
   1759     CHECK_NON_NULL_ARGUMENT(java_string);
   1760     ScopedObjectAccess soa(env);
   1761     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1762     gc::Heap* heap = Runtime::Current()->GetHeap();
   1763     if (heap->IsMovableObject(s)) {
   1764       StackHandleScope<1> hs(soa.Self());
   1765       HandleWrapperObjPtr<mirror::String> h(hs.NewHandleWrapper(&s));
   1766       if (!kUseReadBarrier) {
   1767         heap->IncrementDisableMovingGC(soa.Self());
   1768       } else {
   1769         // For the CC collector, we only need to wait for the thread flip rather than the whole GC
   1770         // to occur thanks to the to-space invariant.
   1771         heap->IncrementDisableThreadFlip(soa.Self());
   1772       }
   1773     }
   1774     if (s->IsCompressed()) {
   1775       if (is_copy != nullptr) {
   1776         *is_copy = JNI_TRUE;
   1777       }
   1778       int32_t length = s->GetLength();
   1779       jchar* chars = new jchar[length];
   1780       for (int i = 0; i < length; ++i) {
   1781         chars[i] = s->CharAt(i);
   1782       }
   1783       return chars;
   1784     } else {
   1785       if (is_copy != nullptr) {
   1786         *is_copy = JNI_FALSE;
   1787       }
   1788       return static_cast<jchar*>(s->GetValue());
   1789     }
   1790   }
   1791 
   1792   static void ReleaseStringCritical(JNIEnv* env,
   1793                                     jstring java_string,
   1794                                     const jchar* chars) {
   1795     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
   1796     ScopedObjectAccess soa(env);
   1797     gc::Heap* heap = Runtime::Current()->GetHeap();
   1798     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1799     if (heap->IsMovableObject(s)) {
   1800       if (!kUseReadBarrier) {
   1801         heap->DecrementDisableMovingGC(soa.Self());
   1802       } else {
   1803         heap->DecrementDisableThreadFlip(soa.Self());
   1804       }
   1805     }
   1806     if (s->IsCompressed() || (s->IsCompressed() == false && s->GetValue() != chars)) {
   1807       delete[] chars;
   1808     }
   1809   }
   1810 
   1811   static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
   1812     if (java_string == nullptr) {
   1813       return nullptr;
   1814     }
   1815     if (is_copy != nullptr) {
   1816       *is_copy = JNI_TRUE;
   1817     }
   1818     ScopedObjectAccess soa(env);
   1819     ObjPtr<mirror::String> s = soa.Decode<mirror::String>(java_string);
   1820     size_t byte_count = s->GetUtfLength();
   1821     char* bytes = new char[byte_count + 1];
   1822     CHECK(bytes != nullptr);  // bionic aborts anyway.
   1823     if (s->IsCompressed()) {
   1824       for (size_t i = 0; i < byte_count; ++i) {
   1825         bytes[i] = s->CharAt(i);
   1826       }
   1827     } else {
   1828       const uint16_t* chars = s->GetValue();
   1829       ConvertUtf16ToModifiedUtf8(bytes, byte_count, chars, s->GetLength());
   1830     }
   1831     bytes[byte_count] = '\0';
   1832     return bytes;
   1833   }
   1834 
   1835   static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
   1836     delete[] chars;
   1837   }
   1838 
   1839   static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
   1840     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
   1841     ScopedObjectAccess soa(env);
   1842     ObjPtr<mirror::Object> obj = soa.Decode<mirror::Object>(java_array);
   1843     if (UNLIKELY(!obj->IsArrayInstance())) {
   1844       soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", obj->PrettyTypeOf().c_str());
   1845       return 0;
   1846     }
   1847     mirror::Array* array = obj->AsArray();
   1848     return array->GetLength();
   1849   }
   1850 
   1851   static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
   1852     CHECK_NON_NULL_ARGUMENT(java_array);
   1853     ScopedObjectAccess soa(env);
   1854     ObjPtr<mirror::ObjectArray<mirror::Object>> array =
   1855         soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
   1856     return soa.AddLocalReference<jobject>(array->Get(index));
   1857   }
   1858 
   1859   static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
   1860                                     jobject java_value) {
   1861     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
   1862     ScopedObjectAccess soa(env);
   1863     ObjPtr<mirror::ObjectArray<mirror::Object>> array =
   1864         soa.Decode<mirror::ObjectArray<mirror::Object>>(java_array);
   1865     ObjPtr<mirror::Object> value = soa.Decode<mirror::Object>(java_value);
   1866     array->Set<false>(index, value.Ptr());
   1867   }
   1868 
   1869   static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
   1870     return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
   1871   }
   1872 
   1873   static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
   1874     return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
   1875   }
   1876 
   1877   static jcharArray NewCharArray(JNIEnv* env, jsize length) {
   1878     return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
   1879   }
   1880 
   1881   static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
   1882     return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
   1883   }
   1884 
   1885   static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
   1886     return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
   1887   }
   1888 
   1889   static jintArray NewIntArray(JNIEnv* env, jsize length) {
   1890     return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
   1891   }
   1892 
   1893   static jlongArray NewLongArray(JNIEnv* env, jsize length) {
   1894     return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
   1895   }
   1896 
   1897   static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
   1898                                      jobject initial_element) {
   1899     if (UNLIKELY(length < 0)) {
   1900       JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
   1901       return nullptr;
   1902     }
   1903     CHECK_NON_NULL_ARGUMENT(element_jclass);
   1904 
   1905     // Compute the array class corresponding to the given element class.
   1906     ScopedObjectAccess soa(env);
   1907     ObjPtr<mirror::Class> array_class;
   1908     {
   1909       ObjPtr<mirror::Class> element_class = soa.Decode<mirror::Class>(element_jclass).Ptr();
   1910       if (UNLIKELY(element_class->IsPrimitive())) {
   1911         soa.Vm()->JniAbortF("NewObjectArray",
   1912                             "not an object type: %s",
   1913                             element_class->PrettyDescriptor().c_str());
   1914         return nullptr;
   1915       }
   1916       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   1917       array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
   1918       if (UNLIKELY(array_class == nullptr)) {
   1919         return nullptr;
   1920       }
   1921     }
   1922 
   1923     // Allocate and initialize if necessary.
   1924     mirror::ObjectArray<mirror::Object>* result =
   1925         mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
   1926     if (result != nullptr && initial_element != nullptr) {
   1927       ObjPtr<mirror::Object> initial_object = soa.Decode<mirror::Object>(initial_element);
   1928       if (initial_object != nullptr) {
   1929         mirror::Class* element_class = result->GetClass()->GetComponentType();
   1930         if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
   1931           soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
   1932                               "element type of '%s'",
   1933                               mirror::Class::PrettyDescriptor(initial_object->GetClass()).c_str(),
   1934                               element_class->PrettyDescriptor().c_str());
   1935           return nullptr;
   1936         } else {
   1937           for (jsize i = 0; i < length; ++i) {
   1938             result->SetWithoutChecks<false>(i, initial_object.Ptr());
   1939           }
   1940         }
   1941       }
   1942     }
   1943     return soa.AddLocalReference<jobjectArray>(result);
   1944   }
   1945 
   1946   static jshortArray NewShortArray(JNIEnv* env, jsize length) {
   1947     return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
   1948   }
   1949 
   1950   static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
   1951     CHECK_NON_NULL_ARGUMENT(java_array);
   1952     ScopedObjectAccess soa(env);
   1953     ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
   1954     if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
   1955       soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
   1956                           array->GetClass()->PrettyDescriptor().c_str());
   1957       return nullptr;
   1958     }
   1959     gc::Heap* heap = Runtime::Current()->GetHeap();
   1960     if (heap->IsMovableObject(array)) {
   1961       if (!kUseReadBarrier) {
   1962         heap->IncrementDisableMovingGC(soa.Self());
   1963       } else {
   1964         // For the CC collector, we only need to wait for the thread flip rather than the whole GC
   1965         // to occur thanks to the to-space invariant.
   1966         heap->IncrementDisableThreadFlip(soa.Self());
   1967       }
   1968       // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
   1969       array = soa.Decode<mirror::Array>(java_array);
   1970     }
   1971     if (is_copy != nullptr) {
   1972       *is_copy = JNI_FALSE;
   1973     }
   1974     return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
   1975   }
   1976 
   1977   static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
   1978                                             jint mode) {
   1979     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
   1980     ScopedObjectAccess soa(env);
   1981     ObjPtr<mirror::Array> array = soa.Decode<mirror::Array>(java_array);
   1982     if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
   1983       soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
   1984                           array->GetClass()->PrettyDescriptor().c_str());
   1985       return;
   1986     }
   1987     const size_t component_size = array->GetClass()->GetComponentSize();
   1988     ReleasePrimitiveArray(soa, array.Ptr(), component_size, elements, mode);
   1989   }
   1990 
   1991   static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
   1992     return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
   1993   }
   1994 
   1995   static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
   1996     return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
   1997   }
   1998 
   1999   static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
   2000     return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
   2001   }
   2002 
   2003   static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
   2004     return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
   2005   }
   2006 
   2007   static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
   2008     return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
   2009   }
   2010 
   2011   static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
   2012     return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
   2013   }
   2014 
   2015   static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
   2016     return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
   2017   }
   2018 
   2019   static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
   2020     return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
   2021   }
   2022 
   2023   static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
   2024                                           jint mode) {
   2025     ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
   2026                                                                          mode);
   2027   }
   2028 
   2029   static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
   2030     ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
   2031   }
   2032 
   2033   static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
   2034     ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
   2035   }
   2036 
   2037   static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
   2038                                          jint mode) {
   2039     ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
   2040   }
   2041 
   2042   static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
   2043                                         jint mode) {
   2044     ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
   2045   }
   2046 
   2047   static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
   2048     ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
   2049   }
   2050 
   2051   static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
   2052     ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
   2053   }
   2054 
   2055   static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
   2056                                         jint mode) {
   2057     ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
   2058   }
   2059 
   2060   static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
   2061                                     jboolean* buf) {
   2062     GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
   2063                                                                            length, buf);
   2064   }
   2065 
   2066   static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
   2067                                  jbyte* buf) {
   2068     GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
   2069   }
   2070 
   2071   static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
   2072                                  jchar* buf) {
   2073     GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
   2074   }
   2075 
   2076   static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
   2077                                    jdouble* buf) {
   2078     GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
   2079                                                                         buf);
   2080   }
   2081 
   2082   static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
   2083                                   jfloat* buf) {
   2084     GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
   2085                                                                      buf);
   2086   }
   2087 
   2088   static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
   2089                                 jint* buf) {
   2090     GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
   2091   }
   2092 
   2093   static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
   2094                                  jlong* buf) {
   2095     GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
   2096   }
   2097 
   2098   static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
   2099                                   jshort* buf) {
   2100     GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
   2101                                                                      buf);
   2102   }
   2103 
   2104   static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
   2105                                     const jboolean* buf) {
   2106     SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
   2107                                                                            length, buf);
   2108   }
   2109 
   2110   static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
   2111                                  const jbyte* buf) {
   2112     SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
   2113   }
   2114 
   2115   static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
   2116                                  const jchar* buf) {
   2117     SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
   2118   }
   2119 
   2120   static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
   2121                                    const jdouble* buf) {
   2122     SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
   2123                                                                         buf);
   2124   }
   2125 
   2126   static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
   2127                                   const jfloat* buf) {
   2128     SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
   2129                                                                      buf);
   2130   }
   2131 
   2132   static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
   2133                                 const jint* buf) {
   2134     SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
   2135   }
   2136 
   2137   static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
   2138                                  const jlong* buf) {
   2139     SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
   2140   }
   2141 
   2142   static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
   2143                                   const jshort* buf) {
   2144     SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
   2145                                                                      buf);
   2146   }
   2147 
   2148   static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
   2149                               jint method_count) {
   2150     return RegisterNativeMethods(env, java_class, methods, method_count, true);
   2151   }
   2152 
   2153   static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
   2154                                     jint method_count, bool return_errors) {
   2155     if (UNLIKELY(method_count < 0)) {
   2156       JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
   2157                                        method_count);
   2158       return JNI_ERR;  // Not reached except in unit tests.
   2159     }
   2160     CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
   2161     ScopedObjectAccess soa(env);
   2162     StackHandleScope<1> hs(soa.Self());
   2163     Handle<mirror::Class> c = hs.NewHandle(soa.Decode<mirror::Class>(java_class));
   2164     if (UNLIKELY(method_count == 0)) {
   2165       LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
   2166           << c->PrettyDescriptor();
   2167       return JNI_OK;
   2168     }
   2169     CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
   2170     for (jint i = 0; i < method_count; ++i) {
   2171       const char* name = methods[i].name;
   2172       const char* sig = methods[i].signature;
   2173       const void* fnPtr = methods[i].fnPtr;
   2174       if (UNLIKELY(name == nullptr)) {
   2175         ReportInvalidJNINativeMethod(soa, c.Get(), "method name", i, return_errors);
   2176         return JNI_ERR;
   2177       } else if (UNLIKELY(sig == nullptr)) {
   2178         ReportInvalidJNINativeMethod(soa, c.Get(), "method signature", i, return_errors);
   2179         return JNI_ERR;
   2180       } else if (UNLIKELY(fnPtr == nullptr)) {
   2181         ReportInvalidJNINativeMethod(soa, c.Get(), "native function", i, return_errors);
   2182         return JNI_ERR;
   2183       }
   2184       bool is_fast = false;
   2185       // Notes about fast JNI calls:
   2186       //
   2187       // On a normal JNI call, the calling thread usually transitions
   2188       // from the kRunnable state to the kNative state. But if the
   2189       // called native function needs to access any Java object, it
   2190       // will have to transition back to the kRunnable state.
   2191       //
   2192       // There is a cost to this double transition. For a JNI call
   2193       // that should be quick, this cost may dominate the call cost.
   2194       //
   2195       // On a fast JNI call, the calling thread avoids this double
   2196       // transition by not transitioning from kRunnable to kNative and
   2197       // stays in the kRunnable state.
   2198       //
   2199       // There are risks to using a fast JNI call because it can delay
   2200       // a response to a thread suspension request which is typically
   2201       // used for a GC root scanning, etc. If a fast JNI call takes a
   2202       // long time, it could cause longer thread suspension latency
   2203       // and GC pauses.
   2204       //
   2205       // Thus, fast JNI should be used with care. It should be used
   2206       // for a JNI call that takes a short amount of time (eg. no
   2207       // long-running loop) and does not block (eg. no locks, I/O,
   2208       // etc.)
   2209       //
   2210       // A '!' prefix in the signature in the JNINativeMethod
   2211       // indicates that it's a fast JNI call and the runtime omits the
   2212       // thread state transition from kRunnable to kNative at the
   2213       // entry.
   2214       if (*sig == '!') {
   2215         is_fast = true;
   2216         ++sig;
   2217       }
   2218 
   2219       // Note: the right order is to try to find the method locally
   2220       // first, either as a direct or a virtual method. Then move to
   2221       // the parent.
   2222       ArtMethod* m = nullptr;
   2223       bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
   2224       for (ObjPtr<mirror::Class> current_class = c.Get();
   2225            current_class != nullptr;
   2226            current_class = current_class->GetSuperClass()) {
   2227         // Search first only comparing methods which are native.
   2228         m = FindMethod<true>(current_class.Ptr(), name, sig);
   2229         if (m != nullptr) {
   2230           break;
   2231         }
   2232 
   2233         // Search again comparing to all methods, to find non-native methods that match.
   2234         m = FindMethod<false>(current_class.Ptr(), name, sig);
   2235         if (m != nullptr) {
   2236           break;
   2237         }
   2238 
   2239         if (warn_on_going_to_parent) {
   2240           LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
   2241                        << "This is slow, consider changing your RegisterNatives calls.";
   2242           warn_on_going_to_parent = false;
   2243         }
   2244       }
   2245 
   2246       if (m == nullptr) {
   2247         c->DumpClass(
   2248             LOG_STREAM(return_errors
   2249                            ? ::android::base::ERROR
   2250                            : ::android::base::FATAL_WITHOUT_ABORT),
   2251             mirror::Class::kDumpClassFullDetail);
   2252         LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
   2253             << "Failed to register native method "
   2254             << c->PrettyDescriptor() << "." << name << sig << " in "
   2255             << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
   2256         ThrowNoSuchMethodError(soa, c.Get(), name, sig, "static or non-static");
   2257         return JNI_ERR;
   2258       } else if (!m->IsNative()) {
   2259         LOG(return_errors ? ::android::base::ERROR : ::android::base::FATAL)
   2260             << "Failed to register non-native method "
   2261             << c->PrettyDescriptor() << "." << name << sig
   2262             << " as native";
   2263         ThrowNoSuchMethodError(soa, c.Get(), name, sig, "native");
   2264         return JNI_ERR;
   2265       }
   2266 
   2267       VLOG(jni) << "[Registering JNI native method " << m->PrettyMethod() << "]";
   2268 
   2269       if (UNLIKELY(is_fast)) {
   2270         // There are a few reasons to switch:
   2271         // 1) We don't support !bang JNI anymore, it will turn to a hard error later.
   2272         // 2) @FastNative is actually faster. At least 1.5x faster than !bang JNI.
   2273         //    and switching is super easy, remove ! in C code, add annotation in .java code.
   2274         // 3) Good chance of hitting DCHECK failures in ScopedFastNativeObjectAccess
   2275         //    since that checks for presence of @FastNative and not for ! in the descriptor.
   2276         LOG(WARNING) << "!bang JNI is deprecated. Switch to @FastNative for " << m->PrettyMethod();
   2277         is_fast = false;
   2278         // TODO: make this a hard register error in the future.
   2279       }
   2280 
   2281       const void* final_function_ptr = m->RegisterNative(fnPtr, is_fast);
   2282       UNUSED(final_function_ptr);
   2283     }
   2284     return JNI_OK;
   2285   }
   2286 
   2287   static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
   2288     CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
   2289     ScopedObjectAccess soa(env);
   2290     ObjPtr<mirror::Class> c = soa.Decode<mirror::Class>(java_class);
   2291 
   2292     VLOG(jni) << "[Unregistering JNI native methods for " << mirror::Class::PrettyClass(c) << "]";
   2293 
   2294     size_t unregistered_count = 0;
   2295     auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
   2296     for (auto& m : c->GetMethods(pointer_size)) {
   2297       if (m.IsNative()) {
   2298         m.UnregisterNative();
   2299         unregistered_count++;
   2300       }
   2301     }
   2302 
   2303     if (unregistered_count == 0) {
   2304       LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
   2305           << mirror::Class::PrettyDescriptor(c) << "' that contains no native methods";
   2306     }
   2307     return JNI_OK;
   2308   }
   2309 
   2310   static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
   2311     CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
   2312     ScopedObjectAccess soa(env);
   2313     ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
   2314     o = o->MonitorEnter(soa.Self());
   2315     if (soa.Self()->IsExceptionPending()) {
   2316       return JNI_ERR;
   2317     }
   2318     soa.Env()->monitors.Add(o);
   2319     return JNI_OK;
   2320   }
   2321 
   2322   static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
   2323     CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
   2324     ScopedObjectAccess soa(env);
   2325     ObjPtr<mirror::Object> o = soa.Decode<mirror::Object>(java_object);
   2326     o->MonitorExit(soa.Self());
   2327     if (soa.Self()->IsExceptionPending()) {
   2328       return JNI_ERR;
   2329     }
   2330     soa.Env()->monitors.Remove(o);
   2331     return JNI_OK;
   2332   }
   2333 
   2334   static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
   2335     CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
   2336     Runtime* runtime = Runtime::Current();
   2337     if (runtime != nullptr) {
   2338       *vm = runtime->GetJavaVM();
   2339     } else {
   2340       *vm = nullptr;
   2341     }
   2342     return (*vm != nullptr) ? JNI_OK : JNI_ERR;
   2343   }
   2344 
   2345   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
   2346     if (capacity < 0) {
   2347       JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
   2348                                        capacity);
   2349       return nullptr;
   2350     }
   2351     if (address == nullptr && capacity != 0) {
   2352       JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
   2353                                        "non-zero capacity for nullptr pointer: %" PRId64, capacity);
   2354       return nullptr;
   2355     }
   2356 
   2357     // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
   2358     if (capacity > INT_MAX) {
   2359       JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
   2360                                        "buffer capacity greater than maximum jint: %" PRId64,
   2361                                        capacity);
   2362       return nullptr;
   2363     }
   2364     jlong address_arg = reinterpret_cast<jlong>(address);
   2365     jint capacity_arg = static_cast<jint>(capacity);
   2366 
   2367     jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
   2368                                     WellKnownClasses::java_nio_DirectByteBuffer_init,
   2369                                     address_arg, capacity_arg);
   2370     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
   2371   }
   2372 
   2373   static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
   2374     return reinterpret_cast<void*>(env->GetLongField(
   2375         java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
   2376   }
   2377 
   2378   static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
   2379     return static_cast<jlong>(env->GetIntField(
   2380         java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
   2381   }
   2382 
   2383   static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
   2384     if (java_object == nullptr) {
   2385       return JNIInvalidRefType;
   2386     }
   2387 
   2388     // Do we definitely know what kind of reference this is?
   2389     IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
   2390     IndirectRefKind kind = IndirectReferenceTable::GetIndirectRefKind(ref);
   2391     switch (kind) {
   2392     case kLocal:
   2393       return JNILocalRefType;
   2394     case kGlobal:
   2395       return JNIGlobalRefType;
   2396     case kWeakGlobal:
   2397       return JNIWeakGlobalRefType;
   2398     case kHandleScopeOrInvalid:
   2399       // Assume value is in a handle scope.
   2400       return JNILocalRefType;
   2401     }
   2402     LOG(FATAL) << "IndirectRefKind[" << kind << "]";
   2403     UNREACHABLE();
   2404   }
   2405 
   2406  private:
   2407   static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
   2408                                           const char* caller)
   2409       REQUIRES_SHARED(Locks::mutator_lock_) {
   2410     // TODO: we should try to expand the table if necessary.
   2411     if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsInitial)) {
   2412       LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
   2413       return JNI_ERR;
   2414     }
   2415     // TODO: this isn't quite right, since "capacity" includes holes.
   2416     const size_t capacity = soa.Env()->locals.Capacity();
   2417     bool okay = (static_cast<jint>(kLocalsInitial - capacity) >= desired_capacity);
   2418     if (!okay) {
   2419       soa.Self()->ThrowOutOfMemoryError(caller);
   2420     }
   2421     return okay ? JNI_OK : JNI_ERR;
   2422   }
   2423 
   2424   template<typename JniT, typename ArtT>
   2425   static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
   2426     ScopedObjectAccess soa(env);
   2427     if (UNLIKELY(length < 0)) {
   2428       soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
   2429       return nullptr;
   2430     }
   2431     ArtT* result = ArtT::Alloc(soa.Self(), length);
   2432     return soa.AddLocalReference<JniT>(result);
   2433   }
   2434 
   2435   template <typename JArrayT, typename ElementT, typename ArtArrayT>
   2436   static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
   2437                                            const char* fn_name, const char* operation)
   2438       REQUIRES_SHARED(Locks::mutator_lock_) {
   2439     ObjPtr<ArtArrayT> array = soa.Decode<ArtArrayT>(java_array);
   2440     if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
   2441       soa.Vm()->JniAbortF(fn_name,
   2442                           "attempt to %s %s primitive array elements with an object of type %s",
   2443                           operation,
   2444                           mirror::Class::PrettyDescriptor(
   2445                               ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
   2446                           mirror::Class::PrettyDescriptor(array->GetClass()).c_str());
   2447       return nullptr;
   2448     }
   2449     DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
   2450     return array.Ptr();
   2451   }
   2452 
   2453   template <typename ArrayT, typename ElementT, typename ArtArrayT>
   2454   static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
   2455     CHECK_NON_NULL_ARGUMENT(java_array);
   2456     ScopedObjectAccess soa(env);
   2457     ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
   2458                                                                             "GetArrayElements",
   2459                                                                             "get");
   2460     if (UNLIKELY(array == nullptr)) {
   2461       return nullptr;
   2462     }
   2463     // Only make a copy if necessary.
   2464     if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
   2465       if (is_copy != nullptr) {
   2466         *is_copy = JNI_TRUE;
   2467       }
   2468       const size_t component_size = sizeof(ElementT);
   2469       size_t size = array->GetLength() * component_size;
   2470       void* data = new uint64_t[RoundUp(size, 8) / 8];
   2471       memcpy(data, array->GetData(), size);
   2472       return reinterpret_cast<ElementT*>(data);
   2473     } else {
   2474       if (is_copy != nullptr) {
   2475         *is_copy = JNI_FALSE;
   2476       }
   2477       return reinterpret_cast<ElementT*>(array->GetData());
   2478     }
   2479   }
   2480 
   2481   template <typename ArrayT, typename ElementT, typename ArtArrayT>
   2482   static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
   2483     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
   2484     ScopedObjectAccess soa(env);
   2485     ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
   2486                                                                             "ReleaseArrayElements",
   2487                                                                             "release");
   2488     if (array == nullptr) {
   2489       return;
   2490     }
   2491     ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
   2492   }
   2493 
   2494   static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
   2495                                     size_t component_size, void* elements, jint mode)
   2496       REQUIRES_SHARED(Locks::mutator_lock_) {
   2497     void* array_data = array->GetRawData(component_size, 0);
   2498     gc::Heap* heap = Runtime::Current()->GetHeap();
   2499     bool is_copy = array_data != elements;
   2500     size_t bytes = array->GetLength() * component_size;
   2501     if (is_copy) {
   2502       // Sanity check: If elements is not the same as the java array's data, it better not be a
   2503       // heap address. TODO: This might be slow to check, may be worth keeping track of which
   2504       // copies we make?
   2505       if (heap->IsNonDiscontinuousSpaceHeapAddress(elements)) {
   2506         soa.Vm()->JniAbortF("ReleaseArrayElements",
   2507                             "invalid element pointer %p, array elements are %p",
   2508                             reinterpret_cast<void*>(elements), array_data);
   2509         return;
   2510       }
   2511       if (mode != JNI_ABORT) {
   2512         memcpy(array_data, elements, bytes);
   2513       } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
   2514         // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
   2515         LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
   2516         soa.Self()->DumpJavaStack(LOG_STREAM(WARNING));
   2517       }
   2518     }
   2519     if (mode != JNI_COMMIT) {
   2520       if (is_copy) {
   2521         delete[] reinterpret_cast<uint64_t*>(elements);
   2522       } else if (heap->IsMovableObject(array)) {
   2523         // Non copy to a movable object must means that we had disabled the moving GC.
   2524         if (!kUseReadBarrier) {
   2525           heap->DecrementDisableMovingGC(soa.Self());
   2526         } else {
   2527           heap->DecrementDisableThreadFlip(soa.Self());
   2528         }
   2529       }
   2530     }
   2531   }
   2532 
   2533   template <typename JArrayT, typename ElementT, typename ArtArrayT>
   2534   static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
   2535                                       jsize start, jsize length, ElementT* buf) {
   2536     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
   2537     ScopedObjectAccess soa(env);
   2538     ArtArrayT* array =
   2539         DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
   2540                                                               "GetPrimitiveArrayRegion",
   2541                                                               "get region of");
   2542     if (array != nullptr) {
   2543       if (start < 0 || length < 0 || length > array->GetLength() - start) {
   2544         ThrowAIOOBE(soa, array, start, length, "src");
   2545       } else {
   2546         CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
   2547         ElementT* data = array->GetData();
   2548         memcpy(buf, data + start, length * sizeof(ElementT));
   2549       }
   2550     }
   2551   }
   2552 
   2553   template <typename JArrayT, typename ElementT, typename ArtArrayT>
   2554   static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
   2555                                       jsize start, jsize length, const ElementT* buf) {
   2556     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
   2557     ScopedObjectAccess soa(env);
   2558     ArtArrayT* array =
   2559         DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
   2560                                                               "SetPrimitiveArrayRegion",
   2561                                                               "set region of");
   2562     if (array != nullptr) {
   2563       if (start < 0 || length < 0 || length > array->GetLength() - start) {
   2564         ThrowAIOOBE(soa, array, start, length, "dst");
   2565       } else {
   2566         CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
   2567         ElementT* data = array->GetData();
   2568         memcpy(data + start, buf, length * sizeof(ElementT));
   2569       }
   2570     }
   2571   }
   2572 };
   2573 
   2574 const JNINativeInterface gJniNativeInterface = {
   2575   nullptr,  // reserved0.
   2576   nullptr,  // reserved1.
   2577   nullptr,  // reserved2.
   2578   nullptr,  // reserved3.
   2579   JNI::GetVersion,
   2580   JNI::DefineClass,
   2581   JNI::FindClass,
   2582   JNI::FromReflectedMethod,
   2583   JNI::FromReflectedField,
   2584   JNI::ToReflectedMethod,
   2585   JNI::GetSuperclass,
   2586   JNI::IsAssignableFrom,
   2587   JNI::ToReflectedField,
   2588   JNI::Throw,
   2589   JNI::ThrowNew,
   2590   JNI::ExceptionOccurred,
   2591   JNI::ExceptionDescribe,
   2592   JNI::ExceptionClear,
   2593   JNI::FatalError,
   2594   JNI::PushLocalFrame,
   2595   JNI::PopLocalFrame,
   2596   JNI::NewGlobalRef,
   2597   JNI::DeleteGlobalRef,
   2598   JNI::DeleteLocalRef,
   2599   JNI::IsSameObject,
   2600   JNI::NewLocalRef,
   2601   JNI::EnsureLocalCapacity,
   2602   JNI::AllocObject,
   2603   JNI::NewObject,
   2604   JNI::NewObjectV,
   2605   JNI::NewObjectA,
   2606   JNI::GetObjectClass,
   2607   JNI::IsInstanceOf,
   2608   JNI::GetMethodID,
   2609   JNI::CallObjectMethod,
   2610   JNI::CallObjectMethodV,
   2611   JNI::CallObjectMethodA,
   2612   JNI::CallBooleanMethod,
   2613   JNI::CallBooleanMethodV,
   2614   JNI::CallBooleanMethodA,
   2615   JNI::CallByteMethod,
   2616   JNI::CallByteMethodV,
   2617   JNI::CallByteMethodA,
   2618   JNI::CallCharMethod,
   2619   JNI::CallCharMethodV,
   2620   JNI::CallCharMethodA,
   2621   JNI::CallShortMethod,
   2622   JNI::CallShortMethodV,
   2623   JNI::CallShortMethodA,
   2624   JNI::CallIntMethod,
   2625   JNI::CallIntMethodV,
   2626   JNI::CallIntMethodA,
   2627   JNI::CallLongMethod,
   2628   JNI::CallLongMethodV,
   2629   JNI::CallLongMethodA,
   2630   JNI::CallFloatMethod,
   2631   JNI::CallFloatMethodV,
   2632   JNI::CallFloatMethodA,
   2633   JNI::CallDoubleMethod,
   2634   JNI::CallDoubleMethodV,
   2635   JNI::CallDoubleMethodA,
   2636   JNI::CallVoidMethod,
   2637   JNI::CallVoidMethodV,
   2638   JNI::CallVoidMethodA,
   2639   JNI::CallNonvirtualObjectMethod,
   2640   JNI::CallNonvirtualObjectMethodV,
   2641   JNI::CallNonvirtualObjectMethodA,
   2642   JNI::CallNonvirtualBooleanMethod,
   2643   JNI::CallNonvirtualBooleanMethodV,
   2644   JNI::CallNonvirtualBooleanMethodA,
   2645   JNI::CallNonvirtualByteMethod,
   2646   JNI::CallNonvirtualByteMethodV,
   2647   JNI::CallNonvirtualByteMethodA,
   2648   JNI::CallNonvirtualCharMethod,
   2649   JNI::CallNonvirtualCharMethodV,
   2650   JNI::CallNonvirtualCharMethodA,
   2651   JNI::CallNonvirtualShortMethod,
   2652   JNI::CallNonvirtualShortMethodV,
   2653   JNI::CallNonvirtualShortMethodA,
   2654   JNI::CallNonvirtualIntMethod,
   2655   JNI::CallNonvirtualIntMethodV,
   2656   JNI::CallNonvirtualIntMethodA,
   2657   JNI::CallNonvirtualLongMethod,
   2658   JNI::CallNonvirtualLongMethodV,
   2659   JNI::CallNonvirtualLongMethodA,
   2660   JNI::CallNonvirtualFloatMethod,
   2661   JNI::CallNonvirtualFloatMethodV,
   2662   JNI::CallNonvirtualFloatMethodA,
   2663   JNI::CallNonvirtualDoubleMethod,
   2664   JNI::CallNonvirtualDoubleMethodV,
   2665   JNI::CallNonvirtualDoubleMethodA,
   2666   JNI::CallNonvirtualVoidMethod,
   2667   JNI::CallNonvirtualVoidMethodV,
   2668   JNI::CallNonvirtualVoidMethodA,
   2669   JNI::GetFieldID,
   2670   JNI::GetObjectField,
   2671   JNI::GetBooleanField,
   2672   JNI::GetByteField,
   2673   JNI::GetCharField,
   2674   JNI::GetShortField,
   2675   JNI::GetIntField,
   2676   JNI::GetLongField,
   2677   JNI::GetFloatField,
   2678   JNI::GetDoubleField,
   2679   JNI::SetObjectField,
   2680   JNI::SetBooleanField,
   2681   JNI::SetByteField,
   2682   JNI::SetCharField,
   2683   JNI::SetShortField,
   2684   JNI::SetIntField,
   2685   JNI::SetLongField,
   2686   JNI::SetFloatField,
   2687   JNI::SetDoubleField,
   2688   JNI::GetStaticMethodID,
   2689   JNI::CallStaticObjectMethod,
   2690   JNI::CallStaticObjectMethodV,
   2691   JNI::CallStaticObjectMethodA,
   2692   JNI::CallStaticBooleanMethod,
   2693   JNI::CallStaticBooleanMethodV,
   2694   JNI::CallStaticBooleanMethodA,
   2695   JNI::CallStaticByteMethod,
   2696   JNI::CallStaticByteMethodV,
   2697   JNI::CallStaticByteMethodA,
   2698   JNI::CallStaticCharMethod,
   2699   JNI::CallStaticCharMethodV,
   2700   JNI::CallStaticCharMethodA,
   2701   JNI::CallStaticShortMethod,
   2702   JNI::CallStaticShortMethodV,
   2703   JNI::CallStaticShortMethodA,
   2704   JNI::CallStaticIntMethod,
   2705   JNI::CallStaticIntMethodV,
   2706   JNI::CallStaticIntMethodA,
   2707   JNI::CallStaticLongMethod,
   2708   JNI::CallStaticLongMethodV,
   2709   JNI::CallStaticLongMethodA,
   2710   JNI::CallStaticFloatMethod,
   2711   JNI::CallStaticFloatMethodV,
   2712   JNI::CallStaticFloatMethodA,
   2713   JNI::CallStaticDoubleMethod,
   2714   JNI::CallStaticDoubleMethodV,
   2715   JNI::CallStaticDoubleMethodA,
   2716   JNI::CallStaticVoidMethod,
   2717   JNI::CallStaticVoidMethodV,
   2718   JNI::CallStaticVoidMethodA,
   2719   JNI::GetStaticFieldID,
   2720   JNI::GetStaticObjectField,
   2721   JNI::GetStaticBooleanField,
   2722   JNI::GetStaticByteField,
   2723   JNI::GetStaticCharField,
   2724   JNI::GetStaticShortField,
   2725   JNI::GetStaticIntField,
   2726   JNI::GetStaticLongField,
   2727   JNI::GetStaticFloatField,
   2728   JNI::GetStaticDoubleField,
   2729   JNI::SetStaticObjectField,
   2730   JNI::SetStaticBooleanField,
   2731   JNI::SetStaticByteField,
   2732   JNI::SetStaticCharField,
   2733   JNI::SetStaticShortField,
   2734   JNI::SetStaticIntField,
   2735   JNI::SetStaticLongField,
   2736   JNI::SetStaticFloatField,
   2737   JNI::SetStaticDoubleField,
   2738   JNI::NewString,
   2739   JNI::GetStringLength,
   2740   JNI::GetStringChars,
   2741   JNI::ReleaseStringChars,
   2742   JNI::NewStringUTF,
   2743   JNI::GetStringUTFLength,
   2744   JNI::GetStringUTFChars,
   2745   JNI::ReleaseStringUTFChars,
   2746   JNI::GetArrayLength,
   2747   JNI::NewObjectArray,
   2748   JNI::GetObjectArrayElement,
   2749   JNI::SetObjectArrayElement,
   2750   JNI::NewBooleanArray,
   2751   JNI::NewByteArray,
   2752   JNI::NewCharArray,
   2753   JNI::NewShortArray,
   2754   JNI::NewIntArray,
   2755   JNI::NewLongArray,
   2756   JNI::NewFloatArray,
   2757   JNI::NewDoubleArray,
   2758   JNI::GetBooleanArrayElements,
   2759   JNI::GetByteArrayElements,
   2760   JNI::GetCharArrayElements,
   2761   JNI::GetShortArrayElements,
   2762   JNI::GetIntArrayElements,
   2763   JNI::GetLongArrayElements,
   2764   JNI::GetFloatArrayElements,
   2765   JNI::GetDoubleArrayElements,
   2766   JNI::ReleaseBooleanArrayElements,
   2767   JNI::ReleaseByteArrayElements,
   2768   JNI::ReleaseCharArrayElements,
   2769   JNI::ReleaseShortArrayElements,
   2770   JNI::ReleaseIntArrayElements,
   2771   JNI::ReleaseLongArrayElements,
   2772   JNI::ReleaseFloatArrayElements,
   2773   JNI::ReleaseDoubleArrayElements,
   2774   JNI::GetBooleanArrayRegion,
   2775   JNI::GetByteArrayRegion,
   2776   JNI::GetCharArrayRegion,
   2777   JNI::GetShortArrayRegion,
   2778   JNI::GetIntArrayRegion,
   2779   JNI::GetLongArrayRegion,
   2780   JNI::GetFloatArrayRegion,
   2781   JNI::GetDoubleArrayRegion,
   2782   JNI::SetBooleanArrayRegion,
   2783   JNI::SetByteArrayRegion,
   2784   JNI::SetCharArrayRegion,
   2785   JNI::SetShortArrayRegion,
   2786   JNI::SetIntArrayRegion,
   2787   JNI::SetLongArrayRegion,
   2788   JNI::SetFloatArrayRegion,
   2789   JNI::SetDoubleArrayRegion,
   2790   JNI::RegisterNatives,
   2791   JNI::UnregisterNatives,
   2792   JNI::MonitorEnter,
   2793   JNI::MonitorExit,
   2794   JNI::GetJavaVM,
   2795   JNI::GetStringRegion,
   2796   JNI::GetStringUTFRegion,
   2797   JNI::GetPrimitiveArrayCritical,
   2798   JNI::ReleasePrimitiveArrayCritical,
   2799   JNI::GetStringCritical,
   2800   JNI::ReleaseStringCritical,
   2801   JNI::NewWeakGlobalRef,
   2802   JNI::DeleteWeakGlobalRef,
   2803   JNI::ExceptionCheck,
   2804   JNI::NewDirectByteBuffer,
   2805   JNI::GetDirectBufferAddress,
   2806   JNI::GetDirectBufferCapacity,
   2807   JNI::GetObjectRefType,
   2808 };
   2809 
   2810 const JNINativeInterface* GetJniNativeInterface() {
   2811   return &gJniNativeInterface;
   2812 }
   2813 
   2814 void (*gJniSleepForeverStub[])()  = {
   2815   nullptr,  // reserved0.
   2816   nullptr,  // reserved1.
   2817   nullptr,  // reserved2.
   2818   nullptr,  // reserved3.
   2819   SleepForever,
   2820   SleepForever,
   2821   SleepForever,
   2822   SleepForever,
   2823   SleepForever,
   2824   SleepForever,
   2825   SleepForever,
   2826   SleepForever,
   2827   SleepForever,
   2828   SleepForever,
   2829   SleepForever,
   2830   SleepForever,
   2831   SleepForever,
   2832   SleepForever,
   2833   SleepForever,
   2834   SleepForever,
   2835   SleepForever,
   2836   SleepForever,
   2837   SleepForever,
   2838   SleepForever,
   2839   SleepForever,
   2840   SleepForever,
   2841   SleepForever,
   2842   SleepForever,
   2843   SleepForever,
   2844   SleepForever,
   2845   SleepForever,
   2846   SleepForever,
   2847   SleepForever,
   2848   SleepForever,
   2849   SleepForever,
   2850   SleepForever,
   2851   SleepForever,
   2852   SleepForever,
   2853   SleepForever,
   2854   SleepForever,
   2855   SleepForever,
   2856   SleepForever,
   2857   SleepForever,
   2858   SleepForever,
   2859   SleepForever,
   2860   SleepForever,
   2861   SleepForever,
   2862   SleepForever,
   2863   SleepForever,
   2864   SleepForever,
   2865   SleepForever,
   2866   SleepForever,
   2867   SleepForever,
   2868   SleepForever,
   2869   SleepForever,
   2870   SleepForever,
   2871   SleepForever,
   2872   SleepForever,
   2873   SleepForever,
   2874   SleepForever,
   2875   SleepForever,
   2876   SleepForever,
   2877   SleepForever,
   2878   SleepForever,
   2879   SleepForever,
   2880   SleepForever,
   2881   SleepForever,
   2882   SleepForever,
   2883   SleepForever,
   2884   SleepForever,
   2885   SleepForever,
   2886   SleepForever,
   2887   SleepForever,
   2888   SleepForever,
   2889   SleepForever,
   2890   SleepForever,
   2891   SleepForever,
   2892   SleepForever,
   2893   SleepForever,
   2894   SleepForever,
   2895   SleepForever,
   2896   SleepForever,
   2897   SleepForever,
   2898   SleepForever,
   2899   SleepForever,
   2900   SleepForever,
   2901   SleepForever,
   2902   SleepForever,
   2903   SleepForever,
   2904   SleepForever,
   2905   SleepForever,
   2906   SleepForever,
   2907   SleepForever,
   2908   SleepForever,
   2909   SleepForever,
   2910   SleepForever,
   2911   SleepForever,
   2912   SleepForever,
   2913   SleepForever,
   2914   SleepForever,
   2915   SleepForever,
   2916   SleepForever,
   2917   SleepForever,
   2918   SleepForever,
   2919   SleepForever,
   2920   SleepForever,
   2921   SleepForever,
   2922   SleepForever,
   2923   SleepForever,
   2924   SleepForever,
   2925   SleepForever,
   2926   SleepForever,
   2927   SleepForever,
   2928   SleepForever,
   2929   SleepForever,
   2930   SleepForever,
   2931   SleepForever,
   2932   SleepForever,
   2933   SleepForever,
   2934   SleepForever,
   2935   SleepForever,
   2936   SleepForever,
   2937   SleepForever,
   2938   SleepForever,
   2939   SleepForever,
   2940   SleepForever,
   2941   SleepForever,
   2942   SleepForever,
   2943   SleepForever,
   2944   SleepForever,
   2945   SleepForever,
   2946   SleepForever,
   2947   SleepForever,
   2948   SleepForever,
   2949   SleepForever,
   2950   SleepForever,
   2951   SleepForever,
   2952   SleepForever,
   2953   SleepForever,
   2954   SleepForever,
   2955   SleepForever,
   2956   SleepForever,
   2957   SleepForever,
   2958   SleepForever,
   2959   SleepForever,
   2960   SleepForever,
   2961   SleepForever,
   2962   SleepForever,
   2963   SleepForever,
   2964   SleepForever,
   2965   SleepForever,
   2966   SleepForever,
   2967   SleepForever,
   2968   SleepForever,
   2969   SleepForever,
   2970   SleepForever,
   2971   SleepForever,
   2972   SleepForever,
   2973   SleepForever,
   2974   SleepForever,
   2975   SleepForever,
   2976   SleepForever,
   2977   SleepForever,
   2978   SleepForever,
   2979   SleepForever,
   2980   SleepForever,
   2981   SleepForever,
   2982   SleepForever,
   2983   SleepForever,
   2984   SleepForever,
   2985   SleepForever,
   2986   SleepForever,
   2987   SleepForever,
   2988   SleepForever,
   2989   SleepForever,
   2990   SleepForever,
   2991   SleepForever,
   2992   SleepForever,
   2993   SleepForever,
   2994   SleepForever,
   2995   SleepForever,
   2996   SleepForever,
   2997   SleepForever,
   2998   SleepForever,
   2999   SleepForever,
   3000   SleepForever,
   3001   SleepForever,
   3002   SleepForever,
   3003   SleepForever,
   3004   SleepForever,
   3005   SleepForever,
   3006   SleepForever,
   3007   SleepForever,
   3008   SleepForever,
   3009   SleepForever,
   3010   SleepForever,
   3011   SleepForever,
   3012   SleepForever,
   3013   SleepForever,
   3014   SleepForever,
   3015   SleepForever,
   3016   SleepForever,
   3017   SleepForever,
   3018   SleepForever,
   3019   SleepForever,
   3020   SleepForever,
   3021   SleepForever,
   3022   SleepForever,
   3023   SleepForever,
   3024   SleepForever,
   3025   SleepForever,
   3026   SleepForever,
   3027   SleepForever,
   3028   SleepForever,
   3029   SleepForever,
   3030   SleepForever,
   3031   SleepForever,
   3032   SleepForever,
   3033   SleepForever,
   3034   SleepForever,
   3035   SleepForever,
   3036   SleepForever,
   3037   SleepForever,
   3038   SleepForever,
   3039   SleepForever,
   3040   SleepForever,
   3041   SleepForever,
   3042   SleepForever,
   3043   SleepForever,
   3044   SleepForever,
   3045   SleepForever,
   3046   SleepForever,
   3047   SleepForever,
   3048 };
   3049 
   3050 const JNINativeInterface* GetRuntimeShutdownNativeInterface() {
   3051   return reinterpret_cast<JNINativeInterface*>(&gJniSleepForeverStub);
   3052 }
   3053 
   3054 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
   3055                            jint method_count) {
   3056   ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
   3057   if (c.get() == nullptr) {
   3058     LOG(FATAL) << "Couldn't find class: " << jni_class_name;
   3059   }
   3060   JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
   3061 }
   3062 
   3063 }  // namespace art
   3064 
   3065 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
   3066   switch (rhs) {
   3067   case JNIInvalidRefType:
   3068     os << "JNIInvalidRefType";
   3069     return os;
   3070   case JNILocalRefType:
   3071     os << "JNILocalRefType";
   3072     return os;
   3073   case JNIGlobalRefType:
   3074     os << "JNIGlobalRefType";
   3075     return os;
   3076   case JNIWeakGlobalRefType:
   3077     os << "JNIWeakGlobalRefType";
   3078     return os;
   3079   default:
   3080     LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
   3081     UNREACHABLE();
   3082   }
   3083 }
   3084