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