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    if (!class_loader_.IsNull()) {
441      class_loader_.VisitRoot(visitor, arg, 0, kRootVMInternal);
442    }
443  }
444
445 private:
446  enum JNI_OnLoadState {
447    kPending,
448    kFailed,
449    kOkay,
450  };
451
452  // Path to library "/system/lib/libjni.so".
453  std::string path_;
454
455  // The void* returned by dlopen(3).
456  void* handle_;
457
458  // True if a native bridge is required.
459  bool needs_native_bridge_;
460
461  // The ClassLoader this library is associated with.
462  GcRoot<mirror::Object> class_loader_;
463
464  // Guards remaining items.
465  Mutex jni_on_load_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
466  // Wait for JNI_OnLoad in other thread.
467  ConditionVariable jni_on_load_cond_ GUARDED_BY(jni_on_load_lock_);
468  // Recursive invocation guard.
469  uint32_t jni_on_load_thread_id_ GUARDED_BY(jni_on_load_lock_);
470  // Result of earlier JNI_OnLoad call.
471  JNI_OnLoadState jni_on_load_result_ GUARDED_BY(jni_on_load_lock_);
472};
473
474// This exists mainly to keep implementation details out of the header file.
475class Libraries {
476 public:
477  Libraries() {
478  }
479
480  ~Libraries() {
481    STLDeleteValues(&libraries_);
482  }
483
484  void Dump(std::ostream& os) const {
485    bool first = true;
486    for (const auto& library : libraries_) {
487      if (!first) {
488        os << ' ';
489      }
490      first = false;
491      os << library.first;
492    }
493  }
494
495  size_t size() const {
496    return libraries_.size();
497  }
498
499  SharedLibrary* Get(const std::string& path) {
500    auto it = libraries_.find(path);
501    return (it == libraries_.end()) ? nullptr : it->second;
502  }
503
504  void Put(const std::string& path, SharedLibrary* library) {
505    libraries_.Put(path, library);
506  }
507
508  // See section 11.3 "Linking Native Methods" of the JNI spec.
509  void* FindNativeMethod(mirror::ArtMethod* m, std::string& detail)
510      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
511    std::string jni_short_name(JniShortName(m));
512    std::string jni_long_name(JniLongName(m));
513    const mirror::ClassLoader* declaring_class_loader = m->GetDeclaringClass()->GetClassLoader();
514    for (const auto& lib : libraries_) {
515      SharedLibrary* library = lib.second;
516      if (library->GetClassLoader() != declaring_class_loader) {
517        // We only search libraries loaded by the appropriate ClassLoader.
518        continue;
519      }
520      // Try the short name then the long name...
521      void* fn = nullptr;
522      if (UNLIKELY(library->NeedsNativeBridge())) {
523        fn = library->FindSymbolWithNativeBridge(jni_short_name, m);
524        if (fn == nullptr) {
525          fn = library->FindSymbolWithNativeBridge(jni_long_name, m);
526        }
527      } else {
528        fn = library->FindSymbol(jni_short_name);
529        if (fn == nullptr) {
530          fn = library->FindSymbol(jni_long_name);
531        }
532      }
533      if (fn != nullptr) {
534        VLOG(jni) << "[Found native code for " << PrettyMethod(m)
535                  << " in \"" << library->GetPath() << "\"]";
536        return fn;
537      }
538    }
539    detail += "No implementation found for ";
540    detail += PrettyMethod(m);
541    detail += " (tried " + jni_short_name + " and " + jni_long_name + ")";
542    LOG(ERROR) << detail;
543    return nullptr;
544  }
545
546  void VisitRoots(RootCallback* callback, void* arg) {
547    for (auto& lib_pair : libraries_) {
548      lib_pair.second->VisitRoots(callback, arg);
549    }
550  }
551
552 private:
553  AllocationTrackingSafeMap<std::string, SharedLibrary*, kAllocatorTagJNILibrarires> libraries_;
554};
555
556#define CHECK_NON_NULL_ARGUMENT(value) \
557    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
558
559#define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
560    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
561
562#define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
563    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
564
565#define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
566    CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
567
568#define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
569  if (UNLIKELY(value == nullptr)) { \
570    JniAbortF(name, #value " == null"); \
571    return return_val; \
572  }
573
574#define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
575  if (UNLIKELY(length != 0 && value == nullptr)) { \
576    JniAbortF(__FUNCTION__, #value " == null"); \
577    return; \
578  }
579
580class JNI {
581 public:
582  static jint GetVersion(JNIEnv*) {
583    return JNI_VERSION_1_6;
584  }
585
586  static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
587    LOG(WARNING) << "JNI DefineClass is not supported";
588    return nullptr;
589  }
590
591  static jclass FindClass(JNIEnv* env, const char* name) {
592    CHECK_NON_NULL_ARGUMENT(name);
593    Runtime* runtime = Runtime::Current();
594    ClassLinker* class_linker = runtime->GetClassLinker();
595    std::string descriptor(NormalizeJniClassDescriptor(name));
596    ScopedObjectAccess soa(env);
597    mirror::Class* c = nullptr;
598    if (runtime->IsStarted()) {
599      StackHandleScope<1> hs(soa.Self());
600      Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
601      c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
602    } else {
603      c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
604    }
605    return soa.AddLocalReference<jclass>(c);
606  }
607
608  static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
609    CHECK_NON_NULL_ARGUMENT(jlr_method);
610    ScopedObjectAccess soa(env);
611    return soa.EncodeMethod(mirror::ArtMethod::FromReflectedMethod(soa, jlr_method));
612  }
613
614  static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
615    CHECK_NON_NULL_ARGUMENT(jlr_field);
616    ScopedObjectAccess soa(env);
617    return soa.EncodeField(mirror::ArtField::FromReflectedField(soa, jlr_field));
618  }
619
620  static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
621    CHECK_NON_NULL_ARGUMENT(mid);
622    ScopedObjectAccess soa(env);
623    mirror::ArtMethod* m = soa.DecodeMethod(mid);
624    CHECK(!kMovingMethods);
625    jobject art_method = soa.AddLocalReference<jobject>(m);
626    jobject reflect_method;
627    if (m->IsConstructor()) {
628      reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Constructor);
629    } else {
630      reflect_method = env->AllocObject(WellKnownClasses::java_lang_reflect_Method);
631    }
632    if (env->ExceptionCheck()) {
633      return nullptr;
634    }
635    SetObjectField(env, reflect_method,
636                   WellKnownClasses::java_lang_reflect_AbstractMethod_artMethod, art_method);
637    return reflect_method;
638  }
639
640  static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
641    CHECK_NON_NULL_ARGUMENT(fid);
642    ScopedObjectAccess soa(env);
643    mirror::ArtField* f = soa.DecodeField(fid);
644    jobject art_field = soa.AddLocalReference<jobject>(f);
645    jobject reflect_field = env->AllocObject(WellKnownClasses::java_lang_reflect_Field);
646    if (env->ExceptionCheck()) {
647      return nullptr;
648    }
649    SetObjectField(env, reflect_field,
650                   WellKnownClasses::java_lang_reflect_Field_artField, art_field);
651    return reflect_field;
652  }
653
654  static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
655    CHECK_NON_NULL_ARGUMENT(java_object);
656    ScopedObjectAccess soa(env);
657    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
658    return soa.AddLocalReference<jclass>(o->GetClass());
659  }
660
661  static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
662    CHECK_NON_NULL_ARGUMENT(java_class);
663    ScopedObjectAccess soa(env);
664    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
665    return soa.AddLocalReference<jclass>(c->GetSuperClass());
666  }
667
668  // Note: java_class1 should be safely castable to java_class2, and
669  // not the other way around.
670  static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
671    CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
672    CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
673    ScopedObjectAccess soa(env);
674    mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
675    mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
676    return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
677  }
678
679  static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
680    CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
681    if (jobj == nullptr) {
682      // Note: JNI is different from regular Java instanceof in this respect
683      return JNI_TRUE;
684    } else {
685      ScopedObjectAccess soa(env);
686      mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
687      mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
688      return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
689    }
690  }
691
692  static jint Throw(JNIEnv* env, jthrowable java_exception) {
693    ScopedObjectAccess soa(env);
694    mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
695    if (exception == nullptr) {
696      return JNI_ERR;
697    }
698    ThrowLocation throw_location = soa.Self()->GetCurrentLocationForThrow();
699    soa.Self()->SetException(throw_location, exception);
700    return JNI_OK;
701  }
702
703  static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
704    CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
705    return ThrowNewException(env, c, msg, nullptr);
706  }
707
708  static jboolean ExceptionCheck(JNIEnv* env) {
709    return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
710  }
711
712  static void ExceptionClear(JNIEnv* env) {
713    ScopedObjectAccess soa(env);
714    soa.Self()->ClearException();
715  }
716
717  static void ExceptionDescribe(JNIEnv* env) {
718    ScopedObjectAccess soa(env);
719
720    // If we have no exception to describe, pass through.
721    if (!soa.Self()->GetException(nullptr)) {
722      return;
723    }
724
725    StackHandleScope<3> hs(soa.Self());
726    // TODO: Use nullptr instead of null handles?
727    auto old_throw_this_object(hs.NewHandle<mirror::Object>(nullptr));
728    auto old_throw_method(hs.NewHandle<mirror::ArtMethod>(nullptr));
729    auto old_exception(hs.NewHandle<mirror::Throwable>(nullptr));
730    uint32_t old_throw_dex_pc;
731    bool old_is_exception_reported;
732    {
733      ThrowLocation old_throw_location;
734      mirror::Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location);
735      old_throw_this_object.Assign(old_throw_location.GetThis());
736      old_throw_method.Assign(old_throw_location.GetMethod());
737      old_exception.Assign(old_exception_obj);
738      old_throw_dex_pc = old_throw_location.GetDexPc();
739      old_is_exception_reported = soa.Self()->IsExceptionReportedToInstrumentation();
740      soa.Self()->ClearException();
741    }
742    ScopedLocalRef<jthrowable> exception(env,
743                                         soa.AddLocalReference<jthrowable>(old_exception.Get()));
744    ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
745    jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
746    if (mid == nullptr) {
747      LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
748                   << PrettyTypeOf(old_exception.Get());
749    } else {
750      env->CallVoidMethod(exception.get(), mid);
751      if (soa.Self()->IsExceptionPending()) {
752        LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException(nullptr))
753                     << " thrown while calling printStackTrace";
754        soa.Self()->ClearException();
755      }
756    }
757    ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(),
758                                         old_throw_dex_pc);
759
760    soa.Self()->SetException(gc_safe_throw_location, old_exception.Get());
761    soa.Self()->SetExceptionReportedToInstrumentation(old_is_exception_reported);
762  }
763
764  static jthrowable ExceptionOccurred(JNIEnv* env) {
765    ScopedObjectAccess soa(env);
766    mirror::Object* exception = soa.Self()->GetException(nullptr);
767    return soa.AddLocalReference<jthrowable>(exception);
768  }
769
770  static void FatalError(JNIEnv*, const char* msg) {
771    LOG(FATAL) << "JNI FatalError called: " << msg;
772  }
773
774  static jint PushLocalFrame(JNIEnv* env, jint capacity) {
775    // TODO: SOA may not be necessary but I do it to please lock annotations.
776    ScopedObjectAccess soa(env);
777    if (EnsureLocalCapacity(soa, capacity, "PushLocalFrame") != JNI_OK) {
778      return JNI_ERR;
779    }
780    static_cast<JNIEnvExt*>(env)->PushFrame(capacity);
781    return JNI_OK;
782  }
783
784  static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
785    ScopedObjectAccess soa(env);
786    mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
787    soa.Env()->PopFrame();
788    return soa.AddLocalReference<jobject>(survivor);
789  }
790
791  static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
792    // TODO: SOA may not be necessary but I do it to please lock annotations.
793    ScopedObjectAccess soa(env);
794    return EnsureLocalCapacity(soa, desired_capacity, "EnsureLocalCapacity");
795  }
796
797  static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
798    ScopedObjectAccess soa(env);
799    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
800    // Check for null after decoding the object to handle cleared weak globals.
801    if (decoded_obj == nullptr) {
802      return nullptr;
803    }
804    JavaVMExt* vm = soa.Vm();
805    IndirectReferenceTable& globals = vm->globals;
806    WriterMutexLock mu(soa.Self(), vm->globals_lock);
807    IndirectRef ref = globals.Add(IRT_FIRST_SEGMENT, decoded_obj);
808    return reinterpret_cast<jobject>(ref);
809  }
810
811  static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
812    if (obj == nullptr) {
813      return;
814    }
815    JavaVMExt* vm = reinterpret_cast<JNIEnvExt*>(env)->vm;
816    IndirectReferenceTable& globals = vm->globals;
817    Thread* self = reinterpret_cast<JNIEnvExt*>(env)->self;
818    WriterMutexLock mu(self, vm->globals_lock);
819
820    if (!globals.Remove(IRT_FIRST_SEGMENT, obj)) {
821      LOG(WARNING) << "JNI WARNING: DeleteGlobalRef(" << obj << ") "
822                   << "failed to find entry";
823    }
824  }
825
826  static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
827    ScopedObjectAccess soa(env);
828    return AddWeakGlobalReference(soa, soa.Decode<mirror::Object*>(obj));
829  }
830
831  static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
832    if (obj != nullptr) {
833      ScopedObjectAccess soa(env);
834      soa.Vm()->DeleteWeakGlobalRef(soa.Self(), obj);
835    }
836  }
837
838  static jobject NewLocalRef(JNIEnv* env, jobject obj) {
839    ScopedObjectAccess soa(env);
840    mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
841    // Check for null after decoding the object to handle cleared weak globals.
842    if (decoded_obj == nullptr) {
843      return nullptr;
844    }
845    return soa.AddLocalReference<jobject>(decoded_obj);
846  }
847
848  static void DeleteLocalRef(JNIEnv* env, jobject obj) {
849    if (obj == nullptr) {
850      return;
851    }
852    ScopedObjectAccess soa(env);
853    IndirectReferenceTable& locals = reinterpret_cast<JNIEnvExt*>(env)->locals;
854
855    uint32_t cookie = reinterpret_cast<JNIEnvExt*>(env)->local_ref_cookie;
856    if (!locals.Remove(cookie, obj)) {
857      // Attempting to delete a local reference that is not in the
858      // topmost local reference frame is a no-op.  DeleteLocalRef returns
859      // void and doesn't throw any exceptions, but we should probably
860      // complain about it so the user will notice that things aren't
861      // going quite the way they expect.
862      LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
863                   << "failed to find entry";
864    }
865  }
866
867  static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
868    if (obj1 == obj2) {
869      return JNI_TRUE;
870    } else {
871      ScopedObjectAccess soa(env);
872      return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
873              ? JNI_TRUE : JNI_FALSE;
874    }
875  }
876
877  static jobject AllocObject(JNIEnv* env, jclass java_class) {
878    CHECK_NON_NULL_ARGUMENT(java_class);
879    ScopedObjectAccess soa(env);
880    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
881    if (c == nullptr) {
882      return nullptr;
883    }
884    return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
885  }
886
887  static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
888    va_list args;
889    va_start(args, mid);
890    CHECK_NON_NULL_ARGUMENT(java_class);
891    CHECK_NON_NULL_ARGUMENT(mid);
892    jobject result = NewObjectV(env, java_class, mid, args);
893    va_end(args);
894    return result;
895  }
896
897  static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
898    CHECK_NON_NULL_ARGUMENT(java_class);
899    CHECK_NON_NULL_ARGUMENT(mid);
900    ScopedObjectAccess soa(env);
901    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
902    if (c == nullptr) {
903      return nullptr;
904    }
905    mirror::Object* result = c->AllocObject(soa.Self());
906    if (result == nullptr) {
907      return nullptr;
908    }
909    jobject local_result = soa.AddLocalReference<jobject>(result);
910    CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
911    if (soa.Self()->IsExceptionPending()) {
912      return nullptr;
913    }
914    return local_result;
915  }
916
917  static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
918    CHECK_NON_NULL_ARGUMENT(java_class);
919    CHECK_NON_NULL_ARGUMENT(mid);
920    ScopedObjectAccess soa(env);
921    mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
922    if (c == nullptr) {
923      return nullptr;
924    }
925    mirror::Object* result = c->AllocObject(soa.Self());
926    if (result == nullptr) {
927      return nullptr;
928    }
929    jobject local_result = soa.AddLocalReference<jobjectArray>(result);
930    CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
931    if (soa.Self()->IsExceptionPending()) {
932      return nullptr;
933    }
934    return local_result;
935  }
936
937  static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
938    CHECK_NON_NULL_ARGUMENT(java_class);
939    CHECK_NON_NULL_ARGUMENT(name);
940    CHECK_NON_NULL_ARGUMENT(sig);
941    ScopedObjectAccess soa(env);
942    return FindMethodID(soa, java_class, name, sig, false);
943  }
944
945  static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
946                                     const char* sig) {
947    CHECK_NON_NULL_ARGUMENT(java_class);
948    CHECK_NON_NULL_ARGUMENT(name);
949    CHECK_NON_NULL_ARGUMENT(sig);
950    ScopedObjectAccess soa(env);
951    return FindMethodID(soa, java_class, name, sig, true);
952  }
953
954  static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
955    va_list ap;
956    va_start(ap, mid);
957    CHECK_NON_NULL_ARGUMENT(obj);
958    CHECK_NON_NULL_ARGUMENT(mid);
959    ScopedObjectAccess soa(env);
960    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
961    va_end(ap);
962    return soa.AddLocalReference<jobject>(result.GetL());
963  }
964
965  static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
966    CHECK_NON_NULL_ARGUMENT(obj);
967    CHECK_NON_NULL_ARGUMENT(mid);
968    ScopedObjectAccess soa(env);
969    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
970    return soa.AddLocalReference<jobject>(result.GetL());
971  }
972
973  static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
974    CHECK_NON_NULL_ARGUMENT(obj);
975    CHECK_NON_NULL_ARGUMENT(mid);
976    ScopedObjectAccess soa(env);
977    JValue result(InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
978                                                      args));
979    return soa.AddLocalReference<jobject>(result.GetL());
980  }
981
982  static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
983    va_list ap;
984    va_start(ap, mid);
985    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
986    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
987    ScopedObjectAccess soa(env);
988    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
989    va_end(ap);
990    return result.GetZ();
991  }
992
993  static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
994    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
995    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
996    ScopedObjectAccess soa(env);
997    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
998  }
999
1000  static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1001    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1002    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1003    ScopedObjectAccess soa(env);
1004    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1005                                               args).GetZ();
1006  }
1007
1008  static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1009    va_list ap;
1010    va_start(ap, mid);
1011    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1012    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1013    ScopedObjectAccess soa(env);
1014    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1015    va_end(ap);
1016    return result.GetB();
1017  }
1018
1019  static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1020    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1021    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1022    ScopedObjectAccess soa(env);
1023    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
1024  }
1025
1026  static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1027    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1028    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1029    ScopedObjectAccess soa(env);
1030    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1031                                               args).GetB();
1032  }
1033
1034  static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1035    va_list ap;
1036    va_start(ap, mid);
1037    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1038    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1039    ScopedObjectAccess soa(env);
1040    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1041    va_end(ap);
1042    return result.GetC();
1043  }
1044
1045  static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1046    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1047    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1048    ScopedObjectAccess soa(env);
1049    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
1050  }
1051
1052  static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1053    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1054    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1055    ScopedObjectAccess soa(env);
1056    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1057                                               args).GetC();
1058  }
1059
1060  static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1061    va_list ap;
1062    va_start(ap, mid);
1063    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1064    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1065    ScopedObjectAccess soa(env);
1066    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1067    va_end(ap);
1068    return result.GetD();
1069  }
1070
1071  static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1072    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1073    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1074    ScopedObjectAccess soa(env);
1075    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
1076  }
1077
1078  static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1079    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1080    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1081    ScopedObjectAccess soa(env);
1082    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1083                                               args).GetD();
1084  }
1085
1086  static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1087    va_list ap;
1088    va_start(ap, mid);
1089    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1090    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1091    ScopedObjectAccess soa(env);
1092    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1093    va_end(ap);
1094    return result.GetF();
1095  }
1096
1097  static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1098    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1099    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1100    ScopedObjectAccess soa(env);
1101    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
1102  }
1103
1104  static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1105    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1106    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1107    ScopedObjectAccess soa(env);
1108    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1109                                               args).GetF();
1110  }
1111
1112  static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1113    va_list ap;
1114    va_start(ap, mid);
1115    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1116    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1117    ScopedObjectAccess soa(env);
1118    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1119    va_end(ap);
1120    return result.GetI();
1121  }
1122
1123  static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1124    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1125    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1126    ScopedObjectAccess soa(env);
1127    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
1128  }
1129
1130  static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1131    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1132    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1133    ScopedObjectAccess soa(env);
1134    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1135                                               args).GetI();
1136  }
1137
1138  static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1139    va_list ap;
1140    va_start(ap, mid);
1141    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1142    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1143    ScopedObjectAccess soa(env);
1144    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1145    va_end(ap);
1146    return result.GetJ();
1147  }
1148
1149  static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1150    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1151    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1152    ScopedObjectAccess soa(env);
1153    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
1154  }
1155
1156  static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1157    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1158    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1159    ScopedObjectAccess soa(env);
1160    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1161                                               args).GetJ();
1162  }
1163
1164  static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1165    va_list ap;
1166    va_start(ap, mid);
1167    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1168    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1169    ScopedObjectAccess soa(env);
1170    JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
1171    va_end(ap);
1172    return result.GetS();
1173  }
1174
1175  static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1176    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1177    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1178    ScopedObjectAccess soa(env);
1179    return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
1180  }
1181
1182  static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1183    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1184    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1185    ScopedObjectAccess soa(env);
1186    return InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid,
1187                                               args).GetS();
1188  }
1189
1190  static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
1191    va_list ap;
1192    va_start(ap, mid);
1193    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1194    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1195    ScopedObjectAccess soa(env);
1196    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
1197    va_end(ap);
1198  }
1199
1200  static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
1201    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1202    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1203    ScopedObjectAccess soa(env);
1204    InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
1205  }
1206
1207  static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
1208    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1209    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1210    ScopedObjectAccess soa(env);
1211    InvokeVirtualOrInterfaceWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
1212  }
1213
1214  static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1215    va_list ap;
1216    va_start(ap, mid);
1217    CHECK_NON_NULL_ARGUMENT(obj);
1218    CHECK_NON_NULL_ARGUMENT(mid);
1219    ScopedObjectAccess soa(env);
1220    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1221    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1222    va_end(ap);
1223    return local_result;
1224  }
1225
1226  static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1227                                             va_list args) {
1228    CHECK_NON_NULL_ARGUMENT(obj);
1229    CHECK_NON_NULL_ARGUMENT(mid);
1230    ScopedObjectAccess soa(env);
1231    JValue result(InvokeWithVarArgs(soa, obj, mid, args));
1232    return soa.AddLocalReference<jobject>(result.GetL());
1233  }
1234
1235  static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1236                                             jvalue* args) {
1237    CHECK_NON_NULL_ARGUMENT(obj);
1238    CHECK_NON_NULL_ARGUMENT(mid);
1239    ScopedObjectAccess soa(env);
1240    JValue result(InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args));
1241    return soa.AddLocalReference<jobject>(result.GetL());
1242  }
1243
1244  static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1245                                              ...) {
1246    va_list ap;
1247    va_start(ap, mid);
1248    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1249    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1250    ScopedObjectAccess soa(env);
1251    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1252    va_end(ap);
1253    return result.GetZ();
1254  }
1255
1256  static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1257                                               va_list args) {
1258    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1259    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1260    ScopedObjectAccess soa(env);
1261    return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
1262  }
1263
1264  static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1265                                               jvalue* args) {
1266    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1267    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1268    ScopedObjectAccess soa(env);
1269    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetZ();
1270  }
1271
1272  static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1273    va_list ap;
1274    va_start(ap, mid);
1275    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1276    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1277    ScopedObjectAccess soa(env);
1278    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1279    va_end(ap);
1280    return result.GetB();
1281  }
1282
1283  static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1284                                         va_list args) {
1285    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1286    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1287    ScopedObjectAccess soa(env);
1288    return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1289  }
1290
1291  static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1292                                         jvalue* args) {
1293    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1294    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1295    ScopedObjectAccess soa(env);
1296    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetB();
1297  }
1298
1299  static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1300    va_list ap;
1301    va_start(ap, mid);
1302    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1303    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1304    ScopedObjectAccess soa(env);
1305    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1306    va_end(ap);
1307    return result.GetC();
1308  }
1309
1310  static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1311                                         va_list args) {
1312    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1313    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1314    ScopedObjectAccess soa(env);
1315    return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1316  }
1317
1318  static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1319                                         jvalue* args) {
1320    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1321    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1322    ScopedObjectAccess soa(env);
1323    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetC();
1324  }
1325
1326  static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1327    va_list ap;
1328    va_start(ap, mid);
1329    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1330    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1331    ScopedObjectAccess soa(env);
1332    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1333    va_end(ap);
1334    return result.GetS();
1335  }
1336
1337  static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1338                                           va_list args) {
1339    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1340    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1341    ScopedObjectAccess soa(env);
1342    return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1343  }
1344
1345  static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1346                                           jvalue* args) {
1347    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1348    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1349    ScopedObjectAccess soa(env);
1350    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetS();
1351  }
1352
1353  static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1354    va_list ap;
1355    va_start(ap, mid);
1356    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1357    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1358    ScopedObjectAccess soa(env);
1359    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1360    va_end(ap);
1361    return result.GetI();
1362  }
1363
1364  static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1365                                       va_list args) {
1366    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1367    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1368    ScopedObjectAccess soa(env);
1369    return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1370  }
1371
1372  static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1373                                       jvalue* args) {
1374    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1375    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1376    ScopedObjectAccess soa(env);
1377    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetI();
1378  }
1379
1380  static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1381    va_list ap;
1382    va_start(ap, mid);
1383    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1384    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1385    ScopedObjectAccess soa(env);
1386    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1387    va_end(ap);
1388    return result.GetJ();
1389  }
1390
1391  static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1392                                         va_list args) {
1393    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1394    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1395    ScopedObjectAccess soa(env);
1396    return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1397  }
1398
1399  static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1400                                         jvalue* args) {
1401    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1402    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1403    ScopedObjectAccess soa(env);
1404    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetJ();
1405  }
1406
1407  static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1408    va_list ap;
1409    va_start(ap, mid);
1410    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1411    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1412    ScopedObjectAccess soa(env);
1413    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1414    va_end(ap);
1415    return result.GetF();
1416  }
1417
1418  static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1419                                           va_list args) {
1420    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1421    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1422    ScopedObjectAccess soa(env);
1423    return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1424  }
1425
1426  static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1427                                           jvalue* args) {
1428    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1429    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1430    ScopedObjectAccess soa(env);
1431    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetF();
1432  }
1433
1434  static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1435    va_list ap;
1436    va_start(ap, mid);
1437    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1438    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1439    ScopedObjectAccess soa(env);
1440    JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1441    va_end(ap);
1442    return result.GetD();
1443  }
1444
1445  static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1446                                             va_list args) {
1447    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1448    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1449    ScopedObjectAccess soa(env);
1450    return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1451  }
1452
1453  static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1454                                             jvalue* args) {
1455    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1456    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1457    ScopedObjectAccess soa(env);
1458    return InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args).GetD();
1459  }
1460
1461  static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1462    va_list ap;
1463    va_start(ap, mid);
1464    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1465    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1466    ScopedObjectAccess soa(env);
1467    InvokeWithVarArgs(soa, obj, mid, ap);
1468    va_end(ap);
1469  }
1470
1471  static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1472                                        va_list args) {
1473    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1474    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1475    ScopedObjectAccess soa(env);
1476    InvokeWithVarArgs(soa, obj, mid, args);
1477  }
1478
1479  static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1480                                        jvalue* args) {
1481    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1482    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1483    ScopedObjectAccess soa(env);
1484    InvokeWithJValues(soa, soa.Decode<mirror::Object*>(obj), mid, args);
1485  }
1486
1487  static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1488    CHECK_NON_NULL_ARGUMENT(java_class);
1489    CHECK_NON_NULL_ARGUMENT(name);
1490    CHECK_NON_NULL_ARGUMENT(sig);
1491    ScopedObjectAccess soa(env);
1492    return FindFieldID(soa, java_class, name, sig, false);
1493  }
1494
1495  static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1496                                   const char* sig) {
1497    CHECK_NON_NULL_ARGUMENT(java_class);
1498    CHECK_NON_NULL_ARGUMENT(name);
1499    CHECK_NON_NULL_ARGUMENT(sig);
1500    ScopedObjectAccess soa(env);
1501    return FindFieldID(soa, java_class, name, sig, true);
1502  }
1503
1504  static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
1505    CHECK_NON_NULL_ARGUMENT(obj);
1506    CHECK_NON_NULL_ARGUMENT(fid);
1507    ScopedObjectAccess soa(env);
1508    mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1509    mirror::ArtField* f = soa.DecodeField(fid);
1510    return soa.AddLocalReference<jobject>(f->GetObject(o));
1511  }
1512
1513  static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
1514    CHECK_NON_NULL_ARGUMENT(fid);
1515    ScopedObjectAccess soa(env);
1516    mirror::ArtField* f = soa.DecodeField(fid);
1517    return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1518  }
1519
1520  static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
1521    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1522    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1523    ScopedObjectAccess soa(env);
1524    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1525    mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1526    mirror::ArtField* f = soa.DecodeField(fid);
1527    f->SetObject<false>(o, v);
1528  }
1529
1530  static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
1531    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1532    ScopedObjectAccess soa(env);
1533    mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1534    mirror::ArtField* f = soa.DecodeField(fid);
1535    f->SetObject<false>(f->GetDeclaringClass(), v);
1536  }
1537
1538#define GET_PRIMITIVE_FIELD(fn, instance) \
1539  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1540  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1541  ScopedObjectAccess soa(env); \
1542  mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1543  mirror::ArtField* f = soa.DecodeField(fid); \
1544  return f->Get ##fn (o)
1545
1546#define GET_STATIC_PRIMITIVE_FIELD(fn) \
1547  CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1548  ScopedObjectAccess soa(env); \
1549  mirror::ArtField* f = soa.DecodeField(fid); \
1550  return f->Get ##fn (f->GetDeclaringClass())
1551
1552#define SET_PRIMITIVE_FIELD(fn, instance, value) \
1553  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1554  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1555  ScopedObjectAccess soa(env); \
1556  mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1557  mirror::ArtField* f = soa.DecodeField(fid); \
1558  f->Set ##fn <false>(o, value)
1559
1560#define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
1561  CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1562  ScopedObjectAccess soa(env); \
1563  mirror::ArtField* f = soa.DecodeField(fid); \
1564  f->Set ##fn <false>(f->GetDeclaringClass(), value)
1565
1566  static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1567    GET_PRIMITIVE_FIELD(Boolean, obj);
1568  }
1569
1570  static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1571    GET_PRIMITIVE_FIELD(Byte, obj);
1572  }
1573
1574  static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1575    GET_PRIMITIVE_FIELD(Char, obj);
1576  }
1577
1578  static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1579    GET_PRIMITIVE_FIELD(Short, obj);
1580  }
1581
1582  static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1583    GET_PRIMITIVE_FIELD(Int, obj);
1584  }
1585
1586  static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1587    GET_PRIMITIVE_FIELD(Long, obj);
1588  }
1589
1590  static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1591    GET_PRIMITIVE_FIELD(Float, obj);
1592  }
1593
1594  static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1595    GET_PRIMITIVE_FIELD(Double, obj);
1596  }
1597
1598  static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1599    GET_STATIC_PRIMITIVE_FIELD(Boolean);
1600  }
1601
1602  static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1603    GET_STATIC_PRIMITIVE_FIELD(Byte);
1604  }
1605
1606  static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1607    GET_STATIC_PRIMITIVE_FIELD(Char);
1608  }
1609
1610  static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1611    GET_STATIC_PRIMITIVE_FIELD(Short);
1612  }
1613
1614  static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1615    GET_STATIC_PRIMITIVE_FIELD(Int);
1616  }
1617
1618  static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1619    GET_STATIC_PRIMITIVE_FIELD(Long);
1620  }
1621
1622  static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1623    GET_STATIC_PRIMITIVE_FIELD(Float);
1624  }
1625
1626  static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1627    GET_STATIC_PRIMITIVE_FIELD(Double);
1628  }
1629
1630  static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1631    SET_PRIMITIVE_FIELD(Boolean, obj, v);
1632  }
1633
1634  static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1635    SET_PRIMITIVE_FIELD(Byte, obj, v);
1636  }
1637
1638  static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1639    SET_PRIMITIVE_FIELD(Char, obj, v);
1640  }
1641
1642  static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1643    SET_PRIMITIVE_FIELD(Float, obj, v);
1644  }
1645
1646  static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1647    SET_PRIMITIVE_FIELD(Double, obj, v);
1648  }
1649
1650  static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1651    SET_PRIMITIVE_FIELD(Int, obj, v);
1652  }
1653
1654  static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1655    SET_PRIMITIVE_FIELD(Long, obj, v);
1656  }
1657
1658  static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1659    SET_PRIMITIVE_FIELD(Short, obj, v);
1660  }
1661
1662  static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1663    SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1664  }
1665
1666  static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1667    SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1668  }
1669
1670  static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1671    SET_STATIC_PRIMITIVE_FIELD(Char, v);
1672  }
1673
1674  static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1675    SET_STATIC_PRIMITIVE_FIELD(Float, v);
1676  }
1677
1678  static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1679    SET_STATIC_PRIMITIVE_FIELD(Double, v);
1680  }
1681
1682  static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1683    SET_STATIC_PRIMITIVE_FIELD(Int, v);
1684  }
1685
1686  static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1687    SET_STATIC_PRIMITIVE_FIELD(Long, v);
1688  }
1689
1690  static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1691    SET_STATIC_PRIMITIVE_FIELD(Short, v);
1692  }
1693
1694  static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1695    va_list ap;
1696    va_start(ap, mid);
1697    CHECK_NON_NULL_ARGUMENT(mid);
1698    ScopedObjectAccess soa(env);
1699    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1700    jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1701    va_end(ap);
1702    return local_result;
1703  }
1704
1705  static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1706    CHECK_NON_NULL_ARGUMENT(mid);
1707    ScopedObjectAccess soa(env);
1708    JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
1709    return soa.AddLocalReference<jobject>(result.GetL());
1710  }
1711
1712  static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1713    CHECK_NON_NULL_ARGUMENT(mid);
1714    ScopedObjectAccess soa(env);
1715    JValue result(InvokeWithJValues(soa, nullptr, mid, args));
1716    return soa.AddLocalReference<jobject>(result.GetL());
1717  }
1718
1719  static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1720    va_list ap;
1721    va_start(ap, mid);
1722    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1723    ScopedObjectAccess soa(env);
1724    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1725    va_end(ap);
1726    return result.GetZ();
1727  }
1728
1729  static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1730    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1731    ScopedObjectAccess soa(env);
1732    return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1733  }
1734
1735  static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1736    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1737    ScopedObjectAccess soa(env);
1738    return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1739  }
1740
1741  static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1742    va_list ap;
1743    va_start(ap, mid);
1744    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1745    ScopedObjectAccess soa(env);
1746    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1747    va_end(ap);
1748    return result.GetB();
1749  }
1750
1751  static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1752    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1753    ScopedObjectAccess soa(env);
1754    return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1755  }
1756
1757  static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1758    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1759    ScopedObjectAccess soa(env);
1760    return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1761  }
1762
1763  static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1764    va_list ap;
1765    va_start(ap, mid);
1766    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1767    ScopedObjectAccess soa(env);
1768    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1769    va_end(ap);
1770    return result.GetC();
1771  }
1772
1773  static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1774    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1775    ScopedObjectAccess soa(env);
1776    return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1777  }
1778
1779  static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1780    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1781    ScopedObjectAccess soa(env);
1782    return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1783  }
1784
1785  static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1786    va_list ap;
1787    va_start(ap, mid);
1788    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1789    ScopedObjectAccess soa(env);
1790    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1791    va_end(ap);
1792    return result.GetS();
1793  }
1794
1795  static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1796    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1797    ScopedObjectAccess soa(env);
1798    return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1799  }
1800
1801  static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1802    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1803    ScopedObjectAccess soa(env);
1804    return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1805  }
1806
1807  static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1808    va_list ap;
1809    va_start(ap, mid);
1810    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1811    ScopedObjectAccess soa(env);
1812    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1813    va_end(ap);
1814    return result.GetI();
1815  }
1816
1817  static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1818    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1819    ScopedObjectAccess soa(env);
1820    return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1821  }
1822
1823  static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1824    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1825    ScopedObjectAccess soa(env);
1826    return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1827  }
1828
1829  static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1830    va_list ap;
1831    va_start(ap, mid);
1832    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1833    ScopedObjectAccess soa(env);
1834    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1835    va_end(ap);
1836    return result.GetJ();
1837  }
1838
1839  static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1840    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1841    ScopedObjectAccess soa(env);
1842    return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1843  }
1844
1845  static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1846    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1847    ScopedObjectAccess soa(env);
1848    return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1849  }
1850
1851  static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1852    va_list ap;
1853    va_start(ap, mid);
1854    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1855    ScopedObjectAccess soa(env);
1856    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1857    va_end(ap);
1858    return result.GetF();
1859  }
1860
1861  static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1862    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1863    ScopedObjectAccess soa(env);
1864    return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1865  }
1866
1867  static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1868    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1869    ScopedObjectAccess soa(env);
1870    return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1871  }
1872
1873  static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1874    va_list ap;
1875    va_start(ap, mid);
1876    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1877    ScopedObjectAccess soa(env);
1878    JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1879    va_end(ap);
1880    return result.GetD();
1881  }
1882
1883  static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1884    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1885    ScopedObjectAccess soa(env);
1886    return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1887  }
1888
1889  static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1890    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1891    ScopedObjectAccess soa(env);
1892    return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1893  }
1894
1895  static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1896    va_list ap;
1897    va_start(ap, mid);
1898    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1899    ScopedObjectAccess soa(env);
1900    InvokeWithVarArgs(soa, nullptr, mid, ap);
1901    va_end(ap);
1902  }
1903
1904  static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1905    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1906    ScopedObjectAccess soa(env);
1907    InvokeWithVarArgs(soa, nullptr, mid, args);
1908  }
1909
1910  static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1911    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1912    ScopedObjectAccess soa(env);
1913    InvokeWithJValues(soa, nullptr, mid, args);
1914  }
1915
1916  static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
1917    if (UNLIKELY(char_count < 0)) {
1918      JniAbortF("NewString", "char_count < 0: %d", char_count);
1919      return nullptr;
1920    }
1921    if (UNLIKELY(chars == nullptr && char_count > 0)) {
1922      JniAbortF("NewString", "chars == null && char_count > 0");
1923      return nullptr;
1924    }
1925    ScopedObjectAccess soa(env);
1926    mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
1927    return soa.AddLocalReference<jstring>(result);
1928  }
1929
1930  static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1931    if (utf == nullptr) {
1932      return nullptr;
1933    }
1934    ScopedObjectAccess soa(env);
1935    mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
1936    return soa.AddLocalReference<jstring>(result);
1937  }
1938
1939  static jsize GetStringLength(JNIEnv* env, jstring java_string) {
1940    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1941    ScopedObjectAccess soa(env);
1942    return soa.Decode<mirror::String*>(java_string)->GetLength();
1943  }
1944
1945  static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
1946    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1947    ScopedObjectAccess soa(env);
1948    return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
1949  }
1950
1951  static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1952                              jchar* buf) {
1953    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1954    ScopedObjectAccess soa(env);
1955    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1956    if (start < 0 || length < 0 || start + length > s->GetLength()) {
1957      ThrowSIOOBE(soa, start, length, s->GetLength());
1958    } else {
1959      CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1960      const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1961      memcpy(buf, chars + start, length * sizeof(jchar));
1962    }
1963  }
1964
1965  static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1966                                 char* buf) {
1967    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1968    ScopedObjectAccess soa(env);
1969    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1970    if (start < 0 || length < 0 || start + length > s->GetLength()) {
1971      ThrowSIOOBE(soa, start, length, s->GetLength());
1972    } else {
1973      CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1974      const jchar* chars = s->GetCharArray()->GetData() + s->GetOffset();
1975      ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1976    }
1977  }
1978
1979  static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1980    CHECK_NON_NULL_ARGUMENT(java_string);
1981    ScopedObjectAccess soa(env);
1982    mirror::String* s = soa.Decode<mirror::String*>(java_string);
1983    mirror::CharArray* chars = s->GetCharArray();
1984    gc::Heap* heap = Runtime::Current()->GetHeap();
1985    if (heap->IsMovableObject(chars)) {
1986      if (is_copy != nullptr) {
1987        *is_copy = JNI_TRUE;
1988      }
1989      int32_t char_count = s->GetLength();
1990      int32_t offset = s->GetOffset();
1991      jchar* bytes = new jchar[char_count];
1992      for (int32_t i = 0; i < char_count; i++) {
1993        bytes[i] = chars->Get(i + offset);
1994      }
1995      return bytes;
1996    } else {
1997      if (is_copy != nullptr) {
1998        *is_copy = JNI_FALSE;
1999      }
2000      return static_cast<jchar*>(chars->GetData() + s->GetOffset());
2001    }
2002  }
2003
2004  static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
2005    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2006    ScopedObjectAccess soa(env);
2007    mirror::String* s = soa.Decode<mirror::String*>(java_string);
2008    mirror::CharArray* s_chars = s->GetCharArray();
2009    if (chars != (s_chars->GetData() + s->GetOffset())) {
2010      delete[] chars;
2011    }
2012  }
2013
2014  static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2015    CHECK_NON_NULL_ARGUMENT(java_string);
2016    ScopedObjectAccess soa(env);
2017    mirror::String* s = soa.Decode<mirror::String*>(java_string);
2018    mirror::CharArray* chars = s->GetCharArray();
2019    int32_t offset = s->GetOffset();
2020    gc::Heap* heap = Runtime::Current()->GetHeap();
2021    if (heap->IsMovableObject(chars)) {
2022      StackHandleScope<1> hs(soa.Self());
2023      HandleWrapper<mirror::CharArray> h(hs.NewHandleWrapper(&chars));
2024      heap->IncrementDisableMovingGC(soa.Self());
2025    }
2026    if (is_copy != nullptr) {
2027      *is_copy = JNI_FALSE;
2028    }
2029    return static_cast<jchar*>(chars->GetData() + offset);
2030  }
2031
2032  static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
2033    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
2034    ScopedObjectAccess soa(env);
2035    gc::Heap* heap = Runtime::Current()->GetHeap();
2036    mirror::String* s = soa.Decode<mirror::String*>(java_string);
2037    mirror::CharArray* s_chars = s->GetCharArray();
2038    if (heap->IsMovableObject(s_chars)) {
2039      heap->DecrementDisableMovingGC(soa.Self());
2040    }
2041  }
2042
2043  static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
2044    if (java_string == nullptr) {
2045      return nullptr;
2046    }
2047    if (is_copy != nullptr) {
2048      *is_copy = JNI_TRUE;
2049    }
2050    ScopedObjectAccess soa(env);
2051    mirror::String* s = soa.Decode<mirror::String*>(java_string);
2052    size_t byte_count = s->GetUtfLength();
2053    char* bytes = new char[byte_count + 1];
2054    CHECK(bytes != nullptr);  // bionic aborts anyway.
2055    const uint16_t* chars = s->GetCharArray()->GetData() + s->GetOffset();
2056    ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
2057    bytes[byte_count] = '\0';
2058    return bytes;
2059  }
2060
2061  static void ReleaseStringUTFChars(JNIEnv* env, jstring, const char* chars) {
2062    delete[] chars;
2063  }
2064
2065  static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
2066    CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
2067    ScopedObjectAccess soa(env);
2068    mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
2069    if (UNLIKELY(!obj->IsArrayInstance())) {
2070      JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
2071    }
2072    mirror::Array* array = obj->AsArray();
2073    return array->GetLength();
2074  }
2075
2076  static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
2077    CHECK_NON_NULL_ARGUMENT(java_array);
2078    ScopedObjectAccess soa(env);
2079    mirror::ObjectArray<mirror::Object>* array =
2080        soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
2081    return soa.AddLocalReference<jobject>(array->Get(index));
2082  }
2083
2084  static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
2085                                    jobject java_value) {
2086    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2087    ScopedObjectAccess soa(env);
2088    mirror::ObjectArray<mirror::Object>* array =
2089        soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
2090    mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
2091    array->Set<false>(index, value);
2092  }
2093
2094  static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
2095    return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
2096  }
2097
2098  static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
2099    return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
2100  }
2101
2102  static jcharArray NewCharArray(JNIEnv* env, jsize length) {
2103    return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
2104  }
2105
2106  static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
2107    return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
2108  }
2109
2110  static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
2111    return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
2112  }
2113
2114  static jintArray NewIntArray(JNIEnv* env, jsize length) {
2115    return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
2116  }
2117
2118  static jlongArray NewLongArray(JNIEnv* env, jsize length) {
2119    return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
2120  }
2121
2122  static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
2123                                     jobject initial_element) {
2124    if (UNLIKELY(length < 0)) {
2125      JniAbortF("NewObjectArray", "negative array length: %d", length);
2126      return nullptr;
2127    }
2128    CHECK_NON_NULL_ARGUMENT(element_jclass);
2129
2130    // Compute the array class corresponding to the given element class.
2131    ScopedObjectAccess soa(env);
2132    mirror::Class* array_class;
2133    {
2134      mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
2135      if (UNLIKELY(element_class->IsPrimitive())) {
2136        JniAbortF("NewObjectArray", "not an object type: %s",
2137                  PrettyDescriptor(element_class).c_str());
2138        return nullptr;
2139      }
2140      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
2141      array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
2142      if (UNLIKELY(array_class == nullptr)) {
2143        return nullptr;
2144      }
2145    }
2146
2147    // Allocate and initialize if necessary.
2148    mirror::ObjectArray<mirror::Object>* result =
2149        mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
2150    if (result != nullptr && initial_element != nullptr) {
2151      mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
2152      if (initial_object != nullptr) {
2153        mirror::Class* element_class = result->GetClass()->GetComponentType();
2154        if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
2155          JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with element "
2156                    "type of '%s'", PrettyDescriptor(initial_object->GetClass()).c_str(),
2157                    PrettyDescriptor(element_class).c_str());
2158
2159        } else {
2160          for (jsize i = 0; i < length; ++i) {
2161            result->SetWithoutChecks<false>(i, initial_object);
2162          }
2163        }
2164      }
2165    }
2166    return soa.AddLocalReference<jobjectArray>(result);
2167  }
2168
2169  static jshortArray NewShortArray(JNIEnv* env, jsize length) {
2170    return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
2171  }
2172
2173  static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
2174    CHECK_NON_NULL_ARGUMENT(java_array);
2175    ScopedObjectAccess soa(env);
2176    mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
2177    if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2178      JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
2179                PrettyDescriptor(array->GetClass()).c_str());
2180      return nullptr;
2181    }
2182    gc::Heap* heap = Runtime::Current()->GetHeap();
2183    if (heap->IsMovableObject(array)) {
2184      heap->IncrementDisableMovingGC(soa.Self());
2185      // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
2186      array = soa.Decode<mirror::Array*>(java_array);
2187    }
2188    if (is_copy != nullptr) {
2189      *is_copy = JNI_FALSE;
2190    }
2191    return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
2192  }
2193
2194  static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
2195                                            jint mode) {
2196    CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2197    ScopedObjectAccess soa(env);
2198    mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
2199    if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
2200      JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
2201                PrettyDescriptor(array->GetClass()).c_str());
2202      return;
2203    }
2204    const size_t component_size = array->GetClass()->GetComponentSize();
2205    ReleasePrimitiveArray(soa, array, component_size, elements, mode);
2206  }
2207
2208  static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
2209    return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
2210  }
2211
2212  static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
2213    return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
2214  }
2215
2216  static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
2217    return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
2218  }
2219
2220  static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
2221    return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
2222  }
2223
2224  static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
2225    return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
2226  }
2227
2228  static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
2229    return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
2230  }
2231
2232  static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
2233    return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
2234  }
2235
2236  static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
2237    return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
2238  }
2239
2240  static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
2241                                          jint mode) {
2242    ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
2243                                                                         mode);
2244  }
2245
2246  static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
2247    ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
2248  }
2249
2250  static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
2251    ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
2252  }
2253
2254  static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
2255                                         jint mode) {
2256    ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
2257  }
2258
2259  static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
2260                                        jint mode) {
2261    ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
2262  }
2263
2264  static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
2265    ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
2266  }
2267
2268  static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
2269    ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
2270  }
2271
2272  static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
2273                                        jint mode) {
2274    ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
2275  }
2276
2277  static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2278                                    jboolean* buf) {
2279    GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2280                                                                           length, buf);
2281  }
2282
2283  static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2284                                 jbyte* buf) {
2285    GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2286  }
2287
2288  static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2289                                 jchar* buf) {
2290    GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2291  }
2292
2293  static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2294                                   jdouble* buf) {
2295    GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2296                                                                        buf);
2297  }
2298
2299  static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2300                                  jfloat* buf) {
2301    GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2302                                                                     buf);
2303  }
2304
2305  static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2306                                jint* buf) {
2307    GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2308  }
2309
2310  static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2311                                 jlong* buf) {
2312    GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2313  }
2314
2315  static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2316                                  jshort* buf) {
2317    GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2318                                                                     buf);
2319  }
2320
2321  static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2322                                    const jboolean* buf) {
2323    SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2324                                                                           length, buf);
2325  }
2326
2327  static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2328                                 const jbyte* buf) {
2329    SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2330  }
2331
2332  static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2333                                 const jchar* buf) {
2334    SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2335  }
2336
2337  static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2338                                   const jdouble* buf) {
2339    SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2340                                                                        buf);
2341  }
2342
2343  static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2344                                  const jfloat* buf) {
2345    SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2346                                                                     buf);
2347  }
2348
2349  static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2350                                const jint* buf) {
2351    SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2352  }
2353
2354  static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2355                                 const jlong* buf) {
2356    SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2357  }
2358
2359  static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2360                                  const jshort* buf) {
2361    SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2362                                                                     buf);
2363  }
2364
2365  static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2366                              jint method_count) {
2367    return RegisterNativeMethods(env, java_class, methods, method_count, true);
2368  }
2369
2370  static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2371                                    jint method_count, bool return_errors) {
2372    if (UNLIKELY(method_count < 0)) {
2373      JniAbortF("RegisterNatives", "negative method count: %d", method_count);
2374      return JNI_ERR;  // Not reached.
2375    }
2376    CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
2377    ScopedObjectAccess soa(env);
2378    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2379    if (UNLIKELY(method_count == 0)) {
2380      LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2381          << PrettyDescriptor(c);
2382      return JNI_OK;
2383    }
2384    CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2385    for (jint i = 0; i < method_count; ++i) {
2386      const char* name = methods[i].name;
2387      const char* sig = methods[i].signature;
2388      const void* fnPtr = methods[i].fnPtr;
2389      if (UNLIKELY(name == nullptr)) {
2390        ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2391        return JNI_ERR;
2392      } else if (UNLIKELY(sig == nullptr)) {
2393        ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2394        return JNI_ERR;
2395      } else if (UNLIKELY(fnPtr == nullptr)) {
2396        ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2397        return JNI_ERR;
2398      }
2399      bool is_fast = false;
2400      if (*sig == '!') {
2401        is_fast = true;
2402        ++sig;
2403      }
2404
2405      mirror::ArtMethod* m = c->FindDirectMethod(name, sig);
2406      if (m == nullptr) {
2407        m = c->FindVirtualMethod(name, sig);
2408      }
2409      if (m == nullptr) {
2410        c->DumpClass(LOG(ERROR), mirror::Class::kDumpClassFullDetail);
2411        LOG(return_errors ? ERROR : FATAL) << "Failed to register native method "
2412            << PrettyDescriptor(c) << "." << name << sig << " in "
2413            << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
2414        ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2415        return JNI_ERR;
2416      } else if (!m->IsNative()) {
2417        LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2418            << PrettyDescriptor(c) << "." << name << sig
2419            << " as native";
2420        ThrowNoSuchMethodError(soa, c, name, sig, "native");
2421        return JNI_ERR;
2422      }
2423
2424      VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
2425
2426      m->RegisterNative(soa.Self(), fnPtr, is_fast);
2427    }
2428    return JNI_OK;
2429  }
2430
2431  static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
2432    CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
2433    ScopedObjectAccess soa(env);
2434    mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2435
2436    VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
2437
2438    size_t unregistered_count = 0;
2439    for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
2440      mirror::ArtMethod* m = c->GetDirectMethod(i);
2441      if (m->IsNative()) {
2442        m->UnregisterNative(soa.Self());
2443        unregistered_count++;
2444      }
2445    }
2446    for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
2447      mirror::ArtMethod* m = c->GetVirtualMethod(i);
2448      if (m->IsNative()) {
2449        m->UnregisterNative(soa.Self());
2450        unregistered_count++;
2451      }
2452    }
2453
2454    if (unregistered_count == 0) {
2455      LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2456          << PrettyDescriptor(c) << "' that contains no native methods";
2457    }
2458    return JNI_OK;
2459  }
2460
2461  static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2462    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2463    ScopedObjectAccess soa(env);
2464    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2465    o = o->MonitorEnter(soa.Self());
2466    if (soa.Self()->IsExceptionPending()) {
2467      return JNI_ERR;
2468    }
2469    soa.Env()->monitors.Add(o);
2470    return JNI_OK;
2471  }
2472
2473  static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2474    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2475    ScopedObjectAccess soa(env);
2476    mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2477    o->MonitorExit(soa.Self());
2478    if (soa.Self()->IsExceptionPending()) {
2479      return JNI_ERR;
2480    }
2481    soa.Env()->monitors.Remove(o);
2482    return JNI_OK;
2483  }
2484
2485  static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
2486    CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2487    Runtime* runtime = Runtime::Current();
2488    if (runtime != nullptr) {
2489      *vm = runtime->GetJavaVM();
2490    } else {
2491      *vm = nullptr;
2492    }
2493    return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2494  }
2495
2496  static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
2497    if (capacity < 0) {
2498      JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64, capacity);
2499      return nullptr;
2500    }
2501    if (address == nullptr && capacity != 0) {
2502      JniAbortF("NewDirectByteBuffer", "non-zero capacity for nullptr pointer: %" PRId64, capacity);
2503      return nullptr;
2504    }
2505
2506    // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
2507    if (capacity > INT_MAX) {
2508      JniAbortF("NewDirectByteBuffer", "buffer capacity greater than maximum jint: %" PRId64, capacity);
2509      return nullptr;
2510    }
2511    jlong address_arg = reinterpret_cast<jlong>(address);
2512    jint capacity_arg = static_cast<jint>(capacity);
2513
2514    jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2515                                    WellKnownClasses::java_nio_DirectByteBuffer_init,
2516                                    address_arg, capacity_arg);
2517    return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
2518  }
2519
2520  static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2521    return reinterpret_cast<void*>(env->GetLongField(
2522        java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2523  }
2524
2525  static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2526    return static_cast<jlong>(env->GetIntField(
2527        java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2528  }
2529
2530  static jobjectRefType GetObjectRefType(JNIEnv* env, jobject java_object) {
2531    CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNIInvalidRefType);
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, 0, 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