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