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