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