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