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     ClassLoader* cl = GetClassLoader(soa);
    295     field_type = class_linker->FindClass(sig, cl);
    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     if (obj == NULL) {
    835       return NULL;
    836     }
    837     ScopedObjectAccess soa(env);
    838     JavaVMExt* vm = soa.Vm();
    839     IndirectReferenceTable& globals = vm->globals;
    840     Object* decoded_obj = soa.Decode<Object*>(obj);
    841     WriterMutexLock mu(soa.Self(), vm->globals_lock);
    842     IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
    843     return reinterpret_cast<jobject>(ref);
    844   }
    845 
    846   static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
    847     if (obj == NULL) {
    848       return;
    849     }
    850     JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
    851     IndirectReferenceTable& globals = vm->globals;
    852     Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
    853     WriterMutexLock mu(self, vm->globals_lock);
    854 
    855     if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
    856       LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
    857                    << "failed to find entry";
    858     }
    859   }
    860 
    861   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
    862     ScopedObjectAccess soa(env);
    863     return AddWeakGlobalReference(soa, soa.Decode<Object*>(obj));
    864   }
    865 
    866   static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
    867     if (obj != nullptr) {
    868       ScopedObjectAccess soa(env);
    869       soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
    870     }
    871   }
    872 
    873   static jobject NewLocalRef(JNIEnv* env, jobject obj) {
    874     if (obj == NULL) {
    875       return NULL;
    876     }
    877     ScopedObjectAccess soa(env);
    878     return soa.AddLocalReference<jobject>(soa.Decode<Object*>(obj));
    879   }
    880 
    881   static void DeleteLocalRef(JNIEnv* env, jobject obj) {
    882     if (obj == NULL) {
    883       return;
    884     }
    885     IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
    886 
    887     uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
    888     if (!locals.Remove(cookie, obj)) {
    889       // Attempting to delete a local reference that is not in the
    890       // topmost local reference frame is a no-op.  DeleteLocalRef returns
    891       // void and doesn't throw any exceptions, but we should probably
    892       // complain about it so the user will notice that things aren't
    893       // going quite the way they expect.
    894       LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
    895                    << "failed to find entry";
    896     }
    897   }
    898 
    899   static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
    900     if (obj1 == obj2) {
    901       return JNI_TRUE;
    902     } else {
    903       ScopedObjectAccess soa(env);
    904       return (soa.Decode<Object*>(obj1) == soa.Decode<Object*>(obj2)) ? JNI_TRUE : JNI_FALSE;
    905     }
    906   }
    907 
    908   static jobject AllocObject(JNIEnv* env, jclass java_class) {
    909     CHECK_NON_NULL_ARGUMENT(AllocObject, java_class);
    910     ScopedObjectAccess soa(env);
    911     Class* c = soa.Decode<Class*>(java_class);
    912     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
    913       return NULL;
    914     }
    915     return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
    916   }
    917 
    918   static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
    919     va_list args;
    920     va_start(args, mid);
    921     CHECK_NON_NULL_ARGUMENT(NewObject, java_class);
    922     CHECK_NON_NULL_ARGUMENT(NewObject, mid);
    923     jobject result = NewObjectV(env, java_class, mid, args);
    924     va_end(args);
    925     return result;
    926   }
    927 
    928   static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
    929     CHECK_NON_NULL_ARGUMENT(NewObjectV, java_class);
    930     CHECK_NON_NULL_ARGUMENT(NewObjectV, mid);
    931     ScopedObjectAccess soa(env);
    932     Class* c = soa.Decode<Class*>(java_class);
    933     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
    934       return NULL;
    935     }
    936     Object* result = c->AllocObject(soa.Self());
    937     if (result == NULL) {
    938       return NULL;
    939     }
    940     jobject local_result = soa.AddLocalReference<jobject>(result);
    941     CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
    942     if (!soa.Self()->IsExceptionPending()) {
    943       return local_result;
    944     } else {
    945       return NULL;
    946     }
    947   }
    948 
    949   static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
    950     CHECK_NON_NULL_ARGUMENT(NewObjectA, java_class);
    951     CHECK_NON_NULL_ARGUMENT(NewObjectA, mid);
    952     ScopedObjectAccess soa(env);
    953     Class* c = soa.Decode<Class*>(java_class);
    954     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
    955       return NULL;
    956     }
    957     Object* result = c->AllocObject(soa.Self());
    958     if (result == NULL) {
    959       return NULL;
    960     }
    961     jobject local_result = soa.AddLocalReference<jobjectArray>(result);
    962     CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
    963     if (!soa.Self()->IsExceptionPending()) {
    964       return local_result;
    965     } else {
    966       return NULL;
    967     }
    968   }
    969 
    970   static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
    971     CHECK_NON_NULL_ARGUMENT(GetMethodID, java_class);
    972     CHECK_NON_NULL_ARGUMENT(GetMethodID, name);
    973     CHECK_NON_NULL_ARGUMENT(GetMethodID, sig);
    974     ScopedObjectAccess soa(env);
    975     return FindMethodID(soa, java_class, name, sig, false);
    976   }
    977 
    978   static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
    979                                      const char* sig) {
    980     CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, java_class);
    981     CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, name);
    982     CHECK_NON_NULL_ARGUMENT(GetStaticMethodID, sig);
    983     ScopedObjectAccess soa(env);
    984     return FindMethodID(soa, java_class, name, sig, true);
    985   }
    986 
    987   static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
    988     va_list ap;
    989     va_start(ap, mid);
    990     CHECK_NON_NULL_ARGUMENT(CallObjectMethod, obj);
    991     CHECK_NON_NULL_ARGUMENT(CallObjectMethod, mid);
    992     ScopedObjectAccess soa(env);
    993     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
    994     va_end(ap);
    995     return soa.AddLocalReference<jobject>(result.GetL());
    996   }
    997 
    998   static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
    999     CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, obj);
   1000     CHECK_NON_NULL_ARGUMENT(CallObjectMethodV, mid);
   1001     ScopedObjectAccess soa(env);
   1002     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
   1003     return soa.AddLocalReference<jobject>(result.GetL());
   1004   }
   1005 
   1006   static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1007     CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, obj);
   1008     CHECK_NON_NULL_ARGUMENT(CallObjectMethodA, mid);
   1009     ScopedObjectAccess soa(env);
   1010     JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
   1011     return soa.AddLocalReference<jobject>(result.GetL());
   1012   }
   1013 
   1014   static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1015     va_list ap;
   1016     va_start(ap, mid);
   1017     CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, obj);
   1018     CHECK_NON_NULL_ARGUMENT(CallBooleanMethod, mid);
   1019     ScopedObjectAccess soa(env);
   1020     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1021     va_end(ap);
   1022     return result.GetZ();
   1023   }
   1024 
   1025   static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1026     CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, obj);
   1027     CHECK_NON_NULL_ARGUMENT(CallBooleanMethodV, mid);
   1028     ScopedObjectAccess soa(env);
   1029     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
   1030   }
   1031 
   1032   static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1033     CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, obj);
   1034     CHECK_NON_NULL_ARGUMENT(CallBooleanMethodA, mid);
   1035     ScopedObjectAccess soa(env);
   1036     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
   1037   }
   1038 
   1039   static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1040     va_list ap;
   1041     va_start(ap, mid);
   1042     CHECK_NON_NULL_ARGUMENT(CallByteMethod, obj);
   1043     CHECK_NON_NULL_ARGUMENT(CallByteMethod, mid);
   1044     ScopedObjectAccess soa(env);
   1045     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1046     va_end(ap);
   1047     return result.GetB();
   1048   }
   1049 
   1050   static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1051     CHECK_NON_NULL_ARGUMENT(CallByteMethodV, obj);
   1052     CHECK_NON_NULL_ARGUMENT(CallByteMethodV, mid);
   1053     ScopedObjectAccess soa(env);
   1054     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
   1055   }
   1056 
   1057   static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1058     CHECK_NON_NULL_ARGUMENT(CallByteMethodA, obj);
   1059     CHECK_NON_NULL_ARGUMENT(CallByteMethodA, mid);
   1060     ScopedObjectAccess soa(env);
   1061     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
   1062   }
   1063 
   1064   static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1065     va_list ap;
   1066     va_start(ap, mid);
   1067     CHECK_NON_NULL_ARGUMENT(CallCharMethod, obj);
   1068     CHECK_NON_NULL_ARGUMENT(CallCharMethod, mid);
   1069     ScopedObjectAccess soa(env);
   1070     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1071     va_end(ap);
   1072     return result.GetC();
   1073   }
   1074 
   1075   static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1076     CHECK_NON_NULL_ARGUMENT(CallCharMethodV, obj);
   1077     CHECK_NON_NULL_ARGUMENT(CallCharMethodV, mid);
   1078     ScopedObjectAccess soa(env);
   1079     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
   1080   }
   1081 
   1082   static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1083     CHECK_NON_NULL_ARGUMENT(CallCharMethodA, obj);
   1084     CHECK_NON_NULL_ARGUMENT(CallCharMethodA, mid);
   1085     ScopedObjectAccess soa(env);
   1086     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
   1087   }
   1088 
   1089   static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1090     va_list ap;
   1091     va_start(ap, mid);
   1092     CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, obj);
   1093     CHECK_NON_NULL_ARGUMENT(CallDoubleMethod, mid);
   1094     ScopedObjectAccess soa(env);
   1095     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1096     va_end(ap);
   1097     return result.GetD();
   1098   }
   1099 
   1100   static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1101     CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, obj);
   1102     CHECK_NON_NULL_ARGUMENT(CallDoubleMethodV, mid);
   1103     ScopedObjectAccess soa(env);
   1104     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
   1105   }
   1106 
   1107   static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1108     CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, obj);
   1109     CHECK_NON_NULL_ARGUMENT(CallDoubleMethodA, mid);
   1110     ScopedObjectAccess soa(env);
   1111     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
   1112   }
   1113 
   1114   static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1115     va_list ap;
   1116     va_start(ap, mid);
   1117     CHECK_NON_NULL_ARGUMENT(CallFloatMethod, obj);
   1118     CHECK_NON_NULL_ARGUMENT(CallFloatMethod, mid);
   1119     ScopedObjectAccess soa(env);
   1120     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1121     va_end(ap);
   1122     return result.GetF();
   1123   }
   1124 
   1125   static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1126     CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, obj);
   1127     CHECK_NON_NULL_ARGUMENT(CallFloatMethodV, mid);
   1128     ScopedObjectAccess soa(env);
   1129     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
   1130   }
   1131 
   1132   static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1133     CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, obj);
   1134     CHECK_NON_NULL_ARGUMENT(CallFloatMethodA, mid);
   1135     ScopedObjectAccess soa(env);
   1136     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
   1137   }
   1138 
   1139   static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1140     va_list ap;
   1141     va_start(ap, mid);
   1142     CHECK_NON_NULL_ARGUMENT(CallIntMethod, obj);
   1143     CHECK_NON_NULL_ARGUMENT(CallIntMethod, mid);
   1144     ScopedObjectAccess soa(env);
   1145     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1146     va_end(ap);
   1147     return result.GetI();
   1148   }
   1149 
   1150   static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1151     CHECK_NON_NULL_ARGUMENT(CallIntMethodV, obj);
   1152     CHECK_NON_NULL_ARGUMENT(CallIntMethodV, mid);
   1153     ScopedObjectAccess soa(env);
   1154     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
   1155   }
   1156 
   1157   static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1158     CHECK_NON_NULL_ARGUMENT(CallIntMethodA, obj);
   1159     CHECK_NON_NULL_ARGUMENT(CallIntMethodA, mid);
   1160     ScopedObjectAccess soa(env);
   1161     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
   1162   }
   1163 
   1164   static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1165     va_list ap;
   1166     va_start(ap, mid);
   1167     CHECK_NON_NULL_ARGUMENT(CallLongMethod, obj);
   1168     CHECK_NON_NULL_ARGUMENT(CallLongMethod, mid);
   1169     ScopedObjectAccess soa(env);
   1170     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1171     va_end(ap);
   1172     return result.GetJ();
   1173   }
   1174 
   1175   static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1176     CHECK_NON_NULL_ARGUMENT(CallLongMethodV, obj);
   1177     CHECK_NON_NULL_ARGUMENT(CallLongMethodV, mid);
   1178     ScopedObjectAccess soa(env);
   1179     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
   1180   }
   1181 
   1182   static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1183     CHECK_NON_NULL_ARGUMENT(CallLongMethodA, obj);
   1184     CHECK_NON_NULL_ARGUMENT(CallLongMethodA, mid);
   1185     ScopedObjectAccess soa(env);
   1186     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
   1187   }
   1188 
   1189   static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1190     va_list ap;
   1191     va_start(ap, mid);
   1192     CHECK_NON_NULL_ARGUMENT(CallShortMethod, obj);
   1193     CHECK_NON_NULL_ARGUMENT(CallShortMethod, mid);
   1194     ScopedObjectAccess soa(env);
   1195     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
   1196     va_end(ap);
   1197     return result.GetS();
   1198   }
   1199 
   1200   static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1201     CHECK_NON_NULL_ARGUMENT(CallShortMethodV, obj);
   1202     CHECK_NON_NULL_ARGUMENT(CallShortMethodV, mid);
   1203     ScopedObjectAccess soa(env);
   1204     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
   1205   }
   1206 
   1207   static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1208     CHECK_NON_NULL_ARGUMENT(CallShortMethodA, obj);
   1209     CHECK_NON_NULL_ARGUMENT(CallShortMethodA, mid);
   1210     ScopedObjectAccess soa(env);
   1211     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
   1212   }
   1213 
   1214   static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
   1215     va_list ap;
   1216     va_start(ap, mid);
   1217     CHECK_NON_NULL_ARGUMENT(CallVoidMethod, obj);
   1218     CHECK_NON_NULL_ARGUMENT(CallVoidMethod, mid);
   1219     ScopedObjectAccess soa(env);
   1220     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
   1221     va_end(ap);
   1222   }
   1223 
   1224   static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
   1225     CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, obj);
   1226     CHECK_NON_NULL_ARGUMENT(CallVoidMethodV, mid);
   1227     ScopedObjectAccess soa(env);
   1228     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
   1229   }
   1230 
   1231   static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
   1232     CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, obj);
   1233     CHECK_NON_NULL_ARGUMENT(CallVoidMethodA, mid);
   1234     ScopedObjectAccess soa(env);
   1235     InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
   1236   }
   1237 
   1238   static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1239     va_list ap;
   1240     va_start(ap, mid);
   1241     CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, obj);
   1242     CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethod, mid);
   1243     ScopedObjectAccess soa(env);
   1244     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1245     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
   1246     va_end(ap);
   1247     return local_result;
   1248   }
   1249 
   1250   static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1251                                              va_list args) {
   1252     CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, obj);
   1253     CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodV, mid);
   1254     ScopedObjectAccess soa(env);
   1255     JValue result(InvokeWithVarArgs(soa, obj, mid, args));
   1256     return soa.AddLocalReference<jobject>(result.GetL());
   1257   }
   1258 
   1259   static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1260                                              jvalue* args) {
   1261     CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, obj);
   1262     CHECK_NON_NULL_ARGUMENT(CallNonvirtualObjectMethodA, mid);
   1263     ScopedObjectAccess soa(env);
   1264     JValue result(InvokeWithJValues(soa, obj, mid, args));
   1265     return soa.AddLocalReference<jobject>(result.GetL());
   1266   }
   1267 
   1268   static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1269                                               ...) {
   1270     va_list ap;
   1271     va_start(ap, mid);
   1272     CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, obj);
   1273     CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethod, mid);
   1274     ScopedObjectAccess soa(env);
   1275     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1276     va_end(ap);
   1277     return result.GetZ();
   1278   }
   1279 
   1280   static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1281                                                va_list args) {
   1282     CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, obj);
   1283     CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodV, mid);
   1284     ScopedObjectAccess soa(env);
   1285     return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
   1286   }
   1287 
   1288   static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1289                                                jvalue* args) {
   1290     CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, obj);
   1291     CHECK_NON_NULL_ARGUMENT(CallNonvirtualBooleanMethodA, mid);
   1292     ScopedObjectAccess soa(env);
   1293     return InvokeWithJValues(soa, obj, mid, args).GetZ();
   1294   }
   1295 
   1296   static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1297     va_list ap;
   1298     va_start(ap, mid);
   1299     CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, obj);
   1300     CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethod, mid);
   1301     ScopedObjectAccess soa(env);
   1302     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1303     va_end(ap);
   1304     return result.GetB();
   1305   }
   1306 
   1307   static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1308                                          va_list args) {
   1309     CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, obj);
   1310     CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodV, mid);
   1311     ScopedObjectAccess soa(env);
   1312     return InvokeWithVarArgs(soa, obj, mid, args).GetB();
   1313   }
   1314 
   1315   static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1316                                          jvalue* args) {
   1317     CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, obj);
   1318     CHECK_NON_NULL_ARGUMENT(CallNonvirtualByteMethodA, mid);
   1319     ScopedObjectAccess soa(env);
   1320     return InvokeWithJValues(soa, obj, mid, args).GetB();
   1321   }
   1322 
   1323   static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1324     va_list ap;
   1325     va_start(ap, mid);
   1326     CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, obj);
   1327     CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethod, mid);
   1328     ScopedObjectAccess soa(env);
   1329     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1330     va_end(ap);
   1331     return result.GetC();
   1332   }
   1333 
   1334   static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1335                                          va_list args) {
   1336     CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, obj);
   1337     CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodV, mid);
   1338     ScopedObjectAccess soa(env);
   1339     return InvokeWithVarArgs(soa, obj, mid, args).GetC();
   1340   }
   1341 
   1342   static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1343                                          jvalue* args) {
   1344     CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, obj);
   1345     CHECK_NON_NULL_ARGUMENT(CallNonvirtualCharMethodA, mid);
   1346     ScopedObjectAccess soa(env);
   1347     return InvokeWithJValues(soa, obj, mid, args).GetC();
   1348   }
   1349 
   1350   static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1351     va_list ap;
   1352     va_start(ap, mid);
   1353     CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, obj);
   1354     CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethod, mid);
   1355     ScopedObjectAccess soa(env);
   1356     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1357     va_end(ap);
   1358     return result.GetS();
   1359   }
   1360 
   1361   static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1362                                            va_list args) {
   1363     CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, obj);
   1364     CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodV, mid);
   1365     ScopedObjectAccess soa(env);
   1366     return InvokeWithVarArgs(soa, obj, mid, args).GetS();
   1367   }
   1368 
   1369   static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1370                                            jvalue* args) {
   1371     CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, obj);
   1372     CHECK_NON_NULL_ARGUMENT(CallNonvirtualShortMethodA, mid);
   1373     ScopedObjectAccess soa(env);
   1374     return InvokeWithJValues(soa, obj, mid, args).GetS();
   1375   }
   1376 
   1377   static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1378     va_list ap;
   1379     va_start(ap, mid);
   1380     CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, obj);
   1381     CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethod, mid);
   1382     ScopedObjectAccess soa(env);
   1383     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1384     va_end(ap);
   1385     return result.GetI();
   1386   }
   1387 
   1388   static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1389                                        va_list args) {
   1390     CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, obj);
   1391     CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodV, mid);
   1392     ScopedObjectAccess soa(env);
   1393     return InvokeWithVarArgs(soa, obj, mid, args).GetI();
   1394   }
   1395 
   1396   static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1397                                        jvalue* args) {
   1398     CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, obj);
   1399     CHECK_NON_NULL_ARGUMENT(CallNonvirtualIntMethodA, mid);
   1400     ScopedObjectAccess soa(env);
   1401     return InvokeWithJValues(soa, obj, mid, args).GetI();
   1402   }
   1403 
   1404   static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1405     va_list ap;
   1406     va_start(ap, mid);
   1407     CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, obj);
   1408     CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethod, mid);
   1409     ScopedObjectAccess soa(env);
   1410     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1411     va_end(ap);
   1412     return result.GetJ();
   1413   }
   1414 
   1415   static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1416                                          va_list args) {
   1417     CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, obj);
   1418     CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodV, mid);
   1419     ScopedObjectAccess soa(env);
   1420     return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
   1421   }
   1422 
   1423   static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1424                                          jvalue* args) {
   1425     CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, obj);
   1426     CHECK_NON_NULL_ARGUMENT(CallNonvirtualLongMethodA, mid);
   1427     ScopedObjectAccess soa(env);
   1428     return InvokeWithJValues(soa, obj, mid, args).GetJ();
   1429   }
   1430 
   1431   static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1432     va_list ap;
   1433     va_start(ap, mid);
   1434     CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, obj);
   1435     CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethod, mid);
   1436     ScopedObjectAccess soa(env);
   1437     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1438     va_end(ap);
   1439     return result.GetF();
   1440   }
   1441 
   1442   static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1443                                            va_list args) {
   1444     CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, obj);
   1445     CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodV, mid);
   1446     ScopedObjectAccess soa(env);
   1447     return InvokeWithVarArgs(soa, obj, mid, args).GetF();
   1448   }
   1449 
   1450   static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1451                                            jvalue* args) {
   1452     CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, obj);
   1453     CHECK_NON_NULL_ARGUMENT(CallNonvirtualFloatMethodA, mid);
   1454     ScopedObjectAccess soa(env);
   1455     return InvokeWithJValues(soa, obj, mid, args).GetF();
   1456   }
   1457 
   1458   static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1459     va_list ap;
   1460     va_start(ap, mid);
   1461     CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, obj);
   1462     CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethod, mid);
   1463     ScopedObjectAccess soa(env);
   1464     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
   1465     va_end(ap);
   1466     return result.GetD();
   1467   }
   1468 
   1469   static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1470                                              va_list args) {
   1471     CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, obj);
   1472     CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodV, mid);
   1473     ScopedObjectAccess soa(env);
   1474     return InvokeWithVarArgs(soa, obj, mid, args).GetD();
   1475   }
   1476 
   1477   static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1478                                              jvalue* args) {
   1479     CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, obj);
   1480     CHECK_NON_NULL_ARGUMENT(CallNonvirtualDoubleMethodA, mid);
   1481     ScopedObjectAccess soa(env);
   1482     return InvokeWithJValues(soa, obj, mid, args).GetD();
   1483   }
   1484 
   1485   static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
   1486     va_list ap;
   1487     va_start(ap, mid);
   1488     CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, obj);
   1489     CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethod, mid);
   1490     ScopedObjectAccess soa(env);
   1491     InvokeWithVarArgs(soa, obj, mid, ap);
   1492     va_end(ap);
   1493   }
   1494 
   1495   static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1496                                         va_list args) {
   1497     CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, obj);
   1498     CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodV, mid);
   1499     ScopedObjectAccess soa(env);
   1500     InvokeWithVarArgs(soa, obj, mid, args);
   1501   }
   1502 
   1503   static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
   1504                                         jvalue* args) {
   1505     CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, obj);
   1506     CHECK_NON_NULL_ARGUMENT(CallNonvirtualVoidMethodA, mid);
   1507     ScopedObjectAccess soa(env);
   1508     InvokeWithJValues(soa, obj, mid, args);
   1509   }
   1510 
   1511   static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
   1512     CHECK_NON_NULL_ARGUMENT(GetFieldID, java_class);
   1513     CHECK_NON_NULL_ARGUMENT(GetFieldID, name);
   1514     CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
   1515     ScopedObjectAccess soa(env);
   1516     return FindFieldID(soa, java_class, name, sig, false);
   1517   }
   1518 
   1519   static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
   1520                                    const char* sig) {
   1521     CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, java_class);
   1522     CHECK_NON_NULL_ARGUMENT(GetStaticFieldID, name);
   1523     CHECK_NON_NULL_ARGUMENT(GetFieldID, sig);
   1524     ScopedObjectAccess soa(env);
   1525     return FindFieldID(soa, java_class, name, sig, true);
   1526   }
   1527 
   1528   static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
   1529     CHECK_NON_NULL_ARGUMENT(GetObjectField, obj);
   1530     CHECK_NON_NULL_ARGUMENT(GetObjectField, fid);
   1531     ScopedObjectAccess soa(env);
   1532     Object* o = soa.Decode<Object*>(obj);
   1533     ArtField* f = soa.DecodeField(fid);
   1534     return soa.AddLocalReference<jobject>(f->GetObject(o));
   1535   }
   1536 
   1537   static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
   1538     CHECK_NON_NULL_ARGUMENT(GetStaticObjectField, fid);
   1539     ScopedObjectAccess soa(env);
   1540     ArtField* f = soa.DecodeField(fid);
   1541     return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
   1542   }
   1543 
   1544   static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
   1545     CHECK_NON_NULL_ARGUMENT(SetObjectField, java_object);
   1546     CHECK_NON_NULL_ARGUMENT(SetObjectField, fid);
   1547     ScopedObjectAccess soa(env);
   1548     Object* o = soa.Decode<Object*>(java_object);
   1549     Object* v = soa.Decode<Object*>(java_value);
   1550     ArtField* f = soa.DecodeField(fid);
   1551     f->SetObject(o, v);
   1552   }
   1553 
   1554   static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
   1555     CHECK_NON_NULL_ARGUMENT(SetStaticObjectField, fid);
   1556     ScopedObjectAccess soa(env);
   1557     Object* v = soa.Decode<Object*>(java_value);
   1558     ArtField* f = soa.DecodeField(fid);
   1559     f->SetObject(f->GetDeclaringClass(), v);
   1560   }
   1561 
   1562 #define GET_PRIMITIVE_FIELD(fn, instance) \
   1563   CHECK_NON_NULL_ARGUMENT(Get #fn Field, instance); \
   1564   CHECK_NON_NULL_ARGUMENT(Get #fn Field, fid); \
   1565   ScopedObjectAccess soa(env); \
   1566   Object* o = soa.Decode<Object*>(instance); \
   1567   ArtField* f = soa.DecodeField(fid); \
   1568   return f->Get ##fn (o)
   1569 
   1570 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
   1571   CHECK_NON_NULL_ARGUMENT(GetStatic #fn Field, fid); \
   1572   ScopedObjectAccess soa(env); \
   1573   ArtField* f = soa.DecodeField(fid); \
   1574   return f->Get ##fn (f->GetDeclaringClass())
   1575 
   1576 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
   1577   CHECK_NON_NULL_ARGUMENT(Set #fn Field, instance); \
   1578   CHECK_NON_NULL_ARGUMENT(Set #fn Field, fid); \
   1579   ScopedObjectAccess soa(env); \
   1580   Object* o = soa.Decode<Object*>(instance); \
   1581   ArtField* f = soa.DecodeField(fid); \
   1582   f->Set ##fn(o, value)
   1583 
   1584 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
   1585   CHECK_NON_NULL_ARGUMENT(SetStatic #fn Field, fid); \
   1586   ScopedObjectAccess soa(env); \
   1587   ArtField* f = soa.DecodeField(fid); \
   1588   f->Set ##fn(f->GetDeclaringClass(), value)
   1589 
   1590   static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
   1591     GET_PRIMITIVE_FIELD(Boolean, obj);
   1592   }
   1593 
   1594   static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
   1595     GET_PRIMITIVE_FIELD(Byte, obj);
   1596   }
   1597 
   1598   static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
   1599     GET_PRIMITIVE_FIELD(Char, obj);
   1600   }
   1601 
   1602   static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
   1603     GET_PRIMITIVE_FIELD(Short, obj);
   1604   }
   1605 
   1606   static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
   1607     GET_PRIMITIVE_FIELD(Int, obj);
   1608   }
   1609 
   1610   static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
   1611     GET_PRIMITIVE_FIELD(Long, obj);
   1612   }
   1613 
   1614   static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
   1615     GET_PRIMITIVE_FIELD(Float, obj);
   1616   }
   1617 
   1618   static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
   1619     GET_PRIMITIVE_FIELD(Double, obj);
   1620   }
   1621 
   1622   static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
   1623     GET_STATIC_PRIMITIVE_FIELD(Boolean);
   1624   }
   1625 
   1626   static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
   1627     GET_STATIC_PRIMITIVE_FIELD(Byte);
   1628   }
   1629 
   1630   static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
   1631     GET_STATIC_PRIMITIVE_FIELD(Char);
   1632   }
   1633 
   1634   static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
   1635     GET_STATIC_PRIMITIVE_FIELD(Short);
   1636   }
   1637 
   1638   static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
   1639     GET_STATIC_PRIMITIVE_FIELD(Int);
   1640   }
   1641 
   1642   static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
   1643     GET_STATIC_PRIMITIVE_FIELD(Long);
   1644   }
   1645 
   1646   static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
   1647     GET_STATIC_PRIMITIVE_FIELD(Float);
   1648   }
   1649 
   1650   static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
   1651     GET_STATIC_PRIMITIVE_FIELD(Double);
   1652   }
   1653 
   1654   static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
   1655     SET_PRIMITIVE_FIELD(Boolean, obj, v);
   1656   }
   1657 
   1658   static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
   1659     SET_PRIMITIVE_FIELD(Byte, obj, v);
   1660   }
   1661 
   1662   static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
   1663     SET_PRIMITIVE_FIELD(Char, obj, v);
   1664   }
   1665 
   1666   static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
   1667     SET_PRIMITIVE_FIELD(Float, obj, v);
   1668   }
   1669 
   1670   static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
   1671     SET_PRIMITIVE_FIELD(Double, obj, v);
   1672   }
   1673 
   1674   static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
   1675     SET_PRIMITIVE_FIELD(Int, obj, v);
   1676   }
   1677 
   1678   static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
   1679     SET_PRIMITIVE_FIELD(Long, obj, v);
   1680   }
   1681 
   1682   static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
   1683     SET_PRIMITIVE_FIELD(Short, obj, v);
   1684   }
   1685 
   1686   static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
   1687     SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
   1688   }
   1689 
   1690   static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
   1691     SET_STATIC_PRIMITIVE_FIELD(Byte, v);
   1692   }
   1693 
   1694   static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
   1695     SET_STATIC_PRIMITIVE_FIELD(Char, v);
   1696   }
   1697 
   1698   static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
   1699     SET_STATIC_PRIMITIVE_FIELD(Float, v);
   1700   }
   1701 
   1702   static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
   1703     SET_STATIC_PRIMITIVE_FIELD(Double, v);
   1704   }
   1705 
   1706   static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
   1707     SET_STATIC_PRIMITIVE_FIELD(Int, v);
   1708   }
   1709 
   1710   static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
   1711     SET_STATIC_PRIMITIVE_FIELD(Long, v);
   1712   }
   1713 
   1714   static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
   1715     SET_STATIC_PRIMITIVE_FIELD(Short, v);
   1716   }
   1717 
   1718   static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1719     va_list ap;
   1720     va_start(ap, mid);
   1721     CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethod, mid);
   1722     ScopedObjectAccess soa(env);
   1723     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1724     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
   1725     va_end(ap);
   1726     return local_result;
   1727   }
   1728 
   1729   static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1730     CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodV, mid);
   1731     ScopedObjectAccess soa(env);
   1732     JValue result(InvokeWithVarArgs(soa, NULL, mid, args));
   1733     return soa.AddLocalReference<jobject>(result.GetL());
   1734   }
   1735 
   1736   static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1737     CHECK_NON_NULL_ARGUMENT(CallStaticObjectMethodA, mid);
   1738     ScopedObjectAccess soa(env);
   1739     JValue result(InvokeWithJValues(soa, NULL, mid, args));
   1740     return soa.AddLocalReference<jobject>(result.GetL());
   1741   }
   1742 
   1743   static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1744     va_list ap;
   1745     va_start(ap, mid);
   1746     CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethod, mid);
   1747     ScopedObjectAccess soa(env);
   1748     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1749     va_end(ap);
   1750     return result.GetZ();
   1751   }
   1752 
   1753   static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1754     CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodV, mid);
   1755     ScopedObjectAccess soa(env);
   1756     return InvokeWithVarArgs(soa, NULL, mid, args).GetZ();
   1757   }
   1758 
   1759   static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1760     CHECK_NON_NULL_ARGUMENT(CallStaticBooleanMethodA, mid);
   1761     ScopedObjectAccess soa(env);
   1762     return InvokeWithJValues(soa, NULL, mid, args).GetZ();
   1763   }
   1764 
   1765   static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1766     va_list ap;
   1767     va_start(ap, mid);
   1768     CHECK_NON_NULL_ARGUMENT(CallStaticByteMethod, mid);
   1769     ScopedObjectAccess soa(env);
   1770     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1771     va_end(ap);
   1772     return result.GetB();
   1773   }
   1774 
   1775   static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1776     CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodV, mid);
   1777     ScopedObjectAccess soa(env);
   1778     return InvokeWithVarArgs(soa, NULL, mid, args).GetB();
   1779   }
   1780 
   1781   static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1782     CHECK_NON_NULL_ARGUMENT(CallStaticByteMethodA, mid);
   1783     ScopedObjectAccess soa(env);
   1784     return InvokeWithJValues(soa, NULL, mid, args).GetB();
   1785   }
   1786 
   1787   static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1788     va_list ap;
   1789     va_start(ap, mid);
   1790     CHECK_NON_NULL_ARGUMENT(CallStaticCharMethod, mid);
   1791     ScopedObjectAccess soa(env);
   1792     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1793     va_end(ap);
   1794     return result.GetC();
   1795   }
   1796 
   1797   static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1798     CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodV, mid);
   1799     ScopedObjectAccess soa(env);
   1800     return InvokeWithVarArgs(soa, NULL, mid, args).GetC();
   1801   }
   1802 
   1803   static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1804     CHECK_NON_NULL_ARGUMENT(CallStaticCharMethodA, mid);
   1805     ScopedObjectAccess soa(env);
   1806     return InvokeWithJValues(soa, NULL, mid, args).GetC();
   1807   }
   1808 
   1809   static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1810     va_list ap;
   1811     va_start(ap, mid);
   1812     CHECK_NON_NULL_ARGUMENT(CallStaticShortMethod, mid);
   1813     ScopedObjectAccess soa(env);
   1814     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1815     va_end(ap);
   1816     return result.GetS();
   1817   }
   1818 
   1819   static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1820     CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodV, mid);
   1821     ScopedObjectAccess soa(env);
   1822     return InvokeWithVarArgs(soa, NULL, mid, args).GetS();
   1823   }
   1824 
   1825   static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1826     CHECK_NON_NULL_ARGUMENT(CallStaticShortMethodA, mid);
   1827     ScopedObjectAccess soa(env);
   1828     return InvokeWithJValues(soa, NULL, mid, args).GetS();
   1829   }
   1830 
   1831   static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1832     va_list ap;
   1833     va_start(ap, mid);
   1834     CHECK_NON_NULL_ARGUMENT(CallStaticIntMethod, mid);
   1835     ScopedObjectAccess soa(env);
   1836     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1837     va_end(ap);
   1838     return result.GetI();
   1839   }
   1840 
   1841   static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1842     CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodV, mid);
   1843     ScopedObjectAccess soa(env);
   1844     return InvokeWithVarArgs(soa, NULL, mid, args).GetI();
   1845   }
   1846 
   1847   static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1848     CHECK_NON_NULL_ARGUMENT(CallStaticIntMethodA, mid);
   1849     ScopedObjectAccess soa(env);
   1850     return InvokeWithJValues(soa, NULL, mid, args).GetI();
   1851   }
   1852 
   1853   static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1854     va_list ap;
   1855     va_start(ap, mid);
   1856     CHECK_NON_NULL_ARGUMENT(CallStaticLongMethod, mid);
   1857     ScopedObjectAccess soa(env);
   1858     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1859     va_end(ap);
   1860     return result.GetJ();
   1861   }
   1862 
   1863   static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1864     CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodV, mid);
   1865     ScopedObjectAccess soa(env);
   1866     return InvokeWithVarArgs(soa, NULL, mid, args).GetJ();
   1867   }
   1868 
   1869   static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1870     CHECK_NON_NULL_ARGUMENT(CallStaticLongMethodA, mid);
   1871     ScopedObjectAccess soa(env);
   1872     return InvokeWithJValues(soa, NULL, mid, args).GetJ();
   1873   }
   1874 
   1875   static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1876     va_list ap;
   1877     va_start(ap, mid);
   1878     CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethod, mid);
   1879     ScopedObjectAccess soa(env);
   1880     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1881     va_end(ap);
   1882     return result.GetF();
   1883   }
   1884 
   1885   static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1886     CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodV, mid);
   1887     ScopedObjectAccess soa(env);
   1888     return InvokeWithVarArgs(soa, NULL, mid, args).GetF();
   1889   }
   1890 
   1891   static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1892     CHECK_NON_NULL_ARGUMENT(CallStaticFloatMethodA, mid);
   1893     ScopedObjectAccess soa(env);
   1894     return InvokeWithJValues(soa, NULL, mid, args).GetF();
   1895   }
   1896 
   1897   static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1898     va_list ap;
   1899     va_start(ap, mid);
   1900     CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethod, mid);
   1901     ScopedObjectAccess soa(env);
   1902     JValue result(InvokeWithVarArgs(soa, NULL, mid, ap));
   1903     va_end(ap);
   1904     return result.GetD();
   1905   }
   1906 
   1907   static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1908     CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodV, mid);
   1909     ScopedObjectAccess soa(env);
   1910     return InvokeWithVarArgs(soa, NULL, mid, args).GetD();
   1911   }
   1912 
   1913   static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1914     CHECK_NON_NULL_ARGUMENT(CallStaticDoubleMethodA, mid);
   1915     ScopedObjectAccess soa(env);
   1916     return InvokeWithJValues(soa, NULL, mid, args).GetD();
   1917   }
   1918 
   1919   static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
   1920     va_list ap;
   1921     va_start(ap, mid);
   1922     CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethod, mid);
   1923     ScopedObjectAccess soa(env);
   1924     InvokeWithVarArgs(soa, NULL, mid, ap);
   1925     va_end(ap);
   1926   }
   1927 
   1928   static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
   1929     CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodV, mid);
   1930     ScopedObjectAccess soa(env);
   1931     InvokeWithVarArgs(soa, NULL, mid, args);
   1932   }
   1933 
   1934   static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
   1935     CHECK_NON_NULL_ARGUMENT(CallStaticVoidMethodA, mid);
   1936     ScopedObjectAccess soa(env);
   1937     InvokeWithJValues(soa, NULL, mid, args);
   1938   }
   1939 
   1940   static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
   1941     if (UNLIKELY(chars == NULL && char_count > 0)) { \
   1942       JniAbortF("NewString", "char == null && char_count > 0"); \
   1943     }
   1944     ScopedObjectAccess soa(env);
   1945     String* result = String::AllocFromUtf16(soa.Self(), char_count, chars);
   1946     return soa.AddLocalReference<jstring>(result);
   1947   }
   1948 
   1949   static jstring NewStringUTF(JNIEnv* env, const char* utf) {
   1950     if (utf == NULL) {
   1951       return NULL;
   1952     }
   1953     ScopedObjectAccess soa(env);
   1954     String* result = String::AllocFromModifiedUtf8(soa.Self(), utf);
   1955     return soa.AddLocalReference<jstring>(result);
   1956   }
   1957 
   1958   static jsize GetStringLength(JNIEnv* env, jstring java_string) {
   1959     CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
   1960     ScopedObjectAccess soa(env);
   1961     return soa.Decode<String*>(java_string)->GetLength();
   1962   }
   1963 
   1964   static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
   1965     CHECK_NON_NULL_ARGUMENT(GetStringLength, java_string);
   1966     ScopedObjectAccess soa(env);
   1967     return soa.Decode<String*>(java_string)->GetUtfLength();
   1968   }
   1969 
   1970   static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
   1971                               jchar* buf) {
   1972     CHECK_NON_NULL_ARGUMENT(GetStringRegion, java_string);
   1973     ScopedObjectAccess soa(env);
   1974     String* s = soa.Decode<String*>(java_string);
   1975     if (start < 0 || length < 0 || start + length > s->GetLength()) {
   1976       ThrowSIOOBE(soa, start, length, s->GetLength());
   1977     } else {
   1978       CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
   1979       const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
   1980       memcpy(buf, chars + start, length * sizeof(jchar));
   1981     }
   1982   }
   1983 
   1984   static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
   1985                                  char* buf) {
   1986     CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
   1987     ScopedObjectAccess soa(env);
   1988     String* s = soa.Decode<String*>(java_string);
   1989     if (start < 0 || length < 0 || start + length > s->GetLength()) {
   1990       ThrowSIOOBE(soa, start, length, s->GetLength());
   1991     } else {
   1992       CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringUTFRegion, length, buf);
   1993       const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
   1994       ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
   1995     }
   1996   }
   1997 
   1998   static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
   1999     CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
   2000     ScopedObjectAccess soa(env);
   2001     String* s = soa.Decode<String*>(java_string);
   2002     const CharArray* chars = s->GetCharArray();
   2003     PinPrimitiveArray(soa, chars);
   2004     if (is_copy != NULL) {
   2005       *is_copy = JNI_FALSE;
   2006     }
   2007     return chars->GetData() + s->GetOffset();
   2008   }
   2009 
   2010   static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar*) {
   2011     CHECK_NON_NULL_ARGUMENT(GetStringUTFRegion, java_string);
   2012     ScopedObjectAccess soa(env);
   2013     UnpinPrimitiveArray(soa, soa.Decode<String*>(java_string)->GetCharArray());
   2014   }
   2015 
   2016   static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
   2017     return GetStringChars(env, java_string, is_copy);
   2018   }
   2019 
   2020   static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
   2021     return ReleaseStringChars(env, java_string, chars);
   2022   }
   2023 
   2024   static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
   2025     if (java_string == NULL) {
   2026       return NULL;
   2027     }
   2028     if (is_copy != NULL) {
   2029       *is_copy = JNI_TRUE;
   2030     }
   2031     ScopedObjectAccess soa(env);
   2032     String* s = soa.Decode<String*>(java_string);
   2033     size_t byte_count = s->GetUtfLength();
   2034     char* bytes = new char[byte_count + 1];
   2035     CHECK(bytes != NULL);  // bionic aborts anyway.
   2036     const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
   2037     ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
   2038     bytes[byte_count] = '\0';
   2039     return bytes;
   2040   }
   2041 
   2042   static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
   2043     delete[] chars;
   2044   }
   2045 
   2046   static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
   2047     CHECK_NON_NULL_ARGUMENT(GetArrayLength, java_array);
   2048     ScopedObjectAccess soa(env);
   2049     Object* obj = soa.Decode<Object*>(java_array);
   2050     if (UNLIKELY(!obj->IsArrayInstance())) {
   2051       JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
   2052     }
   2053     Array* array = obj->AsArray();
   2054     return array->GetLength();
   2055   }
   2056 
   2057   static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
   2058     CHECK_NON_NULL_ARGUMENT(GetObjectArrayElement, java_array);
   2059     ScopedObjectAccess soa(env);
   2060     ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
   2061     return soa.AddLocalReference<jobject>(array->Get(index));
   2062   }
   2063 
   2064   static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
   2065                                     jobject java_value) {
   2066     CHECK_NON_NULL_ARGUMENT(SetObjectArrayElement, java_array);
   2067     ScopedObjectAccess soa(env);
   2068     ObjectArray<Object>* array = soa.Decode<ObjectArray<Object>*>(java_array);
   2069     Object* value = soa.Decode<Object*>(java_value);
   2070     array->Set(index, value);
   2071   }
   2072 
   2073   static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
   2074     ScopedObjectAccess soa(env);
   2075     return NewPrimitiveArray<jbooleanArray, BooleanArray>(soa, length);
   2076   }
   2077 
   2078   static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
   2079     ScopedObjectAccess soa(env);
   2080     return NewPrimitiveArray<jbyteArray, ByteArray>(soa, length);
   2081   }
   2082 
   2083   static jcharArray NewCharArray(JNIEnv* env, jsize length) {
   2084     ScopedObjectAccess soa(env);
   2085     return NewPrimitiveArray<jcharArray, CharArray>(soa, length);
   2086   }
   2087 
   2088   static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
   2089     ScopedObjectAccess soa(env);
   2090     return NewPrimitiveArray<jdoubleArray, DoubleArray>(soa, length);
   2091   }
   2092 
   2093   static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
   2094     ScopedObjectAccess soa(env);
   2095     return NewPrimitiveArray<jfloatArray, FloatArray>(soa, length);
   2096   }
   2097 
   2098   static jintArray NewIntArray(JNIEnv* env, jsize length) {
   2099     ScopedObjectAccess soa(env);
   2100     return NewPrimitiveArray<jintArray, IntArray>(soa, length);
   2101   }
   2102 
   2103   static jlongArray NewLongArray(JNIEnv* env, jsize length) {
   2104     ScopedObjectAccess soa(env);
   2105     return NewPrimitiveArray<jlongArray, LongArray>(soa, length);
   2106   }
   2107 
   2108   static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass, jobject initial_element) {
   2109     if (length < 0) {
   2110       JniAbortF("NewObjectArray", "negative array length: %d", length);
   2111     }
   2112 
   2113     // Compute the array class corresponding to the given element class.
   2114     ScopedObjectAccess soa(env);
   2115     Class* element_class = soa.Decode<Class*>(element_jclass);
   2116     std::string descriptor;
   2117     descriptor += "[";
   2118     descriptor += ClassHelper(element_class).GetDescriptor();
   2119 
   2120     // Find the class.
   2121     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   2122     Class* array_class = class_linker->FindClass(descriptor.c_str(),
   2123                                                  element_class->GetClassLoader());
   2124     if (array_class == NULL) {
   2125       return NULL;
   2126     }
   2127 
   2128     // Allocate and initialize if necessary.
   2129     ObjectArray<Object>* result = ObjectArray<Object>::Alloc(soa.Self(), array_class, length);
   2130     if (initial_element != NULL) {
   2131       Object* initial_object = soa.Decode<Object*>(initial_element);
   2132       for (jsize i = 0; i < length; ++i) {
   2133         result->Set(i, initial_object);
   2134       }
   2135     }
   2136     return soa.AddLocalReference<jobjectArray>(result);
   2137   }
   2138 
   2139   static jshortArray NewShortArray(JNIEnv* env, jsize length) {
   2140     ScopedObjectAccess soa(env);
   2141     return NewPrimitiveArray<jshortArray, ShortArray>(soa, length);
   2142   }
   2143 
   2144   static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
   2145     CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayCritical, java_array);
   2146     ScopedObjectAccess soa(env);
   2147     Array* array = soa.Decode<Array*>(java_array);
   2148     PinPrimitiveArray(soa, array);
   2149     if (is_copy != NULL) {
   2150       *is_copy = JNI_FALSE;
   2151     }
   2152     return array->GetRawData(array->GetClass()->GetComponentSize());
   2153   }
   2154 
   2155   static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array, void*, jint mode) {
   2156     CHECK_NON_NULL_ARGUMENT(ReleasePrimitiveArrayCritical, array);
   2157     ReleasePrimitiveArray(env, array, mode);
   2158   }
   2159 
   2160   static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
   2161     CHECK_NON_NULL_ARGUMENT(GetBooleanArrayElements, array);
   2162     ScopedObjectAccess soa(env);
   2163     return GetPrimitiveArray<jbooleanArray, jboolean*, BooleanArray>(soa, array, is_copy);
   2164   }
   2165 
   2166   static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
   2167     CHECK_NON_NULL_ARGUMENT(GetByteArrayElements, array);
   2168     ScopedObjectAccess soa(env);
   2169     return GetPrimitiveArray<jbyteArray, jbyte*, ByteArray>(soa, array, is_copy);
   2170   }
   2171 
   2172   static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
   2173     CHECK_NON_NULL_ARGUMENT(GetCharArrayElements, array);
   2174     ScopedObjectAccess soa(env);
   2175     return GetPrimitiveArray<jcharArray, jchar*, CharArray>(soa, array, is_copy);
   2176   }
   2177 
   2178   static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
   2179     CHECK_NON_NULL_ARGUMENT(GetDoubleArrayElements, array);
   2180     ScopedObjectAccess soa(env);
   2181     return GetPrimitiveArray<jdoubleArray, jdouble*, DoubleArray>(soa, array, is_copy);
   2182   }
   2183 
   2184   static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
   2185     CHECK_NON_NULL_ARGUMENT(GetFloatArrayElements, array);
   2186     ScopedObjectAccess soa(env);
   2187     return GetPrimitiveArray<jfloatArray, jfloat*, FloatArray>(soa, array, is_copy);
   2188   }
   2189 
   2190   static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
   2191     CHECK_NON_NULL_ARGUMENT(GetIntArrayElements, array);
   2192     ScopedObjectAccess soa(env);
   2193     return GetPrimitiveArray<jintArray, jint*, IntArray>(soa, array, is_copy);
   2194   }
   2195 
   2196   static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
   2197     CHECK_NON_NULL_ARGUMENT(GetLongArrayElements, array);
   2198     ScopedObjectAccess soa(env);
   2199     return GetPrimitiveArray<jlongArray, jlong*, LongArray>(soa, array, is_copy);
   2200   }
   2201 
   2202   static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
   2203     CHECK_NON_NULL_ARGUMENT(GetShortArrayElements, array);
   2204     ScopedObjectAccess soa(env);
   2205     return GetPrimitiveArray<jshortArray, jshort*, ShortArray>(soa, array, is_copy);
   2206   }
   2207 
   2208   static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean*, jint mode) {
   2209     ReleasePrimitiveArray(env, array, mode);
   2210   }
   2211 
   2212   static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte*, jint mode) {
   2213     ReleasePrimitiveArray(env, array, mode);
   2214   }
   2215 
   2216   static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar*, jint mode) {
   2217     ReleasePrimitiveArray(env, array, mode);
   2218   }
   2219 
   2220   static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble*, jint mode) {
   2221     ReleasePrimitiveArray(env, array, mode);
   2222   }
   2223 
   2224   static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat*, jint mode) {
   2225     ReleasePrimitiveArray(env, array, mode);
   2226   }
   2227 
   2228   static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint*, jint mode) {
   2229     ReleasePrimitiveArray(env, array, mode);
   2230   }
   2231 
   2232   static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong*, jint mode) {
   2233     ReleasePrimitiveArray(env, array, mode);
   2234   }
   2235 
   2236   static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort*, jint mode) {
   2237     ReleasePrimitiveArray(env, array, mode);
   2238   }
   2239 
   2240   static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
   2241                                     jboolean* buf) {
   2242     ScopedObjectAccess soa(env);
   2243     GetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
   2244   }
   2245 
   2246   static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
   2247                                  jbyte* buf) {
   2248     ScopedObjectAccess soa(env);
   2249     GetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
   2250   }
   2251 
   2252   static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
   2253                                  jchar* buf) {
   2254     ScopedObjectAccess soa(env);
   2255     GetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
   2256   }
   2257 
   2258   static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
   2259                                    jdouble* buf) {
   2260     ScopedObjectAccess soa(env);
   2261     GetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
   2262   }
   2263 
   2264   static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
   2265                                   jfloat* buf) {
   2266     ScopedObjectAccess soa(env);
   2267     GetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
   2268   }
   2269 
   2270   static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
   2271                                 jint* buf) {
   2272     ScopedObjectAccess soa(env);
   2273     GetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
   2274   }
   2275 
   2276   static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
   2277                                  jlong* buf) {
   2278     ScopedObjectAccess soa(env);
   2279     GetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
   2280   }
   2281 
   2282   static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
   2283                                   jshort* buf) {
   2284     ScopedObjectAccess soa(env);
   2285     GetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
   2286   }
   2287 
   2288   static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
   2289                                     const jboolean* buf) {
   2290     ScopedObjectAccess soa(env);
   2291     SetPrimitiveArrayRegion<jbooleanArray, jboolean, BooleanArray>(soa, array, start, length, buf);
   2292   }
   2293 
   2294   static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
   2295                                  const jbyte* buf) {
   2296     ScopedObjectAccess soa(env);
   2297     SetPrimitiveArrayRegion<jbyteArray, jbyte, ByteArray>(soa, array, start, length, buf);
   2298   }
   2299 
   2300   static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
   2301                                  const jchar* buf) {
   2302     ScopedObjectAccess soa(env);
   2303     SetPrimitiveArrayRegion<jcharArray, jchar, CharArray>(soa, array, start, length, buf);
   2304   }
   2305 
   2306   static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
   2307                                    const jdouble* buf) {
   2308     ScopedObjectAccess soa(env);
   2309     SetPrimitiveArrayRegion<jdoubleArray, jdouble, DoubleArray>(soa, array, start, length, buf);
   2310   }
   2311 
   2312   static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
   2313                                   const jfloat* buf) {
   2314     ScopedObjectAccess soa(env);
   2315     SetPrimitiveArrayRegion<jfloatArray, jfloat, FloatArray>(soa, array, start, length, buf);
   2316   }
   2317 
   2318   static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
   2319                                 const jint* buf) {
   2320     ScopedObjectAccess soa(env);
   2321     SetPrimitiveArrayRegion<jintArray, jint, IntArray>(soa, array, start, length, buf);
   2322   }
   2323 
   2324   static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
   2325                                  const jlong* buf) {
   2326     ScopedObjectAccess soa(env);
   2327     SetPrimitiveArrayRegion<jlongArray, jlong, LongArray>(soa, array, start, length, buf);
   2328   }
   2329 
   2330   static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
   2331                                   const jshort* buf) {
   2332     ScopedObjectAccess soa(env);
   2333     SetPrimitiveArrayRegion<jshortArray, jshort, ShortArray>(soa, array, start, length, buf);
   2334   }
   2335 
   2336   static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
   2337                               jint method_count) {
   2338     return RegisterNativeMethods(env, java_class, methods, method_count, true);
   2339   }
   2340 
   2341   static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
   2342                                     jint method_count, bool return_errors) {
   2343     if (UNLIKELY(method_count < 0)) {
   2344       JniAbortF("RegisterNatives", "negative method count: %d", method_count);
   2345       return JNI_ERR;  // Not reached.
   2346     }
   2347     CHECK_NON_NULL_ARGUMENT(RegisterNatives, java_class);
   2348     ScopedObjectAccess soa(env);
   2349     Class* c = soa.Decode<Class*>(java_class);
   2350     if (UNLIKELY(method_count == 0)) {
   2351       LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
   2352           << PrettyDescriptor(c);
   2353       return JNI_OK;
   2354     }
   2355     CHECK_NON_NULL_ARGUMENT(RegisterNatives, methods);
   2356     for (jint i = 0; i < method_count; ++i) {
   2357       const char* name = methods[i].name;
   2358       const char* sig = methods[i].signature;
   2359 
   2360       if (*sig == '!') {
   2361         // TODO: fast jni. it's too noisy to log all these.
   2362         ++sig;
   2363       }
   2364 
   2365       ArtMethod* m = c->FindDirectMethod(name, sig);
   2366       if (m == NULL) {
   2367         m = c->FindVirtualMethod(name, sig);
   2368       }
   2369       if (m == NULL) {
   2370         LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
   2371             << PrettyDescriptor(c) << "." << name << sig;
   2372         ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
   2373         return JNI_ERR;
   2374       } else if (!m->IsNative()) {
   2375         LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
   2376             << PrettyDescriptor(c) << "." << name << sig
   2377             << " as native";
   2378         ThrowNoSuchMethodError(soa, c, name, sig, "native");
   2379         return JNI_ERR;
   2380       }
   2381 
   2382       VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
   2383 
   2384       m->RegisterNative(soa.Self(), methods[i].fnPtr);
   2385     }
   2386     return JNI_OK;
   2387   }
   2388 
   2389   static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
   2390     CHECK_NON_NULL_ARGUMENT(UnregisterNatives, java_class);
   2391     ScopedObjectAccess soa(env);
   2392     Class* c = soa.Decode<Class*>(java_class);
   2393 
   2394     VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
   2395 
   2396     for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
   2397       ArtMethod* m = c->GetDirectMethod(i);
   2398       if (m->IsNative()) {
   2399         m->UnregisterNative(soa.Self());
   2400       }
   2401     }
   2402     for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
   2403       ArtMethod* m = c->GetVirtualMethod(i);
   2404       if (m->IsNative()) {
   2405         m->UnregisterNative(soa.Self());
   2406       }
   2407     }
   2408 
   2409     return JNI_OK;
   2410   }
   2411 
   2412   static jint MonitorEnter(JNIEnv* env, jobject java_object)
   2413       EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
   2414     CHECK_NON_NULL_ARGUMENT(MonitorEnter, java_object);
   2415     ScopedObjectAccess soa(env);
   2416     Object* o = soa.Decode<Object*>(java_object);
   2417     o->MonitorEnter(soa.Self());
   2418     if (soa.Self()->IsExceptionPending()) {
   2419       return JNI_ERR;
   2420     }
   2421     soa.Env()->monitors.Add(o);
   2422     return JNI_OK;
   2423   }
   2424 
   2425   static jint MonitorExit(JNIEnv* env, jobject java_object)
   2426       UNLOCK_FUNCTION(monitor_lock_) {
   2427     CHECK_NON_NULL_ARGUMENT(MonitorExit, java_object);
   2428     ScopedObjectAccess soa(env);
   2429     Object* o = soa.Decode<Object*>(java_object);
   2430     o->MonitorExit(soa.Self());
   2431     if (soa.Self()->IsExceptionPending()) {
   2432       return JNI_ERR;
   2433     }
   2434     soa.Env()->monitors.Remove(o);
   2435     return JNI_OK;
   2436   }
   2437 
   2438   static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
   2439     CHECK_NON_NULL_ARGUMENT(GetJavaVM, vm);
   2440     Runtime* runtime = Runtime::Current();
   2441     if (runtime != NULL) {
   2442       *vm = runtime->GetJavaVM();
   2443     } else {
   2444       *vm = NULL;
   2445     }
   2446     return (*vm != NULL) ? JNI_OK : JNI_ERR;
   2447   }
   2448 
   2449   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
   2450     if (capacity < 0) {
   2451       JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %lld", capacity);
   2452     }
   2453     if (address == NULL && capacity != 0) {
   2454       JniAbortF("NewDirectByteBuffer", "non-zero capacity for NULL pointer: %lld", capacity);
   2455     }
   2456 
   2457     // At the moment, the Java side is limited to 32 bits.
   2458     CHECK_LE(reinterpret_cast<uintptr_t>(address), 0xffffffff);
   2459     CHECK_LE(capacity, 0xffffffff);
   2460     jlong address_arg = reinterpret_cast<jlong>(address);
   2461     jint capacity_arg = static_cast<jint>(capacity);
   2462 
   2463     jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
   2464                                     WellKnownClasses::java_nio_DirectByteBuffer_init,
   2465                                     address_arg, capacity_arg);
   2466     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? NULL : result;
   2467   }
   2468 
   2469   static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
   2470     return reinterpret_cast<void*>(env->GetLongField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
   2471   }
   2472 
   2473   static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
   2474     return static_cast<jlong>(env->GetIntField(java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
   2475   }
   2476 
   2477   static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
   2478     CHECK_NON_NULL_ARGUMENT(GetObjectRefType, java_object);
   2479 
   2480     // Do we definitely know what kind of reference this is?
   2481     IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
   2482     IndirectRefKind kind = GetIndirectRefKind(ref);
   2483     switch (kind) {
   2484     case kLocal:
   2485       if (static_cast<JNIEnvExt*>(env)->locals.Get(ref) != kInvalidIndirectRefObject) {
   2486         return JNILocalRefType;
   2487       }
   2488       return JNIInvalidRefType;
   2489     case kGlobal:
   2490       return JNIGlobalRefType;
   2491     case kWeakGlobal:
   2492       return JNIWeakGlobalRefType;
   2493     case kSirtOrInvalid:
   2494       // Is it in a stack IRT?
   2495       if (static_cast<JNIEnvExt*>(env)->self->SirtContains(java_object)) {
   2496         return JNILocalRefType;
   2497       }
   2498 
   2499       if (!static_cast<JNIEnvExt*>(env)->vm->work_around_app_jni_bugs) {
   2500         return JNIInvalidRefType;
   2501       }
   2502 
   2503       // If we're handing out direct pointers, check whether it's a direct pointer
   2504       // to a local reference.
   2505       {
   2506         ScopedObjectAccess soa(env);
   2507         if (soa.Decode<Object*>(java_object) == reinterpret_cast<Object*>(java_object)) {
   2508           if (soa.Env()->locals.ContainsDirectPointer(reinterpret_cast<Object*>(java_object))) {
   2509             return JNILocalRefType;
   2510           }
   2511         }
   2512       }
   2513       return JNIInvalidRefType;
   2514     }
   2515     LOG(FATAL) << "IndirectRefKind[" << kind << "]";
   2516     return JNIInvalidRefType;
   2517   }
   2518 
   2519  private:
   2520   static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity,
   2521                                   const char* caller) {
   2522     // TODO: we should try to expand the table if necessary.
   2523     if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
   2524       LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
   2525       return JNI_ERR;
   2526     }
   2527     // TODO: this isn't quite right, since "capacity" includes holes.
   2528     size_t capacity = static_cast<JNIEnvExt*>(env)->locals.Capacity();
   2529     bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
   2530     if (!okay) {
   2531       ScopedObjectAccess soa(env);
   2532       soa.Self()->ThrowOutOfMemoryError(caller);
   2533     }
   2534     return okay ? JNI_OK : JNI_ERR;
   2535   }
   2536 
   2537   template<typename JniT, typename ArtT>
   2538   static JniT NewPrimitiveArray(const ScopedObjectAccess& soa, jsize length)
   2539       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   2540     if (length < 0) {
   2541       JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
   2542     }
   2543     ArtT* result = ArtT::Alloc(soa.Self(), length);
   2544     return soa.AddLocalReference<JniT>(result);
   2545   }
   2546 
   2547   template <typename ArrayT, typename CArrayT, typename ArtArrayT>
   2548   static CArrayT GetPrimitiveArray(ScopedObjectAccess& soa, ArrayT java_array,
   2549                                    jboolean* is_copy)
   2550       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   2551     ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
   2552     PinPrimitiveArray(soa, array);
   2553     if (is_copy != NULL) {
   2554       *is_copy = JNI_FALSE;
   2555     }
   2556     return array->GetData();
   2557   }
   2558 
   2559   template <typename ArrayT>
   2560   static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, jint mode) {
   2561     if (mode != JNI_COMMIT) {
   2562       ScopedObjectAccess soa(env);
   2563       Array* array = soa.Decode<Array*>(java_array);
   2564       UnpinPrimitiveArray(soa, array);
   2565     }
   2566   }
   2567 
   2568   template <typename JavaArrayT, typename JavaT, typename ArrayT>
   2569   static void GetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
   2570                                       jsize start, jsize length, JavaT* buf)
   2571       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   2572     CHECK_NON_NULL_ARGUMENT(GetPrimitiveArrayRegion, java_array);
   2573     ArrayT* array = soa.Decode<ArrayT*>(java_array);
   2574     if (start < 0 || length < 0 || start + length > array->GetLength()) {
   2575       ThrowAIOOBE(soa, array, start, length, "src");
   2576     } else {
   2577       CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
   2578       JavaT* data = array->GetData();
   2579       memcpy(buf, data + start, length * sizeof(JavaT));
   2580     }
   2581   }
   2582 
   2583   template <typename JavaArrayT, typename JavaT, typename ArrayT>
   2584   static void SetPrimitiveArrayRegion(ScopedObjectAccess& soa, JavaArrayT java_array,
   2585                                       jsize start, jsize length, const JavaT* buf)
   2586       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   2587     CHECK_NON_NULL_ARGUMENT(SetPrimitiveArrayRegion, java_array);
   2588     ArrayT* array = soa.Decode<ArrayT*>(java_array);
   2589     if (start < 0 || length < 0 || start + length > array->GetLength()) {
   2590       ThrowAIOOBE(soa, array, start, length, "dst");
   2591     } else {
   2592       CHECK_NON_NULL_MEMCPY_ARGUMENT(GetStringRegion, length, buf);
   2593       JavaT* data = array->GetData();
   2594       memcpy(data + start, buf, length * sizeof(JavaT));
   2595     }
   2596   }
   2597 };
   2598 
   2599 const JNINativeInterface gJniNativeInterface = {
   2600   NULL,  // reserved0.
   2601   NULL,  // reserved1.
   2602   NULL,  // reserved2.
   2603   NULL,  // reserved3.
   2604   JNI::GetVersion,
   2605   JNI::DefineClass,
   2606   JNI::FindClass,
   2607   JNI::FromReflectedMethod,
   2608   JNI::FromReflectedField,
   2609   JNI::ToReflectedMethod,
   2610   JNI::GetSuperclass,
   2611   JNI::IsAssignableFrom,
   2612   JNI::ToReflectedField,
   2613   JNI::Throw,
   2614   JNI::ThrowNew,
   2615   JNI::ExceptionOccurred,
   2616   JNI::ExceptionDescribe,
   2617   JNI::ExceptionClear,
   2618   JNI::FatalError,
   2619   JNI::PushLocalFrame,
   2620   JNI::PopLocalFrame,
   2621   JNI::NewGlobalRef,
   2622   JNI::DeleteGlobalRef,
   2623   JNI::DeleteLocalRef,
   2624   JNI::IsSameObject,
   2625   JNI::NewLocalRef,
   2626   JNI::EnsureLocalCapacity,
   2627   JNI::AllocObject,
   2628   JNI::NewObject,
   2629   JNI::NewObjectV,
   2630   JNI::NewObjectA,
   2631   JNI::GetObjectClass,
   2632   JNI::IsInstanceOf,
   2633   JNI::GetMethodID,
   2634   JNI::CallObjectMethod,
   2635   JNI::CallObjectMethodV,
   2636   JNI::CallObjectMethodA,
   2637   JNI::CallBooleanMethod,
   2638   JNI::CallBooleanMethodV,
   2639   JNI::CallBooleanMethodA,
   2640   JNI::CallByteMethod,
   2641   JNI::CallByteMethodV,
   2642   JNI::CallByteMethodA,
   2643   JNI::CallCharMethod,
   2644   JNI::CallCharMethodV,
   2645   JNI::CallCharMethodA,
   2646   JNI::CallShortMethod,
   2647   JNI::CallShortMethodV,
   2648   JNI::CallShortMethodA,
   2649   JNI::CallIntMethod,
   2650   JNI::CallIntMethodV,
   2651   JNI::CallIntMethodA,
   2652   JNI::CallLongMethod,
   2653   JNI::CallLongMethodV,
   2654   JNI::CallLongMethodA,
   2655   JNI::CallFloatMethod,
   2656   JNI::CallFloatMethodV,
   2657   JNI::CallFloatMethodA,
   2658   JNI::CallDoubleMethod,
   2659   JNI::CallDoubleMethodV,
   2660   JNI::CallDoubleMethodA,
   2661   JNI::CallVoidMethod,
   2662   JNI::CallVoidMethodV,
   2663   JNI::CallVoidMethodA,
   2664   JNI::CallNonvirtualObjectMethod,
   2665   JNI::CallNonvirtualObjectMethodV,
   2666   JNI::CallNonvirtualObjectMethodA,
   2667   JNI::CallNonvirtualBooleanMethod,
   2668   JNI::CallNonvirtualBooleanMethodV,
   2669   JNI::CallNonvirtualBooleanMethodA,
   2670   JNI::CallNonvirtualByteMethod,
   2671   JNI::CallNonvirtualByteMethodV,
   2672   JNI::CallNonvirtualByteMethodA,
   2673   JNI::CallNonvirtualCharMethod,
   2674   JNI::CallNonvirtualCharMethodV,
   2675   JNI::CallNonvirtualCharMethodA,
   2676   JNI::CallNonvirtualShortMethod,
   2677   JNI::CallNonvirtualShortMethodV,
   2678   JNI::CallNonvirtualShortMethodA,
   2679   JNI::CallNonvirtualIntMethod,
   2680   JNI::CallNonvirtualIntMethodV,
   2681   JNI::CallNonvirtualIntMethodA,
   2682   JNI::CallNonvirtualLongMethod,
   2683   JNI::CallNonvirtualLongMethodV,
   2684   JNI::CallNonvirtualLongMethodA,
   2685   JNI::CallNonvirtualFloatMethod,
   2686   JNI::CallNonvirtualFloatMethodV,
   2687   JNI::CallNonvirtualFloatMethodA,
   2688   JNI::CallNonvirtualDoubleMethod,
   2689   JNI::CallNonvirtualDoubleMethodV,
   2690   JNI::CallNonvirtualDoubleMethodA,
   2691   JNI::CallNonvirtualVoidMethod,
   2692   JNI::CallNonvirtualVoidMethodV,
   2693   JNI::CallNonvirtualVoidMethodA,
   2694   JNI::GetFieldID,
   2695   JNI::GetObjectField,
   2696   JNI::GetBooleanField,
   2697   JNI::GetByteField,
   2698   JNI::GetCharField,
   2699   JNI::GetShortField,
   2700   JNI::GetIntField,
   2701   JNI::GetLongField,
   2702   JNI::GetFloatField,
   2703   JNI::GetDoubleField,
   2704   JNI::SetObjectField,
   2705   JNI::SetBooleanField,
   2706   JNI::SetByteField,
   2707   JNI::SetCharField,
   2708   JNI::SetShortField,
   2709   JNI::SetIntField,
   2710   JNI::SetLongField,
   2711   JNI::SetFloatField,
   2712   JNI::SetDoubleField,
   2713   JNI::GetStaticMethodID,
   2714   JNI::CallStaticObjectMethod,
   2715   JNI::CallStaticObjectMethodV,
   2716   JNI::CallStaticObjectMethodA,
   2717   JNI::CallStaticBooleanMethod,
   2718   JNI::CallStaticBooleanMethodV,
   2719   JNI::CallStaticBooleanMethodA,
   2720   JNI::CallStaticByteMethod,
   2721   JNI::CallStaticByteMethodV,
   2722   JNI::CallStaticByteMethodA,
   2723   JNI::CallStaticCharMethod,
   2724   JNI::CallStaticCharMethodV,
   2725   JNI::CallStaticCharMethodA,
   2726   JNI::CallStaticShortMethod,
   2727   JNI::CallStaticShortMethodV,
   2728   JNI::CallStaticShortMethodA,
   2729   JNI::CallStaticIntMethod,
   2730   JNI::CallStaticIntMethodV,
   2731   JNI::CallStaticIntMethodA,
   2732   JNI::CallStaticLongMethod,
   2733   JNI::CallStaticLongMethodV,
   2734   JNI::CallStaticLongMethodA,
   2735   JNI::CallStaticFloatMethod,
   2736   JNI::CallStaticFloatMethodV,
   2737   JNI::CallStaticFloatMethodA,
   2738   JNI::CallStaticDoubleMethod,
   2739   JNI::CallStaticDoubleMethodV,
   2740   JNI::CallStaticDoubleMethodA,
   2741   JNI::CallStaticVoidMethod,
   2742   JNI::CallStaticVoidMethodV,
   2743   JNI::CallStaticVoidMethodA,
   2744   JNI::GetStaticFieldID,
   2745   JNI::GetStaticObjectField,
   2746   JNI::GetStaticBooleanField,
   2747   JNI::GetStaticByteField,
   2748   JNI::GetStaticCharField,
   2749   JNI::GetStaticShortField,
   2750   JNI::GetStaticIntField,
   2751   JNI::GetStaticLongField,
   2752   JNI::GetStaticFloatField,
   2753   JNI::GetStaticDoubleField,
   2754   JNI::SetStaticObjectField,
   2755   JNI::SetStaticBooleanField,
   2756   JNI::SetStaticByteField,
   2757   JNI::SetStaticCharField,
   2758   JNI::SetStaticShortField,
   2759   JNI::SetStaticIntField,
   2760   JNI::SetStaticLongField,
   2761   JNI::SetStaticFloatField,
   2762   JNI::SetStaticDoubleField,
   2763   JNI::NewString,
   2764   JNI::GetStringLength,
   2765   JNI::GetStringChars,
   2766   JNI::ReleaseStringChars,
   2767   JNI::NewStringUTF,
   2768   JNI::GetStringUTFLength,
   2769   JNI::GetStringUTFChars,
   2770   JNI::ReleaseStringUTFChars,
   2771   JNI::GetArrayLength,
   2772   JNI::NewObjectArray,
   2773   JNI::GetObjectArrayElement,
   2774   JNI::SetObjectArrayElement,
   2775   JNI::NewBooleanArray,
   2776   JNI::NewByteArray,
   2777   JNI::NewCharArray,
   2778   JNI::NewShortArray,
   2779   JNI::NewIntArray,
   2780   JNI::NewLongArray,
   2781   JNI::NewFloatArray,
   2782   JNI::NewDoubleArray,
   2783   JNI::GetBooleanArrayElements,
   2784   JNI::GetByteArrayElements,
   2785   JNI::GetCharArrayElements,
   2786   JNI::GetShortArrayElements,
   2787   JNI::GetIntArrayElements,
   2788   JNI::GetLongArrayElements,
   2789   JNI::GetFloatArrayElements,
   2790   JNI::GetDoubleArrayElements,
   2791   JNI::ReleaseBooleanArrayElements,
   2792   JNI::ReleaseByteArrayElements,
   2793   JNI::ReleaseCharArrayElements,
   2794   JNI::ReleaseShortArrayElements,
   2795   JNI::ReleaseIntArrayElements,
   2796   JNI::ReleaseLongArrayElements,
   2797   JNI::ReleaseFloatArrayElements,
   2798   JNI::ReleaseDoubleArrayElements,
   2799   JNI::GetBooleanArrayRegion,
   2800   JNI::GetByteArrayRegion,
   2801   JNI::GetCharArrayRegion,
   2802   JNI::GetShortArrayRegion,
   2803   JNI::GetIntArrayRegion,
   2804   JNI::GetLongArrayRegion,
   2805   JNI::GetFloatArrayRegion,
   2806   JNI::GetDoubleArrayRegion,
   2807   JNI::SetBooleanArrayRegion,
   2808   JNI::SetByteArrayRegion,
   2809   JNI::SetCharArrayRegion,
   2810   JNI::SetShortArrayRegion,
   2811   JNI::SetIntArrayRegion,
   2812   JNI::SetLongArrayRegion,
   2813   JNI::SetFloatArrayRegion,
   2814   JNI::SetDoubleArrayRegion,
   2815   JNI::RegisterNatives,
   2816   JNI::UnregisterNatives,
   2817   JNI::MonitorEnter,
   2818   JNI::MonitorExit,
   2819   JNI::GetJavaVM,
   2820   JNI::GetStringRegion,
   2821   JNI::GetStringUTFRegion,
   2822   JNI::GetPrimitiveArrayCritical,
   2823   JNI::ReleasePrimitiveArrayCritical,
   2824   JNI::GetStringCritical,
   2825   JNI::ReleaseStringCritical,
   2826   JNI::NewWeakGlobalRef,
   2827   JNI::DeleteWeakGlobalRef,
   2828   JNI::ExceptionCheck,
   2829   JNI::NewDirectByteBuffer,
   2830   JNI::GetDirectBufferAddress,
   2831   JNI::GetDirectBufferCapacity,
   2832   JNI::GetObjectRefType,
   2833 };
   2834 
   2835 JNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
   2836     : self(self),
   2837       vm(vm),
   2838       local_ref_cookie(IRT_FIRST_SEGMENT),
   2839       locals(kLocalsInitial, kLocalsMax, kLocal),
   2840       check_jni(false),
   2841       critical(false),
   2842       monitors("monitors", kMonitorsInitial, kMonitorsMax) {
   2843   functions = unchecked_functions = &gJniNativeInterface;
   2844   if (vm->check_jni) {
   2845     SetCheckJniEnabled(true);
   2846   }
   2847   // The JniEnv local reference values must be at a consistent offset or else cross-compilation
   2848   // errors will ensue.
   2849   CHECK_EQ(JNIEnvExt::LocalRefCookieOffset().Int32Value(), 12);
   2850   CHECK_EQ(JNIEnvExt::SegmentStateOffset().Int32Value(), 16);
   2851 }
   2852 
   2853 JNIEnvExt::~JNIEnvExt() {
   2854 }
   2855 
   2856 void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
   2857   check_jni = enabled;
   2858   functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
   2859 }
   2860 
   2861 void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
   2862   locals.Dump(os);
   2863   monitors.Dump(os);
   2864 }
   2865 
   2866 void JNIEnvExt::PushFrame(int /*capacity*/) {
   2867   // TODO: take 'capacity' into account.
   2868   stacked_local_ref_cookies.push_back(local_ref_cookie);
   2869   local_ref_cookie = locals.GetSegmentState();
   2870 }
   2871 
   2872 void JNIEnvExt::PopFrame() {
   2873   locals.SetSegmentState(local_ref_cookie);
   2874   local_ref_cookie = stacked_local_ref_cookies.back();
   2875   stacked_local_ref_cookies.pop_back();
   2876 }
   2877 
   2878 Offset JNIEnvExt::SegmentStateOffset() {
   2879   return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
   2880                 IndirectReferenceTable::SegmentStateOffset().Int32Value());
   2881 }
   2882 
   2883 // JNI Invocation interface.
   2884 
   2885 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
   2886   const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
   2887   if (IsBadJniVersion(args->version)) {
   2888     LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
   2889     return JNI_EVERSION;
   2890   }
   2891   Runtime::Options options;
   2892   for (int i = 0; i < args->nOptions; ++i) {
   2893     JavaVMOption* option = &args->options[i];
   2894     options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
   2895   }
   2896   bool ignore_unrecognized = args->ignoreUnrecognized;
   2897   if (!Runtime::Create(options, ignore_unrecognized)) {
   2898     return JNI_ERR;
   2899   }
   2900   Runtime* runtime = Runtime::Current();
   2901   bool started = runtime->Start();
   2902   if (!started) {
   2903     delete Thread::Current()->GetJniEnv();
   2904     delete runtime->GetJavaVM();
   2905     LOG(WARNING) << "CreateJavaVM failed";
   2906     return JNI_ERR;
   2907   }
   2908   *p_env = Thread::Current()->GetJniEnv();
   2909   *p_vm = runtime->GetJavaVM();
   2910   return JNI_OK;
   2911 }
   2912 
   2913 extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
   2914   Runtime* runtime = Runtime::Current();
   2915   if (runtime == NULL) {
   2916     *vm_count = 0;
   2917   } else {
   2918     *vm_count = 1;
   2919     vms[0] = runtime->GetJavaVM();
   2920   }
   2921   return JNI_OK;
   2922 }
   2923 
   2924 // Historically unsupported.
   2925 extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
   2926   return JNI_ERR;
   2927 }
   2928 
   2929 class JII {
   2930  public:
   2931   static jint DestroyJavaVM(JavaVM* vm) {
   2932     if (vm == NULL) {
   2933       return JNI_ERR;
   2934     }
   2935     JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
   2936     delete raw_vm->runtime;
   2937     return JNI_OK;
   2938   }
   2939 
   2940   static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
   2941     return JII_AttachCurrentThread(vm, p_env, thr_args, false);
   2942   }
   2943 
   2944   static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
   2945     return JII_AttachCurrentThread(vm, p_env, thr_args, true);
   2946   }
   2947 
   2948   static jint DetachCurrentThread(JavaVM* vm) {
   2949     if (vm == NULL || Thread::Current() == NULL) {
   2950       return JNI_ERR;
   2951     }
   2952     JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
   2953     Runtime* runtime = raw_vm->runtime;
   2954     runtime->DetachCurrentThread();
   2955     return JNI_OK;
   2956   }
   2957 
   2958   static jint GetEnv(JavaVM* vm, void** env, jint version) {
   2959     // GetEnv always returns a JNIEnv* for the most current supported JNI version,
   2960     // and unlike other calls that take a JNI version doesn't care if you supply
   2961     // JNI_VERSION_1_1, which we don't otherwise support.
   2962     if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) {
   2963       LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
   2964       return JNI_EVERSION;
   2965     }
   2966     if (vm == NULL || env == NULL) {
   2967       return JNI_ERR;
   2968     }
   2969     Thread* thread = Thread::Current();
   2970     if (thread == NULL) {
   2971       *env = NULL;
   2972       return JNI_EDETACHED;
   2973     }
   2974     *env = thread->GetJniEnv();
   2975     return JNI_OK;
   2976   }
   2977 };
   2978 
   2979 const JNIInvokeInterface gJniInvokeInterface = {
   2980   NULL,  // reserved0
   2981   NULL,  // reserved1
   2982   NULL,  // reserved2
   2983   JII::DestroyJavaVM,
   2984   JII::AttachCurrentThread,
   2985   JII::DetachCurrentThread,
   2986   JII::GetEnv,
   2987   JII::AttachCurrentThreadAsDaemon
   2988 };
   2989 
   2990 JavaVMExt::JavaVMExt(Runtime* runtime, Runtime::ParsedOptions* options)
   2991     : runtime(runtime),
   2992       check_jni_abort_hook(NULL),
   2993       check_jni_abort_hook_data(NULL),
   2994       check_jni(false),
   2995       force_copy(false),  // TODO: add a way to enable this
   2996       trace(options->jni_trace_),
   2997       work_around_app_jni_bugs(false),
   2998       pins_lock("JNI pin table lock", kPinTableLock),
   2999       pin_table("pin table", kPinTableInitial, kPinTableMax),
   3000       globals_lock("JNI global reference table lock"),
   3001       globals(gGlobalsInitial, gGlobalsMax, kGlobal),
   3002       libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
   3003       libraries(new Libraries),
   3004       weak_globals_lock_("JNI weak global reference table lock"),
   3005       weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
   3006       allow_new_weak_globals_(true),
   3007       weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) {
   3008   functions = unchecked_functions = &gJniInvokeInterface;
   3009   if (options->check_jni_) {
   3010     SetCheckJniEnabled(true);
   3011   }
   3012 }
   3013 
   3014 JavaVMExt::~JavaVMExt() {
   3015   delete libraries;
   3016 }
   3017 
   3018 jweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) {
   3019   if (obj == nullptr) {
   3020     return nullptr;
   3021   }
   3022   MutexLock mu(self, weak_globals_lock_);
   3023   while (UNLIKELY(!allow_new_weak_globals_)) {
   3024     weak_globals_add_condition_.WaitHoldingLocks(self);
   3025   }
   3026   IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj);
   3027   return reinterpret_cast<jweak>(ref);
   3028 }
   3029 
   3030 void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
   3031   MutexLock mu(self, weak_globals_lock_);
   3032   if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) {
   3033     LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
   3034                  << "failed to find entry";
   3035   }
   3036 }
   3037 
   3038 void JavaVMExt::SetCheckJniEnabled(bool enabled) {
   3039   check_jni = enabled;
   3040   functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
   3041 }
   3042 
   3043 void JavaVMExt::DumpForSigQuit(std::ostream& os) {
   3044   os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
   3045   if (force_copy) {
   3046     os << " (with forcecopy)";
   3047   }
   3048   os << "; workarounds are " << (work_around_app_jni_bugs ? "on" : "off");
   3049   Thread* self = Thread::Current();
   3050   {
   3051     MutexLock mu(self, pins_lock);
   3052     os << "; pins=" << pin_table.Size();
   3053   }
   3054   {
   3055     ReaderMutexLock mu(self, globals_lock);
   3056     os << "; globals=" << globals.Capacity();
   3057   }
   3058   {
   3059     MutexLock mu(self, weak_globals_lock_);
   3060     if (weak_globals_.Capacity() > 0) {
   3061       os << " (plus " << weak_globals_.Capacity() << " weak)";
   3062     }
   3063   }
   3064   os << '\n';
   3065 
   3066   {
   3067     MutexLock mu(self, libraries_lock);
   3068     os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
   3069   }
   3070 }
   3071 
   3072 void JavaVMExt::DisallowNewWeakGlobals() {
   3073   MutexLock mu(Thread::Current(), weak_globals_lock_);
   3074   allow_new_weak_globals_ = false;
   3075 }
   3076 
   3077 void JavaVMExt::AllowNewWeakGlobals() {
   3078   Thread* self = Thread::Current();
   3079   MutexLock mu(self, weak_globals_lock_);
   3080   allow_new_weak_globals_ = true;
   3081   weak_globals_add_condition_.Broadcast(self);
   3082 }
   3083 
   3084 void JavaVMExt::SweepWeakGlobals(IsMarkedTester is_marked, void* arg) {
   3085   MutexLock mu(Thread::Current(), weak_globals_lock_);
   3086   for (const Object** entry : weak_globals_) {
   3087     if (!is_marked(*entry, arg)) {
   3088       *entry = kClearedJniWeakGlobal;
   3089     }
   3090   }
   3091 }
   3092 
   3093 mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
   3094   MutexLock mu(self, weak_globals_lock_);
   3095   while (UNLIKELY(!allow_new_weak_globals_)) {
   3096     weak_globals_add_condition_.WaitHoldingLocks(self);
   3097   }
   3098   return const_cast<mirror::Object*>(weak_globals_.Get(ref));
   3099 }
   3100 
   3101 void JavaVMExt::DumpReferenceTables(std::ostream& os) {
   3102   Thread* self = Thread::Current();
   3103   {
   3104     ReaderMutexLock mu(self, globals_lock);
   3105     globals.Dump(os);
   3106   }
   3107   {
   3108     MutexLock mu(self, weak_globals_lock_);
   3109     weak_globals_.Dump(os);
   3110   }
   3111   {
   3112     MutexLock mu(self, pins_lock);
   3113     pin_table.Dump(os);
   3114   }
   3115 }
   3116 
   3117 bool JavaVMExt::LoadNativeLibrary(const std::string& path, ClassLoader* class_loader,
   3118                                   std::string& detail) {
   3119   detail.clear();
   3120 
   3121   // See if we've already loaded this library.  If we have, and the class loader
   3122   // matches, return successfully without doing anything.
   3123   // TODO: for better results we should canonicalize the pathname (or even compare
   3124   // inodes). This implementation is fine if everybody is using System.loadLibrary.
   3125   SharedLibrary* library;
   3126   Thread* self = Thread::Current();
   3127   {
   3128     // TODO: move the locking (and more of this logic) into Libraries.
   3129     MutexLock mu(self, libraries_lock);
   3130     library = libraries->Get(path);
   3131   }
   3132   if (library != NULL) {
   3133     if (library->GetClassLoader() != class_loader) {
   3134       // The library will be associated with class_loader. The JNI
   3135       // spec says we can't load the same library into more than one
   3136       // class loader.
   3137       StringAppendF(&detail, "Shared library \"%s\" already opened by "
   3138           "ClassLoader %p; can't open in ClassLoader %p",
   3139           path.c_str(), library->GetClassLoader(), class_loader);
   3140       LOG(WARNING) << detail;
   3141       return false;
   3142     }
   3143     VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
   3144               << "ClassLoader " << class_loader << "]";
   3145     if (!library->CheckOnLoadResult()) {
   3146       StringAppendF(&detail, "JNI_OnLoad failed on a previous attempt "
   3147           "to load \"%s\"", path.c_str());
   3148       return false;
   3149     }
   3150     return true;
   3151   }
   3152 
   3153   // Open the shared library.  Because we're using a full path, the system
   3154   // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
   3155   // resolve this library's dependencies though.)
   3156 
   3157   // Failures here are expected when java.library.path has several entries
   3158   // and we have to hunt for the lib.
   3159 
   3160   // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
   3161   // class unloading. Libraries will only be unloaded when the reference count (incremented by
   3162   // dlopen) becomes zero from dlclose.
   3163 
   3164   // This can execute slowly for a large library on a busy system, so we
   3165   // want to switch from kRunnable while it executes.  This allows the GC to ignore us.
   3166   self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
   3167   void* handle = dlopen(path.empty() ? NULL : path.c_str(), RTLD_LAZY);
   3168   self->TransitionFromSuspendedToRunnable();
   3169 
   3170   VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";
   3171 
   3172   if (handle == NULL) {
   3173     detail = dlerror();
   3174     LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << detail;
   3175     return false;
   3176   }
   3177 
   3178   // Create a new entry.
   3179   // TODO: move the locking (and more of this logic) into Libraries.
   3180   bool created_library = false;
   3181   {
   3182     MutexLock mu(self, libraries_lock);
   3183     library = libraries->Get(path);
   3184     if (library == NULL) {  // We won race to get libraries_lock
   3185       library = new SharedLibrary(path, handle, class_loader);
   3186       libraries->Put(path, library);
   3187       created_library = true;
   3188     }
   3189   }
   3190   if (!created_library) {
   3191     LOG(INFO) << "WOW: we lost a race to add shared library: "
   3192         << "\"" << path << "\" ClassLoader=" << class_loader;
   3193     return library->CheckOnLoadResult();
   3194   }
   3195 
   3196   VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader << "]";
   3197 
   3198   bool was_successful = false;
   3199   void* sym = dlsym(handle, "JNI_OnLoad");
   3200   if (sym == NULL) {
   3201     VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
   3202     was_successful = true;
   3203   } else {
   3204     // Call JNI_OnLoad.  We have to override the current class
   3205     // loader, which will always be "null" since the stuff at the
   3206     // top of the stack is around Runtime.loadLibrary().  (See
   3207     // the comments in the JNI FindClass function.)
   3208     typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
   3209     JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
   3210     ClassLoader* old_class_loader = self->GetClassLoaderOverride();
   3211     self->SetClassLoaderOverride(class_loader);
   3212 
   3213     int version = 0;
   3214     {
   3215       ScopedThreadStateChange tsc(self, kNative);
   3216       VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
   3217       version = (*jni_on_load)(this, NULL);
   3218     }
   3219 
   3220     self->SetClassLoaderOverride(old_class_loader);
   3221 
   3222     if (version == JNI_ERR) {
   3223       StringAppendF(&detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
   3224     } else if (IsBadJniVersion(version)) {
   3225       StringAppendF(&detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
   3226                     path.c_str(), version);
   3227       // It's unwise to call dlclose() here, but we can mark it
   3228       // as bad and ensure that future load attempts will fail.
   3229       // We don't know how far JNI_OnLoad got, so there could
   3230       // be some partially-initialized stuff accessible through
   3231       // newly-registered native method calls.  We could try to
   3232       // unregister them, but that doesn't seem worthwhile.
   3233     } else {
   3234       was_successful = true;
   3235     }
   3236     VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
   3237               << " from JNI_OnLoad in \"" << path << "\"]";
   3238   }
   3239 
   3240   library->SetResult(was_successful);
   3241   return was_successful;
   3242 }
   3243 
   3244 void* JavaVMExt::FindCodeForNativeMethod(ArtMethod* m) {
   3245   CHECK(m->IsNative());
   3246 
   3247   Class* c = m->GetDeclaringClass();
   3248 
   3249   // If this is a static method, it could be called before the class
   3250   // has been initialized.
   3251   if (m->IsStatic()) {
   3252     if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
   3253       return NULL;
   3254     }
   3255   } else {
   3256     CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
   3257   }
   3258 
   3259   std::string detail;
   3260   void* native_method;
   3261   Thread* self = Thread::Current();
   3262   {
   3263     MutexLock mu(self, libraries_lock);
   3264     native_method = libraries->FindNativeMethod(m, detail);
   3265   }
   3266   // Throwing can cause libraries_lock to be reacquired.
   3267   if (native_method == NULL) {
   3268     ThrowLocation throw_location = self->GetCurrentLocationForThrow();
   3269     self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
   3270   }
   3271   return native_method;
   3272 }
   3273 
   3274 void JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) {
   3275   Thread* self = Thread::Current();
   3276   {
   3277     ReaderMutexLock mu(self, globals_lock);
   3278     globals.VisitRoots(visitor, arg);
   3279   }
   3280   {
   3281     MutexLock mu(self, pins_lock);
   3282     pin_table.VisitRoots(visitor, arg);
   3283   }
   3284   // The weak_globals table is visited by the GC itself (because it mutates the table).
   3285 }
   3286 
   3287 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
   3288                            jint method_count) {
   3289   ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
   3290   if (c.get() == NULL) {
   3291     LOG(FATAL) << "Couldn't find class: " << jni_class_name;
   3292   }
   3293   JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
   3294 }
   3295 
   3296 }  // namespace art
   3297 
   3298 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
   3299   switch (rhs) {
   3300   case JNIInvalidRefType:
   3301     os << "JNIInvalidRefType";
   3302     return os;
   3303   case JNILocalRefType:
   3304     os << "JNILocalRefType";
   3305     return os;
   3306   case JNIGlobalRefType:
   3307     os << "JNIGlobalRefType";
   3308     return os;
   3309   case JNIWeakGlobalRefType:
   3310     os << "JNIWeakGlobalRefType";
   3311     return os;
   3312   default:
   3313     LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
   3314     return os;
   3315   }
   3316 }
   3317