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