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