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