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