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