jni_internal.cc revision 35aef2ce9d9cbfb37e9b2f6776afce3caed37063
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      if (static_cast<JNIEnvExt*>(env)->locals.Get(ref) != kInvalidIndirectRefObject) {
2445        return JNILocalRefType;
2446      }
2447      return JNIInvalidRefType;
2448    }
2449    case kGlobal:
2450      return JNIGlobalRefType;
2451    case kWeakGlobal:
2452      return JNIWeakGlobalRefType;
2453    case kHandleScopeOrInvalid:
2454      // Is it in a stack IRT?
2455      if (static_cast<JNIEnvExt*>(env)->self->HandleScopeContains(java_object)) {
2456        return JNILocalRefType;
2457      }
2458      return JNIInvalidRefType;
2459    }
2460    LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2461    return JNIInvalidRefType;
2462  }
2463
2464 private:
2465  static jint EnsureLocalCapacity(ScopedObjectAccess& soa, jint desired_capacity,
2466                                  const char* caller) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2467    // TODO: we should try to expand the table if necessary.
2468    if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
2469      LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2470      return JNI_ERR;
2471    }
2472    // TODO: this isn't quite right, since "capacity" includes holes.
2473    const size_t capacity = soa.Env()->locals.Capacity();
2474    bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2475    if (!okay) {
2476      soa.Self()->ThrowOutOfMemoryError(caller);
2477    }
2478    return okay ? JNI_OK : JNI_ERR;
2479  }
2480
2481  template<typename JniT, typename ArtT>
2482  static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
2483    if (UNLIKELY(length < 0)) {
2484      JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
2485      return nullptr;
2486    }
2487    ScopedObjectAccess soa(env);
2488    ArtT* result = ArtT::Alloc(soa.Self(), length);
2489    return soa.AddLocalReference<JniT>(result);
2490  }
2491
2492  template <typename JArrayT, typename ElementT, typename ArtArrayT>
2493  static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2494                                           const char* fn_name, const char* operation)
2495      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2496    ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
2497    if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
2498      JniAbortF(fn_name, "attempt to %s %s primitive array elements with an object of type %s",
2499                operation, PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2500                PrettyDescriptor(array->GetClass()).c_str());
2501      return nullptr;
2502    }
2503    DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2504    return array;
2505  }
2506
2507  template <typename ArrayT, typename ElementT, typename ArtArrayT>
2508  static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2509    CHECK_NON_NULL_ARGUMENT(java_array);
2510    ScopedObjectAccess soa(env);
2511    ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2512                                                                            "GetArrayElements",
2513                                                                            "get");
2514    if (UNLIKELY(array == nullptr)) {
2515      return nullptr;
2516    }
2517    PinPrimitiveArray(soa, array);
2518    // Only make a copy if necessary.
2519    if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2520      if (is_copy != nullptr) {
2521        *is_copy = JNI_TRUE;
2522      }
2523      const size_t component_size = sizeof(ElementT);
2524      size_t size = array->GetLength() * component_size;
2525      void* data = new uint64_t[RoundUp(size, 8) / 8];
2526      memcpy(data, array->GetData(), size);
2527      return reinterpret_cast<ElementT*>(data);
2528    } else {
2529      if (is_copy != nullptr) {
2530        *is_copy = JNI_FALSE;
2531      }
2532      return reinterpret_cast<ElementT*>(array->GetData());
2533    }
2534  }
2535
2536  template <typename ArrayT, typename ElementT, typename ArtArrayT>
2537  static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
2538    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2539    ScopedObjectAccess soa(env);
2540    ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2541                                                                            "ReleaseArrayElements",
2542                                                                            "release");
2543    if (array == nullptr) {
2544      return;
2545    }
2546    ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2547  }
2548
2549  static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2550                                    size_t component_size, void* elements, jint mode)
2551      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2552    void* array_data = array->GetRawData(component_size, 0);
2553    gc::Heap* heap = Runtime::Current()->GetHeap();
2554    bool is_copy = array_data != elements;
2555    size_t bytes = array->GetLength() * component_size;
2556    VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
2557               << " elements " << elements;
2558    if (is_copy) {
2559      // Sanity check: If elements is not the same as the java array's data, it better not be a
2560      // heap address. TODO: This might be slow to check, may be worth keeping track of which
2561      // copies we make?
2562      if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
2563        JniAbortF("ReleaseArrayElements", "invalid element pointer %p, array elements are %p",
2564                  reinterpret_cast<void*>(elements), array_data);
2565        return;
2566      }
2567    }
2568    // Don't need to copy if we had a direct pointer.
2569    if (mode != JNI_ABORT && is_copy) {
2570      memcpy(array_data, elements, bytes);
2571    }
2572    if (mode != JNI_COMMIT) {
2573      if (is_copy) {
2574        delete[] reinterpret_cast<uint64_t*>(elements);
2575      } else if (heap->IsMovableObject(array)) {
2576        // Non copy to a movable object must means that we had disabled the moving GC.
2577        heap->DecrementDisableMovingGC(soa.Self());
2578      }
2579      UnpinPrimitiveArray(soa, array);
2580    }
2581  }
2582
2583  template <typename JArrayT, typename ElementT, typename ArtArrayT>
2584  static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2585                                      jsize start, jsize length, ElementT* buf) {
2586    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2587    ScopedObjectAccess soa(env);
2588    ArtArrayT* array =
2589        DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2590                                                              "GetPrimitiveArrayRegion",
2591                                                              "get region of");
2592    if (array != nullptr) {
2593      if (start < 0 || length < 0 || start + length > array->GetLength()) {
2594        ThrowAIOOBE(soa, array, start, length, "src");
2595      } else {
2596        CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2597        ElementT* data = array->GetData();
2598        memcpy(buf, data + start, length * sizeof(ElementT));
2599      }
2600    }
2601  }
2602
2603  template <typename JArrayT, typename ElementT, typename ArtArrayT>
2604  static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2605                                      jsize start, jsize length, const ElementT* buf) {
2606    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2607    ScopedObjectAccess soa(env);
2608    ArtArrayT* array =
2609        DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2610                                                              "SetPrimitiveArrayRegion",
2611                                                              "set region of");
2612    if (array != nullptr) {
2613      if (start < 0 || length < 0 || start + length > array->GetLength()) {
2614        ThrowAIOOBE(soa, array, start, length, "dst");
2615      } else {
2616        CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2617        ElementT* data = array->GetData();
2618        memcpy(data + start, buf, length * sizeof(ElementT));
2619      }
2620    }
2621  }
2622};
2623
2624const JNINativeInterface gJniNativeInterface = {
2625  nullptr,  // reserved0.
2626  nullptr,  // reserved1.
2627  nullptr,  // reserved2.
2628  nullptr,  // reserved3.
2629  JNI::GetVersion,
2630  JNI::DefineClass,
2631  JNI::FindClass,
2632  JNI::FromReflectedMethod,
2633  JNI::FromReflectedField,
2634  JNI::ToReflectedMethod,
2635  JNI::GetSuperclass,
2636  JNI::IsAssignableFrom,
2637  JNI::ToReflectedField,
2638  JNI::Throw,
2639  JNI::ThrowNew,
2640  JNI::ExceptionOccurred,
2641  JNI::ExceptionDescribe,
2642  JNI::ExceptionClear,
2643  JNI::FatalError,
2644  JNI::PushLocalFrame,
2645  JNI::PopLocalFrame,
2646  JNI::NewGlobalRef,
2647  JNI::DeleteGlobalRef,
2648  JNI::DeleteLocalRef,
2649  JNI::IsSameObject,
2650  JNI::NewLocalRef,
2651  JNI::EnsureLocalCapacity,
2652  JNI::AllocObject,
2653  JNI::NewObject,
2654  JNI::NewObjectV,
2655  JNI::NewObjectA,
2656  JNI::GetObjectClass,
2657  JNI::IsInstanceOf,
2658  JNI::GetMethodID,
2659  JNI::CallObjectMethod,
2660  JNI::CallObjectMethodV,
2661  JNI::CallObjectMethodA,
2662  JNI::CallBooleanMethod,
2663  JNI::CallBooleanMethodV,
2664  JNI::CallBooleanMethodA,
2665  JNI::CallByteMethod,
2666  JNI::CallByteMethodV,
2667  JNI::CallByteMethodA,
2668  JNI::CallCharMethod,
2669  JNI::CallCharMethodV,
2670  JNI::CallCharMethodA,
2671  JNI::CallShortMethod,
2672  JNI::CallShortMethodV,
2673  JNI::CallShortMethodA,
2674  JNI::CallIntMethod,
2675  JNI::CallIntMethodV,
2676  JNI::CallIntMethodA,
2677  JNI::CallLongMethod,
2678  JNI::CallLongMethodV,
2679  JNI::CallLongMethodA,
2680  JNI::CallFloatMethod,
2681  JNI::CallFloatMethodV,
2682  JNI::CallFloatMethodA,
2683  JNI::CallDoubleMethod,
2684  JNI::CallDoubleMethodV,
2685  JNI::CallDoubleMethodA,
2686  JNI::CallVoidMethod,
2687  JNI::CallVoidMethodV,
2688  JNI::CallVoidMethodA,
2689  JNI::CallNonvirtualObjectMethod,
2690  JNI::CallNonvirtualObjectMethodV,
2691  JNI::CallNonvirtualObjectMethodA,
2692  JNI::CallNonvirtualBooleanMethod,
2693  JNI::CallNonvirtualBooleanMethodV,
2694  JNI::CallNonvirtualBooleanMethodA,
2695  JNI::CallNonvirtualByteMethod,
2696  JNI::CallNonvirtualByteMethodV,
2697  JNI::CallNonvirtualByteMethodA,
2698  JNI::CallNonvirtualCharMethod,
2699  JNI::CallNonvirtualCharMethodV,
2700  JNI::CallNonvirtualCharMethodA,
2701  JNI::CallNonvirtualShortMethod,
2702  JNI::CallNonvirtualShortMethodV,
2703  JNI::CallNonvirtualShortMethodA,
2704  JNI::CallNonvirtualIntMethod,
2705  JNI::CallNonvirtualIntMethodV,
2706  JNI::CallNonvirtualIntMethodA,
2707  JNI::CallNonvirtualLongMethod,
2708  JNI::CallNonvirtualLongMethodV,
2709  JNI::CallNonvirtualLongMethodA,
2710  JNI::CallNonvirtualFloatMethod,
2711  JNI::CallNonvirtualFloatMethodV,
2712  JNI::CallNonvirtualFloatMethodA,
2713  JNI::CallNonvirtualDoubleMethod,
2714  JNI::CallNonvirtualDoubleMethodV,
2715  JNI::CallNonvirtualDoubleMethodA,
2716  JNI::CallNonvirtualVoidMethod,
2717  JNI::CallNonvirtualVoidMethodV,
2718  JNI::CallNonvirtualVoidMethodA,
2719  JNI::GetFieldID,
2720  JNI::GetObjectField,
2721  JNI::GetBooleanField,
2722  JNI::GetByteField,
2723  JNI::GetCharField,
2724  JNI::GetShortField,
2725  JNI::GetIntField,
2726  JNI::GetLongField,
2727  JNI::GetFloatField,
2728  JNI::GetDoubleField,
2729  JNI::SetObjectField,
2730  JNI::SetBooleanField,
2731  JNI::SetByteField,
2732  JNI::SetCharField,
2733  JNI::SetShortField,
2734  JNI::SetIntField,
2735  JNI::SetLongField,
2736  JNI::SetFloatField,
2737  JNI::SetDoubleField,
2738  JNI::GetStaticMethodID,
2739  JNI::CallStaticObjectMethod,
2740  JNI::CallStaticObjectMethodV,
2741  JNI::CallStaticObjectMethodA,
2742  JNI::CallStaticBooleanMethod,
2743  JNI::CallStaticBooleanMethodV,
2744  JNI::CallStaticBooleanMethodA,
2745  JNI::CallStaticByteMethod,
2746  JNI::CallStaticByteMethodV,
2747  JNI::CallStaticByteMethodA,
2748  JNI::CallStaticCharMethod,
2749  JNI::CallStaticCharMethodV,
2750  JNI::CallStaticCharMethodA,
2751  JNI::CallStaticShortMethod,
2752  JNI::CallStaticShortMethodV,
2753  JNI::CallStaticShortMethodA,
2754  JNI::CallStaticIntMethod,
2755  JNI::CallStaticIntMethodV,
2756  JNI::CallStaticIntMethodA,
2757  JNI::CallStaticLongMethod,
2758  JNI::CallStaticLongMethodV,
2759  JNI::CallStaticLongMethodA,
2760  JNI::CallStaticFloatMethod,
2761  JNI::CallStaticFloatMethodV,
2762  JNI::CallStaticFloatMethodA,
2763  JNI::CallStaticDoubleMethod,
2764  JNI::CallStaticDoubleMethodV,
2765  JNI::CallStaticDoubleMethodA,
2766  JNI::CallStaticVoidMethod,
2767  JNI::CallStaticVoidMethodV,
2768  JNI::CallStaticVoidMethodA,
2769  JNI::GetStaticFieldID,
2770  JNI::GetStaticObjectField,
2771  JNI::GetStaticBooleanField,
2772  JNI::GetStaticByteField,
2773  JNI::GetStaticCharField,
2774  JNI::GetStaticShortField,
2775  JNI::GetStaticIntField,
2776  JNI::GetStaticLongField,
2777  JNI::GetStaticFloatField,
2778  JNI::GetStaticDoubleField,
2779  JNI::SetStaticObjectField,
2780  JNI::SetStaticBooleanField,
2781  JNI::SetStaticByteField,
2782  JNI::SetStaticCharField,
2783  JNI::SetStaticShortField,
2784  JNI::SetStaticIntField,
2785  JNI::SetStaticLongField,
2786  JNI::SetStaticFloatField,
2787  JNI::SetStaticDoubleField,
2788  JNI::NewString,
2789  JNI::GetStringLength,
2790  JNI::GetStringChars,
2791  JNI::ReleaseStringChars,
2792  JNI::NewStringUTF,
2793  JNI::GetStringUTFLength,
2794  JNI::GetStringUTFChars,
2795  JNI::ReleaseStringUTFChars,
2796  JNI::GetArrayLength,
2797  JNI::NewObjectArray,
2798  JNI::GetObjectArrayElement,
2799  JNI::SetObjectArrayElement,
2800  JNI::NewBooleanArray,
2801  JNI::NewByteArray,
2802  JNI::NewCharArray,
2803  JNI::NewShortArray,
2804  JNI::NewIntArray,
2805  JNI::NewLongArray,
2806  JNI::NewFloatArray,
2807  JNI::NewDoubleArray,
2808  JNI::GetBooleanArrayElements,
2809  JNI::GetByteArrayElements,
2810  JNI::GetCharArrayElements,
2811  JNI::GetShortArrayElements,
2812  JNI::GetIntArrayElements,
2813  JNI::GetLongArrayElements,
2814  JNI::GetFloatArrayElements,
2815  JNI::GetDoubleArrayElements,
2816  JNI::ReleaseBooleanArrayElements,
2817  JNI::ReleaseByteArrayElements,
2818  JNI::ReleaseCharArrayElements,
2819  JNI::ReleaseShortArrayElements,
2820  JNI::ReleaseIntArrayElements,
2821  JNI::ReleaseLongArrayElements,
2822  JNI::ReleaseFloatArrayElements,
2823  JNI::ReleaseDoubleArrayElements,
2824  JNI::GetBooleanArrayRegion,
2825  JNI::GetByteArrayRegion,
2826  JNI::GetCharArrayRegion,
2827  JNI::GetShortArrayRegion,
2828  JNI::GetIntArrayRegion,
2829  JNI::GetLongArrayRegion,
2830  JNI::GetFloatArrayRegion,
2831  JNI::GetDoubleArrayRegion,
2832  JNI::SetBooleanArrayRegion,
2833  JNI::SetByteArrayRegion,
2834  JNI::SetCharArrayRegion,
2835  JNI::SetShortArrayRegion,
2836  JNI::SetIntArrayRegion,
2837  JNI::SetLongArrayRegion,
2838  JNI::SetFloatArrayRegion,
2839  JNI::SetDoubleArrayRegion,
2840  JNI::RegisterNatives,
2841  JNI::UnregisterNatives,
2842  JNI::MonitorEnter,
2843  JNI::MonitorExit,
2844  JNI::GetJavaVM,
2845  JNI::GetStringRegion,
2846  JNI::GetStringUTFRegion,
2847  JNI::GetPrimitiveArrayCritical,
2848  JNI::ReleasePrimitiveArrayCritical,
2849  JNI::GetStringCritical,
2850  JNI::ReleaseStringCritical,
2851  JNI::NewWeakGlobalRef,
2852  JNI::DeleteWeakGlobalRef,
2853  JNI::ExceptionCheck,
2854  JNI::NewDirectByteBuffer,
2855  JNI::GetDirectBufferAddress,
2856  JNI::GetDirectBufferCapacity,
2857  JNI::GetObjectRefType,
2858};
2859
2860JNIEnvExt::JNIEnvExt(Thread* self, JavaVMExt* vm)
2861    : self(self),
2862      vm(vm),
2863      local_ref_cookie(IRT_FIRST_SEGMENT),
2864      locals(kLocalsInitial, kLocalsMax, kLocal),
2865      check_jni(false),
2866      critical(0),
2867      monitors("monitors", kMonitorsInitial, kMonitorsMax) {
2868  functions = unchecked_functions = &gJniNativeInterface;
2869  if (vm->check_jni) {
2870    SetCheckJniEnabled(true);
2871  }
2872}
2873
2874JNIEnvExt::~JNIEnvExt() {
2875}
2876
2877jobject JNIEnvExt::NewLocalRef(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2878  if (obj == nullptr) {
2879    return nullptr;
2880  }
2881  return reinterpret_cast<jobject>(locals.Add(local_ref_cookie, obj));
2882}
2883
2884void JNIEnvExt::DeleteLocalRef(jobject obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2885  if (obj != nullptr) {
2886    locals.Remove(local_ref_cookie, reinterpret_cast<IndirectRef>(obj));
2887  }
2888}
2889void JNIEnvExt::SetCheckJniEnabled(bool enabled) {
2890  check_jni = enabled;
2891  functions = enabled ? GetCheckJniNativeInterface() : &gJniNativeInterface;
2892}
2893
2894void JNIEnvExt::DumpReferenceTables(std::ostream& os) {
2895  locals.Dump(os);
2896  monitors.Dump(os);
2897}
2898
2899void JNIEnvExt::PushFrame(int capacity) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2900  UNUSED(capacity);  // cpplint gets confused with (int) and thinks its a cast.
2901  // TODO: take 'capacity' into account.
2902  stacked_local_ref_cookies.push_back(local_ref_cookie);
2903  local_ref_cookie = locals.GetSegmentState();
2904}
2905
2906void JNIEnvExt::PopFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2907  locals.SetSegmentState(local_ref_cookie);
2908  local_ref_cookie = stacked_local_ref_cookies.back();
2909  stacked_local_ref_cookies.pop_back();
2910}
2911
2912Offset JNIEnvExt::SegmentStateOffset() {
2913  return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
2914                IndirectReferenceTable::SegmentStateOffset().Int32Value());
2915}
2916
2917// JNI Invocation interface.
2918
2919extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {
2920  const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
2921  if (IsBadJniVersion(args->version)) {
2922    LOG(ERROR) << "Bad JNI version passed to CreateJavaVM: " << args->version;
2923    return JNI_EVERSION;
2924  }
2925  Runtime::Options options;
2926  for (int i = 0; i < args->nOptions; ++i) {
2927    JavaVMOption* option = &args->options[i];
2928    options.push_back(std::make_pair(std::string(option->optionString), option->extraInfo));
2929  }
2930  bool ignore_unrecognized = args->ignoreUnrecognized;
2931  if (!Runtime::Create(options, ignore_unrecognized)) {
2932    return JNI_ERR;
2933  }
2934  Runtime* runtime = Runtime::Current();
2935  bool started = runtime->Start();
2936  if (!started) {
2937    delete Thread::Current()->GetJniEnv();
2938    delete runtime->GetJavaVM();
2939    LOG(WARNING) << "CreateJavaVM failed";
2940    return JNI_ERR;
2941  }
2942  *p_env = Thread::Current()->GetJniEnv();
2943  *p_vm = runtime->GetJavaVM();
2944  return JNI_OK;
2945}
2946
2947extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize, jsize* vm_count) {
2948  Runtime* runtime = Runtime::Current();
2949  if (runtime == nullptr) {
2950    *vm_count = 0;
2951  } else {
2952    *vm_count = 1;
2953    vms[0] = runtime->GetJavaVM();
2954  }
2955  return JNI_OK;
2956}
2957
2958// Historically unsupported.
2959extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* /*vm_args*/) {
2960  return JNI_ERR;
2961}
2962
2963class JII {
2964 public:
2965  static jint DestroyJavaVM(JavaVM* vm) {
2966    if (vm == nullptr) {
2967      return JNI_ERR;
2968    }
2969    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
2970    delete raw_vm->runtime;
2971    return JNI_OK;
2972  }
2973
2974  static jint AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
2975    return JII_AttachCurrentThread(vm, p_env, thr_args, false);
2976  }
2977
2978  static jint AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
2979    return JII_AttachCurrentThread(vm, p_env, thr_args, true);
2980  }
2981
2982  static jint DetachCurrentThread(JavaVM* vm) {
2983    if (vm == nullptr || Thread::Current() == nullptr) {
2984      return JNI_ERR;
2985    }
2986    JavaVMExt* raw_vm = reinterpret_cast<JavaVMExt*>(vm);
2987    Runtime* runtime = raw_vm->runtime;
2988    runtime->DetachCurrentThread();
2989    return JNI_OK;
2990  }
2991
2992  static jint GetEnv(JavaVM* vm, void** env, jint version) {
2993    // GetEnv always returns a JNIEnv* for the most current supported JNI version,
2994    // and unlike other calls that take a JNI version doesn't care if you supply
2995    // JNI_VERSION_1_1, which we don't otherwise support.
2996    if (IsBadJniVersion(version) && version != JNI_VERSION_1_1) {
2997      LOG(ERROR) << "Bad JNI version passed to GetEnv: " << version;
2998      return JNI_EVERSION;
2999    }
3000    if (vm == nullptr || env == nullptr) {
3001      return JNI_ERR;
3002    }
3003    Thread* thread = Thread::Current();
3004    if (thread == nullptr) {
3005      *env = nullptr;
3006      return JNI_EDETACHED;
3007    }
3008    *env = thread->GetJniEnv();
3009    return JNI_OK;
3010  }
3011};
3012
3013const JNIInvokeInterface gJniInvokeInterface = {
3014  nullptr,  // reserved0
3015  nullptr,  // reserved1
3016  nullptr,  // reserved2
3017  JII::DestroyJavaVM,
3018  JII::AttachCurrentThread,
3019  JII::DetachCurrentThread,
3020  JII::GetEnv,
3021  JII::AttachCurrentThreadAsDaemon
3022};
3023
3024JavaVMExt::JavaVMExt(Runtime* runtime, ParsedOptions* options)
3025    : runtime(runtime),
3026      check_jni_abort_hook(nullptr),
3027      check_jni_abort_hook_data(nullptr),
3028      check_jni(false),
3029      force_copy(false),  // TODO: add a way to enable this
3030      trace(options->jni_trace_),
3031      pins_lock("JNI pin table lock", kPinTableLock),
3032      pin_table("pin table", kPinTableInitial, kPinTableMax),
3033      globals_lock("JNI global reference table lock"),
3034      globals(gGlobalsInitial, gGlobalsMax, kGlobal),
3035      libraries_lock("JNI shared libraries map lock", kLoadLibraryLock),
3036      libraries(new Libraries),
3037      weak_globals_lock_("JNI weak global reference table lock"),
3038      weak_globals_(kWeakGlobalsInitial, kWeakGlobalsMax, kWeakGlobal),
3039      allow_new_weak_globals_(true),
3040      weak_globals_add_condition_("weak globals add condition", weak_globals_lock_) {
3041  functions = unchecked_functions = &gJniInvokeInterface;
3042  if (options->check_jni_) {
3043    SetCheckJniEnabled(true);
3044  }
3045}
3046
3047JavaVMExt::~JavaVMExt() {
3048  delete libraries;
3049}
3050
3051jweak JavaVMExt::AddWeakGlobalReference(Thread* self, mirror::Object* obj) {
3052  if (obj == nullptr) {
3053    return nullptr;
3054  }
3055  MutexLock mu(self, weak_globals_lock_);
3056  while (UNLIKELY(!allow_new_weak_globals_)) {
3057    weak_globals_add_condition_.WaitHoldingLocks(self);
3058  }
3059  IndirectRef ref = weak_globals_.Add(IRT_FIRST_SEGMENT, obj);
3060  return reinterpret_cast<jweak>(ref);
3061}
3062
3063void JavaVMExt::DeleteWeakGlobalRef(Thread* self, jweak obj) {
3064  MutexLock mu(self, weak_globals_lock_);
3065  if (!weak_globals_.Remove(IRT_FIRST_SEGMENT, obj)) {
3066    LOG(WARNING) << "JNI WARNING: DeleteWeakGlobalRef(" << obj << ") "
3067                 << "failed to find entry";
3068  }
3069}
3070
3071void JavaVMExt::SetCheckJniEnabled(bool enabled) {
3072  check_jni = enabled;
3073  functions = enabled ? GetCheckJniInvokeInterface() : &gJniInvokeInterface;
3074}
3075
3076void JavaVMExt::DumpForSigQuit(std::ostream& os) {
3077  os << "JNI: CheckJNI is " << (check_jni ? "on" : "off");
3078  if (force_copy) {
3079    os << " (with forcecopy)";
3080  }
3081  Thread* self = Thread::Current();
3082  {
3083    MutexLock mu(self, pins_lock);
3084    os << "; pins=" << pin_table.Size();
3085  }
3086  {
3087    ReaderMutexLock mu(self, globals_lock);
3088    os << "; globals=" << globals.Capacity();
3089  }
3090  {
3091    MutexLock mu(self, weak_globals_lock_);
3092    if (weak_globals_.Capacity() > 0) {
3093      os << " (plus " << weak_globals_.Capacity() << " weak)";
3094    }
3095  }
3096  os << '\n';
3097
3098  {
3099    MutexLock mu(self, libraries_lock);
3100    os << "Libraries: " << Dumpable<Libraries>(*libraries) << " (" << libraries->size() << ")\n";
3101  }
3102}
3103
3104void JavaVMExt::DisallowNewWeakGlobals() {
3105  MutexLock mu(Thread::Current(), weak_globals_lock_);
3106  allow_new_weak_globals_ = false;
3107}
3108
3109void JavaVMExt::AllowNewWeakGlobals() {
3110  Thread* self = Thread::Current();
3111  MutexLock mu(self, weak_globals_lock_);
3112  allow_new_weak_globals_ = true;
3113  weak_globals_add_condition_.Broadcast(self);
3114}
3115
3116mirror::Object* JavaVMExt::DecodeWeakGlobal(Thread* self, IndirectRef ref) {
3117  MutexLock mu(self, weak_globals_lock_);
3118  while (UNLIKELY(!allow_new_weak_globals_)) {
3119    weak_globals_add_condition_.WaitHoldingLocks(self);
3120  }
3121  return weak_globals_.Get(ref);
3122}
3123
3124void JavaVMExt::DumpReferenceTables(std::ostream& os) {
3125  Thread* self = Thread::Current();
3126  {
3127    ReaderMutexLock mu(self, globals_lock);
3128    globals.Dump(os);
3129  }
3130  {
3131    MutexLock mu(self, weak_globals_lock_);
3132    weak_globals_.Dump(os);
3133  }
3134  {
3135    MutexLock mu(self, pins_lock);
3136    pin_table.Dump(os);
3137  }
3138}
3139
3140bool JavaVMExt::LoadNativeLibrary(const std::string& path,
3141                                  const Handle<mirror::ClassLoader>& class_loader,
3142                                  std::string* detail) {
3143  detail->clear();
3144
3145  // See if we've already loaded this library.  If we have, and the class loader
3146  // matches, return successfully without doing anything.
3147  // TODO: for better results we should canonicalize the pathname (or even compare
3148  // inodes). This implementation is fine if everybody is using System.loadLibrary.
3149  SharedLibrary* library;
3150  Thread* self = Thread::Current();
3151  {
3152    // TODO: move the locking (and more of this logic) into Libraries.
3153    MutexLock mu(self, libraries_lock);
3154    library = libraries->Get(path);
3155  }
3156  if (library != nullptr) {
3157    if (library->GetClassLoader() != class_loader.Get()) {
3158      // The library will be associated with class_loader. The JNI
3159      // spec says we can't load the same library into more than one
3160      // class loader.
3161      StringAppendF(detail, "Shared library \"%s\" already opened by "
3162          "ClassLoader %p; can't open in ClassLoader %p",
3163          path.c_str(), library->GetClassLoader(), class_loader.Get());
3164      LOG(WARNING) << detail;
3165      return false;
3166    }
3167    VLOG(jni) << "[Shared library \"" << path << "\" already loaded in "
3168              << "ClassLoader " << class_loader.Get() << "]";
3169    if (!library->CheckOnLoadResult()) {
3170      StringAppendF(detail, "JNI_OnLoad failed on a previous attempt "
3171          "to load \"%s\"", path.c_str());
3172      return false;
3173    }
3174    return true;
3175  }
3176
3177  // Open the shared library.  Because we're using a full path, the system
3178  // doesn't have to search through LD_LIBRARY_PATH.  (It may do so to
3179  // resolve this library's dependencies though.)
3180
3181  // Failures here are expected when java.library.path has several entries
3182  // and we have to hunt for the lib.
3183
3184  // Below we dlopen but there is no paired dlclose, this would be necessary if we supported
3185  // class unloading. Libraries will only be unloaded when the reference count (incremented by
3186  // dlopen) becomes zero from dlclose.
3187
3188  // This can execute slowly for a large library on a busy system, so we
3189  // want to switch from kRunnable while it executes.  This allows the GC to ignore us.
3190  self->TransitionFromRunnableToSuspended(kWaitingForJniOnLoad);
3191  void* handle = dlopen(path.empty() ? nullptr : path.c_str(), RTLD_LAZY);
3192  self->TransitionFromSuspendedToRunnable();
3193
3194  VLOG(jni) << "[Call to dlopen(\"" << path << "\", RTLD_LAZY) returned " << handle << "]";
3195
3196  if (handle == nullptr) {
3197    *detail = dlerror();
3198    LOG(ERROR) << "dlopen(\"" << path << "\", RTLD_LAZY) failed: " << *detail;
3199    return false;
3200  }
3201
3202  // Create a new entry.
3203  // TODO: move the locking (and more of this logic) into Libraries.
3204  bool created_library = false;
3205  {
3206    MutexLock mu(self, libraries_lock);
3207    library = libraries->Get(path);
3208    if (library == nullptr) {  // We won race to get libraries_lock
3209      library = new SharedLibrary(path, handle, class_loader.Get());
3210      libraries->Put(path, library);
3211      created_library = true;
3212    }
3213  }
3214  if (!created_library) {
3215    LOG(INFO) << "WOW: we lost a race to add shared library: "
3216        << "\"" << path << "\" ClassLoader=" << class_loader.Get();
3217    return library->CheckOnLoadResult();
3218  }
3219
3220  VLOG(jni) << "[Added shared library \"" << path << "\" for ClassLoader " << class_loader.Get()
3221      << "]";
3222
3223  bool was_successful = false;
3224  void* sym = dlsym(handle, "JNI_OnLoad");
3225  if (sym == nullptr) {
3226    VLOG(jni) << "[No JNI_OnLoad found in \"" << path << "\"]";
3227    was_successful = true;
3228  } else {
3229    // Call JNI_OnLoad.  We have to override the current class
3230    // loader, which will always be "null" since the stuff at the
3231    // top of the stack is around Runtime.loadLibrary().  (See
3232    // the comments in the JNI FindClass function.)
3233    typedef int (*JNI_OnLoadFn)(JavaVM*, void*);
3234    JNI_OnLoadFn jni_on_load = reinterpret_cast<JNI_OnLoadFn>(sym);
3235    StackHandleScope<1> hs(self);
3236    Handle<mirror::ClassLoader> old_class_loader(hs.NewHandle(self->GetClassLoaderOverride()));
3237    self->SetClassLoaderOverride(class_loader.Get());
3238
3239    int version = 0;
3240    {
3241      ScopedThreadStateChange tsc(self, kNative);
3242      VLOG(jni) << "[Calling JNI_OnLoad in \"" << path << "\"]";
3243      version = (*jni_on_load)(this, nullptr);
3244    }
3245
3246    self->SetClassLoaderOverride(old_class_loader.Get());
3247
3248    if (version == JNI_ERR) {
3249      StringAppendF(detail, "JNI_ERR returned from JNI_OnLoad in \"%s\"", path.c_str());
3250    } else if (IsBadJniVersion(version)) {
3251      StringAppendF(detail, "Bad JNI version returned from JNI_OnLoad in \"%s\": %d",
3252                    path.c_str(), version);
3253      // It's unwise to call dlclose() here, but we can mark it
3254      // as bad and ensure that future load attempts will fail.
3255      // We don't know how far JNI_OnLoad got, so there could
3256      // be some partially-initialized stuff accessible through
3257      // newly-registered native method calls.  We could try to
3258      // unregister them, but that doesn't seem worthwhile.
3259    } else {
3260      was_successful = true;
3261    }
3262    VLOG(jni) << "[Returned " << (was_successful ? "successfully" : "failure")
3263              << " from JNI_OnLoad in \"" << path << "\"]";
3264  }
3265
3266  library->SetResult(was_successful);
3267  return was_successful;
3268}
3269
3270void* JavaVMExt::FindCodeForNativeMethod(mirror::ArtMethod* m) {
3271  CHECK(m->IsNative());
3272  mirror::Class* c = m->GetDeclaringClass();
3273  // If this is a static method, it could be called before the class
3274  // has been initialized.
3275  if (m->IsStatic()) {
3276    c = EnsureInitialized(Thread::Current(), c);
3277    if (c == nullptr) {
3278      return nullptr;
3279    }
3280  } else {
3281    CHECK(c->IsInitializing()) << c->GetStatus() << " " << PrettyMethod(m);
3282  }
3283  std::string detail;
3284  void* native_method;
3285  Thread* self = Thread::Current();
3286  {
3287    MutexLock mu(self, libraries_lock);
3288    native_method = libraries->FindNativeMethod(m, detail);
3289  }
3290  // Throwing can cause libraries_lock to be reacquired.
3291  if (native_method == nullptr) {
3292    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
3293    self->ThrowNewException(throw_location, "Ljava/lang/UnsatisfiedLinkError;", detail.c_str());
3294  }
3295  return native_method;
3296}
3297
3298void JavaVMExt::SweepJniWeakGlobals(IsMarkedCallback* callback, void* arg) {
3299  MutexLock mu(Thread::Current(), weak_globals_lock_);
3300  for (mirror::Object** entry : weak_globals_) {
3301    mirror::Object* obj = *entry;
3302    mirror::Object* new_obj = callback(obj, arg);
3303    if (new_obj == nullptr) {
3304      new_obj = kClearedJniWeakGlobal;
3305    }
3306    *entry = new_obj;
3307  }
3308}
3309
3310void JavaVMExt::VisitRoots(RootCallback* callback, void* arg) {
3311  Thread* self = Thread::Current();
3312  {
3313    ReaderMutexLock mu(self, globals_lock);
3314    globals.VisitRoots(callback, arg, 0, kRootJNIGlobal);
3315  }
3316  {
3317    MutexLock mu(self, pins_lock);
3318    pin_table.VisitRoots(callback, arg, 0, kRootVMInternal);
3319  }
3320  {
3321    MutexLock mu(self, libraries_lock);
3322    // Libraries contains shared libraries which hold a pointer to a class loader.
3323    libraries->VisitRoots(callback, arg);
3324  }
3325  // The weak_globals table is visited by the GC itself (because it mutates the table).
3326}
3327
3328void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
3329                           jint method_count) {
3330  ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
3331  if (c.get() == nullptr) {
3332    LOG(FATAL) << "Couldn't find class: " << jni_class_name;
3333  }
3334  JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
3335}
3336
3337}  // namespace art
3338
3339std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
3340  switch (rhs) {
3341  case JNIInvalidRefType:
3342    os << "JNIInvalidRefType";
3343    return os;
3344  case JNILocalRefType:
3345    os << "JNILocalRefType";
3346    return os;
3347  case JNIGlobalRefType:
3348    os << "JNIGlobalRefType";
3349    return os;
3350  case JNIWeakGlobalRefType:
3351    os << "JNIWeakGlobalRefType";
3352    return os;
3353  default:
3354    LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
3355    return os;
3356  }
3357}
3358