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 "art_field-inl.h"
27 #include "art_method-inl.h"
28 #include "atomic.h"
29 #include "base/allocator.h"
30 #include "base/logging.h"
31 #include "base/mutex.h"
32 #include "base/stl_util.h"
33 #include "class_linker-inl.h"
34 #include "dex_file-inl.h"
35 #include "fault_handler.h"
36 #include "gc_root.h"
37 #include "gc/accounting/card_table-inl.h"
38 #include "indirect_reference_table-inl.h"
39 #include "interpreter/interpreter.h"
40 #include "jni_env_ext.h"
41 #include "java_vm_ext.h"
42 #include "mirror/class-inl.h"
43 #include "mirror/class_loader.h"
44 #include "mirror/field-inl.h"
45 #include "mirror/method.h"
46 #include "mirror/object-inl.h"
47 #include "mirror/object_array-inl.h"
48 #include "mirror/string-inl.h"
49 #include "mirror/throwable.h"
50 #include "parsed_options.h"
51 #include "reflection.h"
52 #include "runtime.h"
53 #include "safe_map.h"
54 #include "scoped_thread_state_change.h"
55 #include "ScopedLocalRef.h"
56 #include "thread.h"
57 #include "utf.h"
58 #include "well_known_classes.h"
59 
60 namespace art {
61 
62 // Consider turning this on when there is errors which could be related to JNI array copies such as
63 // things not rendering correctly. E.g. b/16858794
64 static constexpr bool kWarnJniAbort = false;
65 
66 // Section 12.3.2 of the JNI spec describes JNI class descriptors. They're
67 // separated with slashes but aren't wrapped with "L;" like regular descriptors
68 // (i.e. "a/b/C" rather than "La/b/C;"). Arrays of reference types are an
69 // exception; there the "L;" must be present ("[La/b/C;"). Historically we've
70 // supported names with dots too (such as "a.b.C").
NormalizeJniClassDescriptor(const char * name)71 static std::string NormalizeJniClassDescriptor(const char* name) {
72   std::string result;
73   // Add the missing "L;" if necessary.
74   if (name[0] == '[') {
75     result = name;
76   } else {
77     result += 'L';
78     result += name;
79     result += ';';
80   }
81   // Rewrite '.' as '/' for backwards compatibility.
82   if (result.find('.') != std::string::npos) {
83     LOG(WARNING) << "Call to JNI FindClass with dots in name: "
84                  << "\"" << name << "\"";
85     std::replace(result.begin(), result.end(), '.', '/');
86   }
87   return result;
88 }
89 
ThrowNoSuchMethodError(ScopedObjectAccess & soa,mirror::Class * c,const char * name,const char * sig,const char * kind)90 static void ThrowNoSuchMethodError(ScopedObjectAccess& soa, mirror::Class* c,
91                                    const char* name, const char* sig, const char* kind)
92     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93   std::string temp;
94   soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
95                                  "no %s method \"%s.%s%s\"",
96                                  kind, c->GetDescriptor(&temp), name, sig);
97 }
98 
ReportInvalidJNINativeMethod(const ScopedObjectAccess & soa,mirror::Class * c,const char * kind,jint idx,bool return_errors)99 static void ReportInvalidJNINativeMethod(const ScopedObjectAccess& soa, mirror::Class* c,
100                                          const char* kind, jint idx, bool return_errors)
101     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
102   LOG(return_errors ? ERROR : FATAL) << "Failed to register native method in "
103       << PrettyDescriptor(c) << " in " << c->GetDexCache()->GetLocation()->ToModifiedUtf8()
104       << ": " << kind << " is null at index " << idx;
105   soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchMethodError;",
106                                  "%s is null at index %d", kind, idx);
107 }
108 
EnsureInitialized(Thread * self,mirror::Class * klass)109 static mirror::Class* EnsureInitialized(Thread* self, mirror::Class* klass)
110     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
111   if (LIKELY(klass->IsInitialized())) {
112     return klass;
113   }
114   StackHandleScope<1> hs(self);
115   Handle<mirror::Class> h_klass(hs.NewHandle(klass));
116   if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_klass, true, true)) {
117     return nullptr;
118   }
119   return h_klass.Get();
120 }
121 
FindMethodID(ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)122 static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
123                               const char* name, const char* sig, bool is_static)
124     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
125   mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class));
126   if (c == nullptr) {
127     return nullptr;
128   }
129   ArtMethod* method = nullptr;
130   auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
131   if (is_static) {
132     method = c->FindDirectMethod(name, sig, pointer_size);
133   } else if (c->IsInterface()) {
134     method = c->FindInterfaceMethod(name, sig, pointer_size);
135   } else {
136     method = c->FindVirtualMethod(name, sig, pointer_size);
137     if (method == nullptr) {
138       // No virtual method matching the signature.  Search declared
139       // private methods and constructors.
140       method = c->FindDeclaredDirectMethod(name, sig, pointer_size);
141     }
142   }
143   if (method == nullptr || method->IsStatic() != is_static) {
144     ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
145     return nullptr;
146   }
147   return soa.EncodeMethod(method);
148 }
149 
GetClassLoader(const ScopedObjectAccess & soa)150 static mirror::ClassLoader* GetClassLoader(const ScopedObjectAccess& soa)
151     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
152   ArtMethod* method = soa.Self()->GetCurrentMethod(nullptr);
153   // If we are running Runtime.nativeLoad, use the overriding ClassLoader it set.
154   if (method == soa.DecodeMethod(WellKnownClasses::java_lang_Runtime_nativeLoad)) {
155     return soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
156   }
157   // If we have a method, use its ClassLoader for context.
158   if (method != nullptr) {
159     return method->GetDeclaringClass()->GetClassLoader();
160   }
161   // We don't have a method, so try to use the system ClassLoader.
162   mirror::ClassLoader* class_loader =
163       soa.Decode<mirror::ClassLoader*>(Runtime::Current()->GetSystemClassLoader());
164   if (class_loader != nullptr) {
165     return class_loader;
166   }
167   // See if the override ClassLoader is set for gtests.
168   class_loader = soa.Decode<mirror::ClassLoader*>(soa.Self()->GetClassLoaderOverride());
169   if (class_loader != nullptr) {
170     // If so, CommonCompilerTest should have marked the runtime as a compiler not compiling an
171     // image.
172     CHECK(Runtime::Current()->IsAotCompiler());
173     CHECK(!Runtime::Current()->IsCompilingBootImage());
174     return class_loader;
175   }
176   // Use the BOOTCLASSPATH.
177   return nullptr;
178 }
179 
FindFieldID(const ScopedObjectAccess & soa,jclass jni_class,const char * name,const char * sig,bool is_static)180 static jfieldID FindFieldID(const ScopedObjectAccess& soa, jclass jni_class, const char* name,
181                             const char* sig, bool is_static)
182     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
183   StackHandleScope<2> hs(soa.Self());
184   Handle<mirror::Class> c(
185       hs.NewHandle(EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class))));
186   if (c.Get() == nullptr) {
187     return nullptr;
188   }
189   ArtField* field = nullptr;
190   mirror::Class* field_type;
191   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
192   if (sig[1] != '\0') {
193     Handle<mirror::ClassLoader> class_loader(hs.NewHandle(c->GetClassLoader()));
194     field_type = class_linker->FindClass(soa.Self(), sig, class_loader);
195   } else {
196     field_type = class_linker->FindPrimitiveClass(*sig);
197   }
198   if (field_type == nullptr) {
199     // Failed to find type from the signature of the field.
200     DCHECK(soa.Self()->IsExceptionPending());
201     StackHandleScope<1> hs2(soa.Self());
202     Handle<mirror::Throwable> cause(hs2.NewHandle(soa.Self()->GetException()));
203     soa.Self()->ClearException();
204     std::string temp;
205     soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
206                                    "no type \"%s\" found and so no field \"%s\" "
207                                    "could be found in class \"%s\" or its superclasses", sig, name,
208                                    c->GetDescriptor(&temp));
209     soa.Self()->GetException()->SetCause(cause.Get());
210     return nullptr;
211   }
212   std::string temp;
213   if (is_static) {
214     field = mirror::Class::FindStaticField(soa.Self(), c, name,
215                                            field_type->GetDescriptor(&temp));
216   } else {
217     field = c->FindInstanceField(name, field_type->GetDescriptor(&temp));
218   }
219   if (field == nullptr) {
220     soa.Self()->ThrowNewExceptionF("Ljava/lang/NoSuchFieldError;",
221                                    "no \"%s\" field \"%s\" in class \"%s\" or its superclasses",
222                                    sig, name, c->GetDescriptor(&temp));
223     return nullptr;
224   }
225   return soa.EncodeField(field);
226 }
227 
ThrowAIOOBE(ScopedObjectAccess & soa,mirror::Array * array,jsize start,jsize length,const char * identifier)228 static void ThrowAIOOBE(ScopedObjectAccess& soa, mirror::Array* array, jsize start,
229                         jsize length, const char* identifier)
230     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
231   std::string type(PrettyTypeOf(array));
232   soa.Self()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
233                                  "%s offset=%d length=%d %s.length=%d",
234                                  type.c_str(), start, length, identifier, array->GetLength());
235 }
236 
ThrowSIOOBE(ScopedObjectAccess & soa,jsize start,jsize length,jsize array_length)237 static void ThrowSIOOBE(ScopedObjectAccess& soa, jsize start, jsize length,
238                         jsize array_length)
239     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
240   soa.Self()->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
241                                  "offset=%d length=%d string.length()=%d", start, length,
242                                  array_length);
243 }
244 
ThrowNewException(JNIEnv * env,jclass exception_class,const char * msg,jobject cause)245 int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause)
246     LOCKS_EXCLUDED(Locks::mutator_lock_) {
247   // Turn the const char* into a java.lang.String.
248   ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg));
249   if (msg != nullptr && s.get() == nullptr) {
250     return JNI_ERR;
251   }
252 
253   // Choose an appropriate constructor and set up the arguments.
254   jvalue args[2];
255   const char* signature;
256   if (msg == nullptr && cause == nullptr) {
257     signature = "()V";
258   } else if (msg != nullptr && cause == nullptr) {
259     signature = "(Ljava/lang/String;)V";
260     args[0].l = s.get();
261   } else if (msg == nullptr && cause != nullptr) {
262     signature = "(Ljava/lang/Throwable;)V";
263     args[0].l = cause;
264   } else {
265     signature = "(Ljava/lang/String;Ljava/lang/Throwable;)V";
266     args[0].l = s.get();
267     args[1].l = cause;
268   }
269   jmethodID mid = env->GetMethodID(exception_class, "<init>", signature);
270   if (mid == nullptr) {
271     ScopedObjectAccess soa(env);
272     LOG(ERROR) << "No <init>" << signature << " in "
273         << PrettyClass(soa.Decode<mirror::Class*>(exception_class));
274     return JNI_ERR;
275   }
276 
277   ScopedLocalRef<jthrowable> exception(
278       env, reinterpret_cast<jthrowable>(env->NewObjectA(exception_class, mid, args)));
279   if (exception.get() == nullptr) {
280     return JNI_ERR;
281   }
282   ScopedObjectAccess soa(env);
283   soa.Self()->SetException(soa.Decode<mirror::Throwable*>(exception.get()));
284   return JNI_OK;
285 }
286 
JavaVmExtFromEnv(JNIEnv * env)287 static JavaVMExt* JavaVmExtFromEnv(JNIEnv* env) {
288   return reinterpret_cast<JNIEnvExt*>(env)->vm;
289 }
290 
291 #define CHECK_NON_NULL_ARGUMENT(value) \
292     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, nullptr)
293 
294 #define CHECK_NON_NULL_ARGUMENT_RETURN_VOID(value) \
295     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, )
296 
297 #define CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(value) \
298     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, 0)
299 
300 #define CHECK_NON_NULL_ARGUMENT_RETURN(value, return_val) \
301     CHECK_NON_NULL_ARGUMENT_FN_NAME(__FUNCTION__, value, return_val)
302 
303 #define CHECK_NON_NULL_ARGUMENT_FN_NAME(name, value, return_val) \
304   if (UNLIKELY(value == nullptr)) { \
305     JavaVmExtFromEnv(env)->JniAbortF(name, #value " == null"); \
306     return return_val; \
307   }
308 
309 #define CHECK_NON_NULL_MEMCPY_ARGUMENT(length, value) \
310   if (UNLIKELY(length != 0 && value == nullptr)) { \
311     JavaVmExtFromEnv(env)->JniAbortF(__FUNCTION__, #value " == null"); \
312     return; \
313   }
314 
315 template <bool kNative>
FindMethod(mirror::Class * c,const StringPiece & name,const StringPiece & sig)316 static ArtMethod* FindMethod(mirror::Class* c, const StringPiece& name, const StringPiece& sig)
317     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
318   auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
319   for (auto& method : c->GetDirectMethods(pointer_size)) {
320     if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
321       return &method;
322     }
323   }
324   for (auto& method : c->GetVirtualMethods(pointer_size)) {
325     if (kNative == method.IsNative() && name == method.GetName() && method.GetSignature() == sig) {
326       return &method;
327     }
328   }
329   return nullptr;
330 }
331 
332 class JNI {
333  public:
GetVersion(JNIEnv *)334   static jint GetVersion(JNIEnv*) {
335     return JNI_VERSION_1_6;
336   }
337 
DefineClass(JNIEnv *,const char *,jobject,const jbyte *,jsize)338   static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) {
339     LOG(WARNING) << "JNI DefineClass is not supported";
340     return nullptr;
341   }
342 
FindClass(JNIEnv * env,const char * name)343   static jclass FindClass(JNIEnv* env, const char* name) {
344     CHECK_NON_NULL_ARGUMENT(name);
345     Runtime* runtime = Runtime::Current();
346     ClassLinker* class_linker = runtime->GetClassLinker();
347     std::string descriptor(NormalizeJniClassDescriptor(name));
348     ScopedObjectAccess soa(env);
349     mirror::Class* c = nullptr;
350     if (runtime->IsStarted()) {
351       StackHandleScope<1> hs(soa.Self());
352       Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa)));
353       c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader);
354     } else {
355       c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str());
356     }
357     return soa.AddLocalReference<jclass>(c);
358   }
359 
FromReflectedMethod(JNIEnv * env,jobject jlr_method)360   static jmethodID FromReflectedMethod(JNIEnv* env, jobject jlr_method) {
361     CHECK_NON_NULL_ARGUMENT(jlr_method);
362     ScopedObjectAccess soa(env);
363     return soa.EncodeMethod(ArtMethod::FromReflectedMethod(soa, jlr_method));
364   }
365 
FromReflectedField(JNIEnv * env,jobject jlr_field)366   static jfieldID FromReflectedField(JNIEnv* env, jobject jlr_field) {
367     CHECK_NON_NULL_ARGUMENT(jlr_field);
368     ScopedObjectAccess soa(env);
369     mirror::Object* obj_field = soa.Decode<mirror::Object*>(jlr_field);
370     if (obj_field->GetClass() != mirror::Field::StaticClass()) {
371       // Not even a java.lang.reflect.Field, return null. TODO, is this check necessary?
372       return nullptr;
373     }
374     auto* field = static_cast<mirror::Field*>(obj_field);
375     return soa.EncodeField(field->GetArtField());
376   }
377 
ToReflectedMethod(JNIEnv * env,jclass,jmethodID mid,jboolean)378   static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
379     CHECK_NON_NULL_ARGUMENT(mid);
380     ScopedObjectAccess soa(env);
381     ArtMethod* m = soa.DecodeMethod(mid);
382     mirror::AbstractMethod* method;
383     if (m->IsConstructor()) {
384       method = mirror::Constructor::CreateFromArtMethod(soa.Self(), m);
385     } else {
386       method = mirror::Method::CreateFromArtMethod(soa.Self(), m);
387     }
388     return soa.AddLocalReference<jobject>(method);
389   }
390 
ToReflectedField(JNIEnv * env,jclass,jfieldID fid,jboolean)391   static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
392     CHECK_NON_NULL_ARGUMENT(fid);
393     ScopedObjectAccess soa(env);
394     ArtField* f = soa.DecodeField(fid);
395     return soa.AddLocalReference<jobject>(mirror::Field::CreateFromArtField(soa.Self(), f, true));
396   }
397 
GetObjectClass(JNIEnv * env,jobject java_object)398   static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
399     CHECK_NON_NULL_ARGUMENT(java_object);
400     ScopedObjectAccess soa(env);
401     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
402     return soa.AddLocalReference<jclass>(o->GetClass());
403   }
404 
GetSuperclass(JNIEnv * env,jclass java_class)405   static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
406     CHECK_NON_NULL_ARGUMENT(java_class);
407     ScopedObjectAccess soa(env);
408     mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
409     return soa.AddLocalReference<jclass>(c->GetSuperClass());
410   }
411 
412   // Note: java_class1 should be safely castable to java_class2, and
413   // not the other way around.
IsAssignableFrom(JNIEnv * env,jclass java_class1,jclass java_class2)414   static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
415     CHECK_NON_NULL_ARGUMENT_RETURN(java_class1, JNI_FALSE);
416     CHECK_NON_NULL_ARGUMENT_RETURN(java_class2, JNI_FALSE);
417     ScopedObjectAccess soa(env);
418     mirror::Class* c1 = soa.Decode<mirror::Class*>(java_class1);
419     mirror::Class* c2 = soa.Decode<mirror::Class*>(java_class2);
420     return c2->IsAssignableFrom(c1) ? JNI_TRUE : JNI_FALSE;
421   }
422 
IsInstanceOf(JNIEnv * env,jobject jobj,jclass java_class)423   static jboolean IsInstanceOf(JNIEnv* env, jobject jobj, jclass java_class) {
424     CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_FALSE);
425     if (jobj == nullptr) {
426       // Note: JNI is different from regular Java instanceof in this respect
427       return JNI_TRUE;
428     } else {
429       ScopedObjectAccess soa(env);
430       mirror::Object* obj = soa.Decode<mirror::Object*>(jobj);
431       mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
432       return obj->InstanceOf(c) ? JNI_TRUE : JNI_FALSE;
433     }
434   }
435 
Throw(JNIEnv * env,jthrowable java_exception)436   static jint Throw(JNIEnv* env, jthrowable java_exception) {
437     ScopedObjectAccess soa(env);
438     mirror::Throwable* exception = soa.Decode<mirror::Throwable*>(java_exception);
439     if (exception == nullptr) {
440       return JNI_ERR;
441     }
442     soa.Self()->SetException(exception);
443     return JNI_OK;
444   }
445 
ThrowNew(JNIEnv * env,jclass c,const char * msg)446   static jint ThrowNew(JNIEnv* env, jclass c, const char* msg) {
447     CHECK_NON_NULL_ARGUMENT_RETURN(c, JNI_ERR);
448     return ThrowNewException(env, c, msg, nullptr);
449   }
450 
ExceptionCheck(JNIEnv * env)451   static jboolean ExceptionCheck(JNIEnv* env) {
452     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? JNI_TRUE : JNI_FALSE;
453   }
454 
ExceptionClear(JNIEnv * env)455   static void ExceptionClear(JNIEnv* env) {
456     ScopedObjectAccess soa(env);
457     soa.Self()->ClearException();
458   }
459 
ExceptionDescribe(JNIEnv * env)460   static void ExceptionDescribe(JNIEnv* env) {
461     ScopedObjectAccess soa(env);
462 
463     // If we have no exception to describe, pass through.
464     if (!soa.Self()->GetException()) {
465       return;
466     }
467 
468     StackHandleScope<1> hs(soa.Self());
469     Handle<mirror::Throwable> old_exception(
470         hs.NewHandle<mirror::Throwable>(soa.Self()->GetException()));
471     soa.Self()->ClearException();
472     ScopedLocalRef<jthrowable> exception(env,
473                                          soa.AddLocalReference<jthrowable>(old_exception.Get()));
474     ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
475     jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
476     if (mid == nullptr) {
477       LOG(WARNING) << "JNI WARNING: no printStackTrace()V in "
478                    << PrettyTypeOf(old_exception.Get());
479     } else {
480       env->CallVoidMethod(exception.get(), mid);
481       if (soa.Self()->IsExceptionPending()) {
482         LOG(WARNING) << "JNI WARNING: " << PrettyTypeOf(soa.Self()->GetException())
483                      << " thrown while calling printStackTrace";
484         soa.Self()->ClearException();
485       }
486     }
487     soa.Self()->SetException(old_exception.Get());
488   }
489 
ExceptionOccurred(JNIEnv * env)490   static jthrowable ExceptionOccurred(JNIEnv* env) {
491     ScopedObjectAccess soa(env);
492     mirror::Object* exception = soa.Self()->GetException();
493     return soa.AddLocalReference<jthrowable>(exception);
494   }
495 
FatalError(JNIEnv *,const char * msg)496   static void FatalError(JNIEnv*, const char* msg) {
497     LOG(FATAL) << "JNI FatalError called: " << msg;
498   }
499 
PushLocalFrame(JNIEnv * env,jint capacity)500   static jint PushLocalFrame(JNIEnv* env, jint capacity) {
501     // TODO: SOA may not be necessary but I do it to please lock annotations.
502     ScopedObjectAccess soa(env);
503     if (EnsureLocalCapacityInternal(soa, capacity, "PushLocalFrame") != JNI_OK) {
504       return JNI_ERR;
505     }
506     down_cast<JNIEnvExt*>(env)->PushFrame(capacity);
507     return JNI_OK;
508   }
509 
PopLocalFrame(JNIEnv * env,jobject java_survivor)510   static jobject PopLocalFrame(JNIEnv* env, jobject java_survivor) {
511     ScopedObjectAccess soa(env);
512     mirror::Object* survivor = soa.Decode<mirror::Object*>(java_survivor);
513     soa.Env()->PopFrame();
514     return soa.AddLocalReference<jobject>(survivor);
515   }
516 
EnsureLocalCapacity(JNIEnv * env,jint desired_capacity)517   static jint EnsureLocalCapacity(JNIEnv* env, jint desired_capacity) {
518     // TODO: SOA may not be necessary but I do it to please lock annotations.
519     ScopedObjectAccess soa(env);
520     return EnsureLocalCapacityInternal(soa, desired_capacity, "EnsureLocalCapacity");
521   }
522 
NewGlobalRef(JNIEnv * env,jobject obj)523   static jobject NewGlobalRef(JNIEnv* env, jobject obj) {
524     ScopedObjectAccess soa(env);
525     mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
526     return soa.Vm()->AddGlobalRef(soa.Self(), decoded_obj);
527   }
528 
DeleteGlobalRef(JNIEnv * env,jobject obj)529   static void DeleteGlobalRef(JNIEnv* env, jobject obj) {
530     JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
531     Thread* self = down_cast<JNIEnvExt*>(env)->self;
532     vm->DeleteGlobalRef(self, obj);
533   }
534 
NewWeakGlobalRef(JNIEnv * env,jobject obj)535   static jweak NewWeakGlobalRef(JNIEnv* env, jobject obj) {
536     ScopedObjectAccess soa(env);
537     mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
538     return soa.Vm()->AddWeakGlobalRef(soa.Self(), decoded_obj);
539   }
540 
DeleteWeakGlobalRef(JNIEnv * env,jweak obj)541   static void DeleteWeakGlobalRef(JNIEnv* env, jweak obj) {
542     JavaVMExt* vm = down_cast<JNIEnvExt*>(env)->vm;
543     Thread* self = down_cast<JNIEnvExt*>(env)->self;
544     vm->DeleteWeakGlobalRef(self, obj);
545   }
546 
NewLocalRef(JNIEnv * env,jobject obj)547   static jobject NewLocalRef(JNIEnv* env, jobject obj) {
548     ScopedObjectAccess soa(env);
549     mirror::Object* decoded_obj = soa.Decode<mirror::Object*>(obj);
550     // Check for null after decoding the object to handle cleared weak globals.
551     if (decoded_obj == nullptr) {
552       return nullptr;
553     }
554     return soa.AddLocalReference<jobject>(decoded_obj);
555   }
556 
DeleteLocalRef(JNIEnv * env,jobject obj)557   static void DeleteLocalRef(JNIEnv* env, jobject obj) {
558     if (obj == nullptr) {
559       return;
560     }
561     // SOA is only necessary to have exclusion between GC root marking and removing.
562     // We don't want to have the GC attempt to mark a null root if we just removed
563     // it. b/22119403
564     ScopedObjectAccess soa(env);
565     auto* ext_env = down_cast<JNIEnvExt*>(env);
566     if (!ext_env->locals.Remove(ext_env->local_ref_cookie, obj)) {
567       // Attempting to delete a local reference that is not in the
568       // topmost local reference frame is a no-op.  DeleteLocalRef returns
569       // void and doesn't throw any exceptions, but we should probably
570       // complain about it so the user will notice that things aren't
571       // going quite the way they expect.
572       LOG(WARNING) << "JNI WARNING: DeleteLocalRef(" << obj << ") "
573                    << "failed to find entry";
574     }
575   }
576 
IsSameObject(JNIEnv * env,jobject obj1,jobject obj2)577   static jboolean IsSameObject(JNIEnv* env, jobject obj1, jobject obj2) {
578     if (obj1 == obj2) {
579       return JNI_TRUE;
580     } else {
581       ScopedObjectAccess soa(env);
582       return (soa.Decode<mirror::Object*>(obj1) == soa.Decode<mirror::Object*>(obj2))
583               ? JNI_TRUE : JNI_FALSE;
584     }
585   }
586 
AllocObject(JNIEnv * env,jclass java_class)587   static jobject AllocObject(JNIEnv* env, jclass java_class) {
588     CHECK_NON_NULL_ARGUMENT(java_class);
589     ScopedObjectAccess soa(env);
590     mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
591     if (c == nullptr) {
592       return nullptr;
593     }
594     if (c->IsStringClass()) {
595       gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
596       mirror::SetStringCountVisitor visitor(0);
597       return soa.AddLocalReference<jobject>(mirror::String::Alloc<true>(soa.Self(), 0,
598                                                                         allocator_type, visitor));
599     }
600     return soa.AddLocalReference<jobject>(c->AllocObject(soa.Self()));
601   }
602 
NewObject(JNIEnv * env,jclass java_class,jmethodID mid,...)603   static jobject NewObject(JNIEnv* env, jclass java_class, jmethodID mid, ...) {
604     va_list args;
605     va_start(args, mid);
606     CHECK_NON_NULL_ARGUMENT(java_class);
607     CHECK_NON_NULL_ARGUMENT(mid);
608     jobject result = NewObjectV(env, java_class, mid, args);
609     va_end(args);
610     return result;
611   }
612 
NewObjectV(JNIEnv * env,jclass java_class,jmethodID mid,va_list args)613   static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID mid, va_list args) {
614     CHECK_NON_NULL_ARGUMENT(java_class);
615     CHECK_NON_NULL_ARGUMENT(mid);
616     ScopedObjectAccess soa(env);
617     mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
618     if (c == nullptr) {
619       return nullptr;
620     }
621     if (c->IsStringClass()) {
622       // Replace calls to String.<init> with equivalent StringFactory call.
623       jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
624       return CallStaticObjectMethodV(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
625     }
626     mirror::Object* result = c->AllocObject(soa.Self());
627     if (result == nullptr) {
628       return nullptr;
629     }
630     jobject local_result = soa.AddLocalReference<jobject>(result);
631     CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
632     if (soa.Self()->IsExceptionPending()) {
633       return nullptr;
634     }
635     return local_result;
636   }
637 
NewObjectA(JNIEnv * env,jclass java_class,jmethodID mid,jvalue * args)638   static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID mid, jvalue* args) {
639     CHECK_NON_NULL_ARGUMENT(java_class);
640     CHECK_NON_NULL_ARGUMENT(mid);
641     ScopedObjectAccess soa(env);
642     mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(java_class));
643     if (c == nullptr) {
644       return nullptr;
645     }
646     if (c->IsStringClass()) {
647       // Replace calls to String.<init> with equivalent StringFactory call.
648       jmethodID sf_mid = WellKnownClasses::StringInitToStringFactoryMethodID(mid);
649       return CallStaticObjectMethodA(env, WellKnownClasses::java_lang_StringFactory, sf_mid, args);
650     }
651     mirror::Object* result = c->AllocObject(soa.Self());
652     if (result == nullptr) {
653       return nullptr;
654     }
655     jobject local_result = soa.AddLocalReference<jobjectArray>(result);
656     CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
657     if (soa.Self()->IsExceptionPending()) {
658       return nullptr;
659     }
660     return local_result;
661   }
662 
GetMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)663   static jmethodID GetMethodID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
664     CHECK_NON_NULL_ARGUMENT(java_class);
665     CHECK_NON_NULL_ARGUMENT(name);
666     CHECK_NON_NULL_ARGUMENT(sig);
667     ScopedObjectAccess soa(env);
668     return FindMethodID(soa, java_class, name, sig, false);
669   }
670 
GetStaticMethodID(JNIEnv * env,jclass java_class,const char * name,const char * sig)671   static jmethodID GetStaticMethodID(JNIEnv* env, jclass java_class, const char* name,
672                                      const char* sig) {
673     CHECK_NON_NULL_ARGUMENT(java_class);
674     CHECK_NON_NULL_ARGUMENT(name);
675     CHECK_NON_NULL_ARGUMENT(sig);
676     ScopedObjectAccess soa(env);
677     return FindMethodID(soa, java_class, name, sig, true);
678   }
679 
CallObjectMethod(JNIEnv * env,jobject obj,jmethodID mid,...)680   static jobject CallObjectMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
681     va_list ap;
682     va_start(ap, mid);
683     CHECK_NON_NULL_ARGUMENT(obj);
684     CHECK_NON_NULL_ARGUMENT(mid);
685     ScopedObjectAccess soa(env);
686     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
687     va_end(ap);
688     return soa.AddLocalReference<jobject>(result.GetL());
689   }
690 
CallObjectMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)691   static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
692     CHECK_NON_NULL_ARGUMENT(obj);
693     CHECK_NON_NULL_ARGUMENT(mid);
694     ScopedObjectAccess soa(env);
695     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args));
696     return soa.AddLocalReference<jobject>(result.GetL());
697   }
698 
CallObjectMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)699   static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
700     CHECK_NON_NULL_ARGUMENT(obj);
701     CHECK_NON_NULL_ARGUMENT(mid);
702     ScopedObjectAccess soa(env);
703     JValue result(InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args));
704     return soa.AddLocalReference<jobject>(result.GetL());
705   }
706 
CallBooleanMethod(JNIEnv * env,jobject obj,jmethodID mid,...)707   static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
708     va_list ap;
709     va_start(ap, mid);
710     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
711     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
712     ScopedObjectAccess soa(env);
713     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
714     va_end(ap);
715     return result.GetZ();
716   }
717 
CallBooleanMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)718   static jboolean CallBooleanMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
719     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
720     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
721     ScopedObjectAccess soa(env);
722     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetZ();
723   }
724 
CallBooleanMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)725   static jboolean CallBooleanMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
726     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
727     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
728     ScopedObjectAccess soa(env);
729     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetZ();
730   }
731 
CallByteMethod(JNIEnv * env,jobject obj,jmethodID mid,...)732   static jbyte CallByteMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
733     va_list ap;
734     va_start(ap, mid);
735     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
736     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
737     ScopedObjectAccess soa(env);
738     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
739     va_end(ap);
740     return result.GetB();
741   }
742 
CallByteMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)743   static jbyte CallByteMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
744     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
745     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
746     ScopedObjectAccess soa(env);
747     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetB();
748   }
749 
CallByteMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)750   static jbyte CallByteMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
751     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
752     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
753     ScopedObjectAccess soa(env);
754     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetB();
755   }
756 
CallCharMethod(JNIEnv * env,jobject obj,jmethodID mid,...)757   static jchar CallCharMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
758     va_list ap;
759     va_start(ap, mid);
760     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
761     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
762     ScopedObjectAccess soa(env);
763     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
764     va_end(ap);
765     return result.GetC();
766   }
767 
CallCharMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)768   static jchar CallCharMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
769     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
770     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
771     ScopedObjectAccess soa(env);
772     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetC();
773   }
774 
CallCharMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)775   static jchar CallCharMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
776     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
777     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
778     ScopedObjectAccess soa(env);
779     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetC();
780   }
781 
CallDoubleMethod(JNIEnv * env,jobject obj,jmethodID mid,...)782   static jdouble CallDoubleMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
783     va_list ap;
784     va_start(ap, mid);
785     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
786     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
787     ScopedObjectAccess soa(env);
788     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
789     va_end(ap);
790     return result.GetD();
791   }
792 
CallDoubleMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)793   static jdouble CallDoubleMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
794     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
795     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
796     ScopedObjectAccess soa(env);
797     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetD();
798   }
799 
CallDoubleMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)800   static jdouble CallDoubleMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
801     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
802     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
803     ScopedObjectAccess soa(env);
804     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetD();
805   }
806 
CallFloatMethod(JNIEnv * env,jobject obj,jmethodID mid,...)807   static jfloat CallFloatMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
808     va_list ap;
809     va_start(ap, mid);
810     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
811     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
812     ScopedObjectAccess soa(env);
813     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
814     va_end(ap);
815     return result.GetF();
816   }
817 
CallFloatMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)818   static jfloat CallFloatMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
819     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
820     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
821     ScopedObjectAccess soa(env);
822     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetF();
823   }
824 
CallFloatMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)825   static jfloat CallFloatMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
826     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
827     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
828     ScopedObjectAccess soa(env);
829     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetF();
830   }
831 
CallIntMethod(JNIEnv * env,jobject obj,jmethodID mid,...)832   static jint CallIntMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
833     va_list ap;
834     va_start(ap, mid);
835     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
836     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
837     ScopedObjectAccess soa(env);
838     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
839     va_end(ap);
840     return result.GetI();
841   }
842 
CallIntMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)843   static jint CallIntMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
844     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
845     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
846     ScopedObjectAccess soa(env);
847     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetI();
848   }
849 
CallIntMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)850   static jint CallIntMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
851     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
852     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
853     ScopedObjectAccess soa(env);
854     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetI();
855   }
856 
CallLongMethod(JNIEnv * env,jobject obj,jmethodID mid,...)857   static jlong CallLongMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
858     va_list ap;
859     va_start(ap, mid);
860     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
861     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
862     ScopedObjectAccess soa(env);
863     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
864     va_end(ap);
865     return result.GetJ();
866   }
867 
CallLongMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)868   static jlong CallLongMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
869     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
870     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
871     ScopedObjectAccess soa(env);
872     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetJ();
873   }
874 
CallLongMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)875   static jlong CallLongMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
876     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
877     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
878     ScopedObjectAccess soa(env);
879     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetJ();
880   }
881 
CallShortMethod(JNIEnv * env,jobject obj,jmethodID mid,...)882   static jshort CallShortMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
883     va_list ap;
884     va_start(ap, mid);
885     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
886     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
887     ScopedObjectAccess soa(env);
888     JValue result(InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap));
889     va_end(ap);
890     return result.GetS();
891   }
892 
CallShortMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)893   static jshort CallShortMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
894     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
895     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
896     ScopedObjectAccess soa(env);
897     return InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args).GetS();
898   }
899 
CallShortMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)900   static jshort CallShortMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
901     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
902     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
903     ScopedObjectAccess soa(env);
904     return InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args).GetS();
905   }
906 
CallVoidMethod(JNIEnv * env,jobject obj,jmethodID mid,...)907   static void CallVoidMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
908     va_list ap;
909     va_start(ap, mid);
910     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
911     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
912     ScopedObjectAccess soa(env);
913     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, ap);
914     va_end(ap);
915   }
916 
CallVoidMethodV(JNIEnv * env,jobject obj,jmethodID mid,va_list args)917   static void CallVoidMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
918     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
919     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
920     ScopedObjectAccess soa(env);
921     InvokeVirtualOrInterfaceWithVarArgs(soa, obj, mid, args);
922   }
923 
CallVoidMethodA(JNIEnv * env,jobject obj,jmethodID mid,jvalue * args)924   static void CallVoidMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
925     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
926     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
927     ScopedObjectAccess soa(env);
928     InvokeVirtualOrInterfaceWithJValues(soa, obj, mid, args);
929   }
930 
CallNonvirtualObjectMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)931   static jobject CallNonvirtualObjectMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
932     va_list ap;
933     va_start(ap, mid);
934     CHECK_NON_NULL_ARGUMENT(obj);
935     CHECK_NON_NULL_ARGUMENT(mid);
936     ScopedObjectAccess soa(env);
937     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
938     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
939     va_end(ap);
940     return local_result;
941   }
942 
CallNonvirtualObjectMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)943   static jobject CallNonvirtualObjectMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
944                                              va_list args) {
945     CHECK_NON_NULL_ARGUMENT(obj);
946     CHECK_NON_NULL_ARGUMENT(mid);
947     ScopedObjectAccess soa(env);
948     JValue result(InvokeWithVarArgs(soa, obj, mid, args));
949     return soa.AddLocalReference<jobject>(result.GetL());
950   }
951 
CallNonvirtualObjectMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)952   static jobject CallNonvirtualObjectMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
953                                              jvalue* args) {
954     CHECK_NON_NULL_ARGUMENT(obj);
955     CHECK_NON_NULL_ARGUMENT(mid);
956     ScopedObjectAccess soa(env);
957     JValue result(InvokeWithJValues(soa, obj, mid, args));
958     return soa.AddLocalReference<jobject>(result.GetL());
959   }
960 
CallNonvirtualBooleanMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)961   static jboolean CallNonvirtualBooleanMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid,
962                                               ...) {
963     va_list ap;
964     va_start(ap, mid);
965     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
966     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
967     ScopedObjectAccess soa(env);
968     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
969     va_end(ap);
970     return result.GetZ();
971   }
972 
CallNonvirtualBooleanMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)973   static jboolean CallNonvirtualBooleanMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
974                                                va_list args) {
975     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
976     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
977     ScopedObjectAccess soa(env);
978     return InvokeWithVarArgs(soa, obj, mid, args).GetZ();
979   }
980 
CallNonvirtualBooleanMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)981   static jboolean CallNonvirtualBooleanMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
982                                                jvalue* args) {
983     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
984     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
985     ScopedObjectAccess soa(env);
986     return InvokeWithJValues(soa, obj, mid, args).GetZ();
987   }
988 
CallNonvirtualByteMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)989   static jbyte CallNonvirtualByteMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
990     va_list ap;
991     va_start(ap, mid);
992     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
993     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
994     ScopedObjectAccess soa(env);
995     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
996     va_end(ap);
997     return result.GetB();
998   }
999 
CallNonvirtualByteMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1000   static jbyte CallNonvirtualByteMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1001                                          va_list args) {
1002     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1003     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1004     ScopedObjectAccess soa(env);
1005     return InvokeWithVarArgs(soa, obj, mid, args).GetB();
1006   }
1007 
CallNonvirtualByteMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1008   static jbyte CallNonvirtualByteMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1009                                          jvalue* args) {
1010     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1011     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1012     ScopedObjectAccess soa(env);
1013     return InvokeWithJValues(soa, obj, mid, args).GetB();
1014   }
1015 
CallNonvirtualCharMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1016   static jchar CallNonvirtualCharMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1017     va_list ap;
1018     va_start(ap, mid);
1019     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1020     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1021     ScopedObjectAccess soa(env);
1022     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1023     va_end(ap);
1024     return result.GetC();
1025   }
1026 
CallNonvirtualCharMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1027   static jchar CallNonvirtualCharMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1028                                          va_list args) {
1029     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1030     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1031     ScopedObjectAccess soa(env);
1032     return InvokeWithVarArgs(soa, obj, mid, args).GetC();
1033   }
1034 
CallNonvirtualCharMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1035   static jchar CallNonvirtualCharMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1036                                          jvalue* args) {
1037     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1038     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1039     ScopedObjectAccess soa(env);
1040     return InvokeWithJValues(soa, obj, mid, args).GetC();
1041   }
1042 
CallNonvirtualShortMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1043   static jshort CallNonvirtualShortMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1044     va_list ap;
1045     va_start(ap, mid);
1046     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1047     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1048     ScopedObjectAccess soa(env);
1049     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1050     va_end(ap);
1051     return result.GetS();
1052   }
1053 
CallNonvirtualShortMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1054   static jshort CallNonvirtualShortMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1055                                            va_list args) {
1056     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1057     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1058     ScopedObjectAccess soa(env);
1059     return InvokeWithVarArgs(soa, obj, mid, args).GetS();
1060   }
1061 
CallNonvirtualShortMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1062   static jshort CallNonvirtualShortMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1063                                            jvalue* args) {
1064     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1065     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1066     ScopedObjectAccess soa(env);
1067     return InvokeWithJValues(soa, obj, mid, args).GetS();
1068   }
1069 
CallNonvirtualIntMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1070   static jint CallNonvirtualIntMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1071     va_list ap;
1072     va_start(ap, mid);
1073     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1074     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1075     ScopedObjectAccess soa(env);
1076     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1077     va_end(ap);
1078     return result.GetI();
1079   }
1080 
CallNonvirtualIntMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1081   static jint CallNonvirtualIntMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1082                                        va_list args) {
1083     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1084     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1085     ScopedObjectAccess soa(env);
1086     return InvokeWithVarArgs(soa, obj, mid, args).GetI();
1087   }
1088 
CallNonvirtualIntMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1089   static jint CallNonvirtualIntMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1090                                        jvalue* args) {
1091     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1092     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1093     ScopedObjectAccess soa(env);
1094     return InvokeWithJValues(soa, obj, mid, args).GetI();
1095   }
1096 
CallNonvirtualLongMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1097   static jlong CallNonvirtualLongMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1098     va_list ap;
1099     va_start(ap, mid);
1100     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1101     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1102     ScopedObjectAccess soa(env);
1103     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1104     va_end(ap);
1105     return result.GetJ();
1106   }
1107 
CallNonvirtualLongMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1108   static jlong CallNonvirtualLongMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1109                                          va_list args) {
1110     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1111     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1112     ScopedObjectAccess soa(env);
1113     return InvokeWithVarArgs(soa, obj, mid, args).GetJ();
1114   }
1115 
CallNonvirtualLongMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1116   static jlong CallNonvirtualLongMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1117                                          jvalue* args) {
1118     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1119     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1120     ScopedObjectAccess soa(env);
1121     return InvokeWithJValues(soa, obj, mid, args).GetJ();
1122   }
1123 
CallNonvirtualFloatMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1124   static jfloat CallNonvirtualFloatMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1125     va_list ap;
1126     va_start(ap, mid);
1127     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1128     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1129     ScopedObjectAccess soa(env);
1130     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1131     va_end(ap);
1132     return result.GetF();
1133   }
1134 
CallNonvirtualFloatMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1135   static jfloat CallNonvirtualFloatMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1136                                            va_list args) {
1137     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1138     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1139     ScopedObjectAccess soa(env);
1140     return InvokeWithVarArgs(soa, obj, mid, args).GetF();
1141   }
1142 
CallNonvirtualFloatMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1143   static jfloat CallNonvirtualFloatMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1144                                            jvalue* args) {
1145     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1146     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1147     ScopedObjectAccess soa(env);
1148     return InvokeWithJValues(soa, obj, mid, args).GetF();
1149   }
1150 
CallNonvirtualDoubleMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1151   static jdouble CallNonvirtualDoubleMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1152     va_list ap;
1153     va_start(ap, mid);
1154     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1155     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1156     ScopedObjectAccess soa(env);
1157     JValue result(InvokeWithVarArgs(soa, obj, mid, ap));
1158     va_end(ap);
1159     return result.GetD();
1160   }
1161 
CallNonvirtualDoubleMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1162   static jdouble CallNonvirtualDoubleMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1163                                              va_list args) {
1164     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1165     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1166     ScopedObjectAccess soa(env);
1167     return InvokeWithVarArgs(soa, obj, mid, args).GetD();
1168   }
1169 
CallNonvirtualDoubleMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1170   static jdouble CallNonvirtualDoubleMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1171                                              jvalue* args) {
1172     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(obj);
1173     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1174     ScopedObjectAccess soa(env);
1175     return InvokeWithJValues(soa, obj, mid, args).GetD();
1176   }
1177 
CallNonvirtualVoidMethod(JNIEnv * env,jobject obj,jclass,jmethodID mid,...)1178   static void CallNonvirtualVoidMethod(JNIEnv* env, jobject obj, jclass, jmethodID mid, ...) {
1179     va_list ap;
1180     va_start(ap, mid);
1181     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1182     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1183     ScopedObjectAccess soa(env);
1184     InvokeWithVarArgs(soa, obj, mid, ap);
1185     va_end(ap);
1186   }
1187 
CallNonvirtualVoidMethodV(JNIEnv * env,jobject obj,jclass,jmethodID mid,va_list args)1188   static void CallNonvirtualVoidMethodV(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1189                                         va_list args) {
1190     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1191     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1192     ScopedObjectAccess soa(env);
1193     InvokeWithVarArgs(soa, obj, mid, args);
1194   }
1195 
CallNonvirtualVoidMethodA(JNIEnv * env,jobject obj,jclass,jmethodID mid,jvalue * args)1196   static void CallNonvirtualVoidMethodA(JNIEnv* env, jobject obj, jclass, jmethodID mid,
1197                                         jvalue* args) {
1198     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(obj);
1199     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1200     ScopedObjectAccess soa(env);
1201     InvokeWithJValues(soa, obj, mid, args);
1202   }
1203 
GetFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1204   static jfieldID GetFieldID(JNIEnv* env, jclass java_class, const char* name, const char* sig) {
1205     CHECK_NON_NULL_ARGUMENT(java_class);
1206     CHECK_NON_NULL_ARGUMENT(name);
1207     CHECK_NON_NULL_ARGUMENT(sig);
1208     ScopedObjectAccess soa(env);
1209     return FindFieldID(soa, java_class, name, sig, false);
1210   }
1211 
GetStaticFieldID(JNIEnv * env,jclass java_class,const char * name,const char * sig)1212   static jfieldID GetStaticFieldID(JNIEnv* env, jclass java_class, const char* name,
1213                                    const char* sig) {
1214     CHECK_NON_NULL_ARGUMENT(java_class);
1215     CHECK_NON_NULL_ARGUMENT(name);
1216     CHECK_NON_NULL_ARGUMENT(sig);
1217     ScopedObjectAccess soa(env);
1218     return FindFieldID(soa, java_class, name, sig, true);
1219   }
1220 
GetObjectField(JNIEnv * env,jobject obj,jfieldID fid)1221   static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
1222     CHECK_NON_NULL_ARGUMENT(obj);
1223     CHECK_NON_NULL_ARGUMENT(fid);
1224     ScopedObjectAccess soa(env);
1225     mirror::Object* o = soa.Decode<mirror::Object*>(obj);
1226     ArtField* f = soa.DecodeField(fid);
1227     return soa.AddLocalReference<jobject>(f->GetObject(o));
1228   }
1229 
GetStaticObjectField(JNIEnv * env,jclass,jfieldID fid)1230   static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
1231     CHECK_NON_NULL_ARGUMENT(fid);
1232     ScopedObjectAccess soa(env);
1233     ArtField* f = soa.DecodeField(fid);
1234     return soa.AddLocalReference<jobject>(f->GetObject(f->GetDeclaringClass()));
1235   }
1236 
SetObjectField(JNIEnv * env,jobject java_object,jfieldID fid,jobject java_value)1237   static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
1238     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_object);
1239     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1240     ScopedObjectAccess soa(env);
1241     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
1242     mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1243     ArtField* f = soa.DecodeField(fid);
1244     f->SetObject<false>(o, v);
1245   }
1246 
SetStaticObjectField(JNIEnv * env,jclass,jfieldID fid,jobject java_value)1247   static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
1248     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid);
1249     ScopedObjectAccess soa(env);
1250     mirror::Object* v = soa.Decode<mirror::Object*>(java_value);
1251     ArtField* f = soa.DecodeField(fid);
1252     f->SetObject<false>(f->GetDeclaringClass(), v);
1253   }
1254 
1255 #define GET_PRIMITIVE_FIELD(fn, instance) \
1256   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(instance); \
1257   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1258   ScopedObjectAccess soa(env); \
1259   mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1260   ArtField* f = soa.DecodeField(fid); \
1261   return f->Get ##fn (o)
1262 
1263 #define GET_STATIC_PRIMITIVE_FIELD(fn) \
1264   CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(fid); \
1265   ScopedObjectAccess soa(env); \
1266   ArtField* f = soa.DecodeField(fid); \
1267   return f->Get ##fn (f->GetDeclaringClass())
1268 
1269 #define SET_PRIMITIVE_FIELD(fn, instance, value) \
1270   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(instance); \
1271   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1272   ScopedObjectAccess soa(env); \
1273   mirror::Object* o = soa.Decode<mirror::Object*>(instance); \
1274   ArtField* f = soa.DecodeField(fid); \
1275   f->Set ##fn <false>(o, value)
1276 
1277 #define SET_STATIC_PRIMITIVE_FIELD(fn, value) \
1278   CHECK_NON_NULL_ARGUMENT_RETURN_VOID(fid); \
1279   ScopedObjectAccess soa(env); \
1280   ArtField* f = soa.DecodeField(fid); \
1281   f->Set ##fn <false>(f->GetDeclaringClass(), value)
1282 
GetBooleanField(JNIEnv * env,jobject obj,jfieldID fid)1283   static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
1284     GET_PRIMITIVE_FIELD(Boolean, obj);
1285   }
1286 
GetByteField(JNIEnv * env,jobject obj,jfieldID fid)1287   static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
1288     GET_PRIMITIVE_FIELD(Byte, obj);
1289   }
1290 
GetCharField(JNIEnv * env,jobject obj,jfieldID fid)1291   static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
1292     GET_PRIMITIVE_FIELD(Char, obj);
1293   }
1294 
GetShortField(JNIEnv * env,jobject obj,jfieldID fid)1295   static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
1296     GET_PRIMITIVE_FIELD(Short, obj);
1297   }
1298 
GetIntField(JNIEnv * env,jobject obj,jfieldID fid)1299   static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
1300     GET_PRIMITIVE_FIELD(Int, obj);
1301   }
1302 
GetLongField(JNIEnv * env,jobject obj,jfieldID fid)1303   static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
1304     GET_PRIMITIVE_FIELD(Long, obj);
1305   }
1306 
GetFloatField(JNIEnv * env,jobject obj,jfieldID fid)1307   static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
1308     GET_PRIMITIVE_FIELD(Float, obj);
1309   }
1310 
GetDoubleField(JNIEnv * env,jobject obj,jfieldID fid)1311   static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
1312     GET_PRIMITIVE_FIELD(Double, obj);
1313   }
1314 
GetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid)1315   static jboolean GetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid) {
1316     GET_STATIC_PRIMITIVE_FIELD(Boolean);
1317   }
1318 
GetStaticByteField(JNIEnv * env,jclass,jfieldID fid)1319   static jbyte GetStaticByteField(JNIEnv* env, jclass, jfieldID fid) {
1320     GET_STATIC_PRIMITIVE_FIELD(Byte);
1321   }
1322 
GetStaticCharField(JNIEnv * env,jclass,jfieldID fid)1323   static jchar GetStaticCharField(JNIEnv* env, jclass, jfieldID fid) {
1324     GET_STATIC_PRIMITIVE_FIELD(Char);
1325   }
1326 
GetStaticShortField(JNIEnv * env,jclass,jfieldID fid)1327   static jshort GetStaticShortField(JNIEnv* env, jclass, jfieldID fid) {
1328     GET_STATIC_PRIMITIVE_FIELD(Short);
1329   }
1330 
GetStaticIntField(JNIEnv * env,jclass,jfieldID fid)1331   static jint GetStaticIntField(JNIEnv* env, jclass, jfieldID fid) {
1332     GET_STATIC_PRIMITIVE_FIELD(Int);
1333   }
1334 
GetStaticLongField(JNIEnv * env,jclass,jfieldID fid)1335   static jlong GetStaticLongField(JNIEnv* env, jclass, jfieldID fid) {
1336     GET_STATIC_PRIMITIVE_FIELD(Long);
1337   }
1338 
GetStaticFloatField(JNIEnv * env,jclass,jfieldID fid)1339   static jfloat GetStaticFloatField(JNIEnv* env, jclass, jfieldID fid) {
1340     GET_STATIC_PRIMITIVE_FIELD(Float);
1341   }
1342 
GetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid)1343   static jdouble GetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid) {
1344     GET_STATIC_PRIMITIVE_FIELD(Double);
1345   }
1346 
SetBooleanField(JNIEnv * env,jobject obj,jfieldID fid,jboolean v)1347   static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
1348     SET_PRIMITIVE_FIELD(Boolean, obj, v);
1349   }
1350 
SetByteField(JNIEnv * env,jobject obj,jfieldID fid,jbyte v)1351   static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
1352     SET_PRIMITIVE_FIELD(Byte, obj, v);
1353   }
1354 
SetCharField(JNIEnv * env,jobject obj,jfieldID fid,jchar v)1355   static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
1356     SET_PRIMITIVE_FIELD(Char, obj, v);
1357   }
1358 
SetFloatField(JNIEnv * env,jobject obj,jfieldID fid,jfloat v)1359   static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
1360     SET_PRIMITIVE_FIELD(Float, obj, v);
1361   }
1362 
SetDoubleField(JNIEnv * env,jobject obj,jfieldID fid,jdouble v)1363   static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
1364     SET_PRIMITIVE_FIELD(Double, obj, v);
1365   }
1366 
SetIntField(JNIEnv * env,jobject obj,jfieldID fid,jint v)1367   static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
1368     SET_PRIMITIVE_FIELD(Int, obj, v);
1369   }
1370 
SetLongField(JNIEnv * env,jobject obj,jfieldID fid,jlong v)1371   static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
1372     SET_PRIMITIVE_FIELD(Long, obj, v);
1373   }
1374 
SetShortField(JNIEnv * env,jobject obj,jfieldID fid,jshort v)1375   static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
1376     SET_PRIMITIVE_FIELD(Short, obj, v);
1377   }
1378 
SetStaticBooleanField(JNIEnv * env,jclass,jfieldID fid,jboolean v)1379   static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
1380     SET_STATIC_PRIMITIVE_FIELD(Boolean, v);
1381   }
1382 
SetStaticByteField(JNIEnv * env,jclass,jfieldID fid,jbyte v)1383   static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
1384     SET_STATIC_PRIMITIVE_FIELD(Byte, v);
1385   }
1386 
SetStaticCharField(JNIEnv * env,jclass,jfieldID fid,jchar v)1387   static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
1388     SET_STATIC_PRIMITIVE_FIELD(Char, v);
1389   }
1390 
SetStaticFloatField(JNIEnv * env,jclass,jfieldID fid,jfloat v)1391   static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
1392     SET_STATIC_PRIMITIVE_FIELD(Float, v);
1393   }
1394 
SetStaticDoubleField(JNIEnv * env,jclass,jfieldID fid,jdouble v)1395   static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
1396     SET_STATIC_PRIMITIVE_FIELD(Double, v);
1397   }
1398 
SetStaticIntField(JNIEnv * env,jclass,jfieldID fid,jint v)1399   static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
1400     SET_STATIC_PRIMITIVE_FIELD(Int, v);
1401   }
1402 
SetStaticLongField(JNIEnv * env,jclass,jfieldID fid,jlong v)1403   static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
1404     SET_STATIC_PRIMITIVE_FIELD(Long, v);
1405   }
1406 
SetStaticShortField(JNIEnv * env,jclass,jfieldID fid,jshort v)1407   static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
1408     SET_STATIC_PRIMITIVE_FIELD(Short, v);
1409   }
1410 
CallStaticObjectMethod(JNIEnv * env,jclass,jmethodID mid,...)1411   static jobject CallStaticObjectMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1412     va_list ap;
1413     va_start(ap, mid);
1414     CHECK_NON_NULL_ARGUMENT(mid);
1415     ScopedObjectAccess soa(env);
1416     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1417     jobject local_result = soa.AddLocalReference<jobject>(result.GetL());
1418     va_end(ap);
1419     return local_result;
1420   }
1421 
CallStaticObjectMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1422   static jobject CallStaticObjectMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1423     CHECK_NON_NULL_ARGUMENT(mid);
1424     ScopedObjectAccess soa(env);
1425     JValue result(InvokeWithVarArgs(soa, nullptr, mid, args));
1426     return soa.AddLocalReference<jobject>(result.GetL());
1427   }
1428 
CallStaticObjectMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1429   static jobject CallStaticObjectMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1430     CHECK_NON_NULL_ARGUMENT(mid);
1431     ScopedObjectAccess soa(env);
1432     JValue result(InvokeWithJValues(soa, nullptr, mid, args));
1433     return soa.AddLocalReference<jobject>(result.GetL());
1434   }
1435 
CallStaticBooleanMethod(JNIEnv * env,jclass,jmethodID mid,...)1436   static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1437     va_list ap;
1438     va_start(ap, mid);
1439     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1440     ScopedObjectAccess soa(env);
1441     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1442     va_end(ap);
1443     return result.GetZ();
1444   }
1445 
CallStaticBooleanMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1446   static jboolean CallStaticBooleanMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1447     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1448     ScopedObjectAccess soa(env);
1449     return InvokeWithVarArgs(soa, nullptr, mid, args).GetZ();
1450   }
1451 
CallStaticBooleanMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1452   static jboolean CallStaticBooleanMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1453     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1454     ScopedObjectAccess soa(env);
1455     return InvokeWithJValues(soa, nullptr, mid, args).GetZ();
1456   }
1457 
CallStaticByteMethod(JNIEnv * env,jclass,jmethodID mid,...)1458   static jbyte CallStaticByteMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1459     va_list ap;
1460     va_start(ap, mid);
1461     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1462     ScopedObjectAccess soa(env);
1463     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1464     va_end(ap);
1465     return result.GetB();
1466   }
1467 
CallStaticByteMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1468   static jbyte CallStaticByteMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1469     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1470     ScopedObjectAccess soa(env);
1471     return InvokeWithVarArgs(soa, nullptr, mid, args).GetB();
1472   }
1473 
CallStaticByteMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1474   static jbyte CallStaticByteMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1475     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1476     ScopedObjectAccess soa(env);
1477     return InvokeWithJValues(soa, nullptr, mid, args).GetB();
1478   }
1479 
CallStaticCharMethod(JNIEnv * env,jclass,jmethodID mid,...)1480   static jchar CallStaticCharMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1481     va_list ap;
1482     va_start(ap, mid);
1483     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1484     ScopedObjectAccess soa(env);
1485     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1486     va_end(ap);
1487     return result.GetC();
1488   }
1489 
CallStaticCharMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1490   static jchar CallStaticCharMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1491     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1492     ScopedObjectAccess soa(env);
1493     return InvokeWithVarArgs(soa, nullptr, mid, args).GetC();
1494   }
1495 
CallStaticCharMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1496   static jchar CallStaticCharMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1497     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1498     ScopedObjectAccess soa(env);
1499     return InvokeWithJValues(soa, nullptr, mid, args).GetC();
1500   }
1501 
CallStaticShortMethod(JNIEnv * env,jclass,jmethodID mid,...)1502   static jshort CallStaticShortMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1503     va_list ap;
1504     va_start(ap, mid);
1505     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1506     ScopedObjectAccess soa(env);
1507     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1508     va_end(ap);
1509     return result.GetS();
1510   }
1511 
CallStaticShortMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1512   static jshort CallStaticShortMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1513     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1514     ScopedObjectAccess soa(env);
1515     return InvokeWithVarArgs(soa, nullptr, mid, args).GetS();
1516   }
1517 
CallStaticShortMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1518   static jshort CallStaticShortMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1519     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1520     ScopedObjectAccess soa(env);
1521     return InvokeWithJValues(soa, nullptr, mid, args).GetS();
1522   }
1523 
CallStaticIntMethod(JNIEnv * env,jclass,jmethodID mid,...)1524   static jint CallStaticIntMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1525     va_list ap;
1526     va_start(ap, mid);
1527     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1528     ScopedObjectAccess soa(env);
1529     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1530     va_end(ap);
1531     return result.GetI();
1532   }
1533 
CallStaticIntMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1534   static jint CallStaticIntMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1535     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1536     ScopedObjectAccess soa(env);
1537     return InvokeWithVarArgs(soa, nullptr, mid, args).GetI();
1538   }
1539 
CallStaticIntMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1540   static jint CallStaticIntMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1541     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1542     ScopedObjectAccess soa(env);
1543     return InvokeWithJValues(soa, nullptr, mid, args).GetI();
1544   }
1545 
CallStaticLongMethod(JNIEnv * env,jclass,jmethodID mid,...)1546   static jlong CallStaticLongMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1547     va_list ap;
1548     va_start(ap, mid);
1549     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1550     ScopedObjectAccess soa(env);
1551     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1552     va_end(ap);
1553     return result.GetJ();
1554   }
1555 
CallStaticLongMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1556   static jlong CallStaticLongMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1557     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1558     ScopedObjectAccess soa(env);
1559     return InvokeWithVarArgs(soa, nullptr, mid, args).GetJ();
1560   }
1561 
CallStaticLongMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1562   static jlong CallStaticLongMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1563     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1564     ScopedObjectAccess soa(env);
1565     return InvokeWithJValues(soa, nullptr, mid, args).GetJ();
1566   }
1567 
CallStaticFloatMethod(JNIEnv * env,jclass,jmethodID mid,...)1568   static jfloat CallStaticFloatMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1569     va_list ap;
1570     va_start(ap, mid);
1571     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1572     ScopedObjectAccess soa(env);
1573     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1574     va_end(ap);
1575     return result.GetF();
1576   }
1577 
CallStaticFloatMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1578   static jfloat CallStaticFloatMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1579     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1580     ScopedObjectAccess soa(env);
1581     return InvokeWithVarArgs(soa, nullptr, mid, args).GetF();
1582   }
1583 
CallStaticFloatMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1584   static jfloat CallStaticFloatMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1585     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1586     ScopedObjectAccess soa(env);
1587     return InvokeWithJValues(soa, nullptr, mid, args).GetF();
1588   }
1589 
CallStaticDoubleMethod(JNIEnv * env,jclass,jmethodID mid,...)1590   static jdouble CallStaticDoubleMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1591     va_list ap;
1592     va_start(ap, mid);
1593     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1594     ScopedObjectAccess soa(env);
1595     JValue result(InvokeWithVarArgs(soa, nullptr, mid, ap));
1596     va_end(ap);
1597     return result.GetD();
1598   }
1599 
CallStaticDoubleMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1600   static jdouble CallStaticDoubleMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1601     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1602     ScopedObjectAccess soa(env);
1603     return InvokeWithVarArgs(soa, nullptr, mid, args).GetD();
1604   }
1605 
CallStaticDoubleMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1606   static jdouble CallStaticDoubleMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1607     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(mid);
1608     ScopedObjectAccess soa(env);
1609     return InvokeWithJValues(soa, nullptr, mid, args).GetD();
1610   }
1611 
CallStaticVoidMethod(JNIEnv * env,jclass,jmethodID mid,...)1612   static void CallStaticVoidMethod(JNIEnv* env, jclass, jmethodID mid, ...) {
1613     va_list ap;
1614     va_start(ap, mid);
1615     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1616     ScopedObjectAccess soa(env);
1617     InvokeWithVarArgs(soa, nullptr, mid, ap);
1618     va_end(ap);
1619   }
1620 
CallStaticVoidMethodV(JNIEnv * env,jclass,jmethodID mid,va_list args)1621   static void CallStaticVoidMethodV(JNIEnv* env, jclass, jmethodID mid, va_list args) {
1622     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1623     ScopedObjectAccess soa(env);
1624     InvokeWithVarArgs(soa, nullptr, mid, args);
1625   }
1626 
CallStaticVoidMethodA(JNIEnv * env,jclass,jmethodID mid,jvalue * args)1627   static void CallStaticVoidMethodA(JNIEnv* env, jclass, jmethodID mid, jvalue* args) {
1628     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(mid);
1629     ScopedObjectAccess soa(env);
1630     InvokeWithJValues(soa, nullptr, mid, args);
1631   }
1632 
NewString(JNIEnv * env,const jchar * chars,jsize char_count)1633   static jstring NewString(JNIEnv* env, const jchar* chars, jsize char_count) {
1634     if (UNLIKELY(char_count < 0)) {
1635       JavaVmExtFromEnv(env)->JniAbortF("NewString", "char_count < 0: %d", char_count);
1636       return nullptr;
1637     }
1638     if (UNLIKELY(chars == nullptr && char_count > 0)) {
1639       JavaVmExtFromEnv(env)->JniAbortF("NewString", "chars == null && char_count > 0");
1640       return nullptr;
1641     }
1642     ScopedObjectAccess soa(env);
1643     mirror::String* result = mirror::String::AllocFromUtf16(soa.Self(), char_count, chars);
1644     return soa.AddLocalReference<jstring>(result);
1645   }
1646 
NewStringUTF(JNIEnv * env,const char * utf)1647   static jstring NewStringUTF(JNIEnv* env, const char* utf) {
1648     if (utf == nullptr) {
1649       return nullptr;
1650     }
1651     ScopedObjectAccess soa(env);
1652     mirror::String* result = mirror::String::AllocFromModifiedUtf8(soa.Self(), utf);
1653     return soa.AddLocalReference<jstring>(result);
1654   }
1655 
GetStringLength(JNIEnv * env,jstring java_string)1656   static jsize GetStringLength(JNIEnv* env, jstring java_string) {
1657     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1658     ScopedObjectAccess soa(env);
1659     return soa.Decode<mirror::String*>(java_string)->GetLength();
1660   }
1661 
GetStringUTFLength(JNIEnv * env,jstring java_string)1662   static jsize GetStringUTFLength(JNIEnv* env, jstring java_string) {
1663     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_string);
1664     ScopedObjectAccess soa(env);
1665     return soa.Decode<mirror::String*>(java_string)->GetUtfLength();
1666   }
1667 
GetStringRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,jchar * buf)1668   static void GetStringRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1669                               jchar* buf) {
1670     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1671     ScopedObjectAccess soa(env);
1672     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1673     if (start < 0 || length < 0 || start + length > s->GetLength()) {
1674       ThrowSIOOBE(soa, start, length, s->GetLength());
1675     } else {
1676       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1677       const jchar* chars = s->GetValue();
1678       memcpy(buf, chars + start, length * sizeof(jchar));
1679     }
1680   }
1681 
GetStringUTFRegion(JNIEnv * env,jstring java_string,jsize start,jsize length,char * buf)1682   static void GetStringUTFRegion(JNIEnv* env, jstring java_string, jsize start, jsize length,
1683                                  char* buf) {
1684     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1685     ScopedObjectAccess soa(env);
1686     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1687     if (start < 0 || length < 0 || start + length > s->GetLength()) {
1688       ThrowSIOOBE(soa, start, length, s->GetLength());
1689     } else {
1690       CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
1691       const jchar* chars = s->GetValue();
1692       ConvertUtf16ToModifiedUtf8(buf, chars + start, length);
1693     }
1694   }
1695 
GetStringChars(JNIEnv * env,jstring java_string,jboolean * is_copy)1696   static const jchar* GetStringChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1697     CHECK_NON_NULL_ARGUMENT(java_string);
1698     ScopedObjectAccess soa(env);
1699     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1700     gc::Heap* heap = Runtime::Current()->GetHeap();
1701     if (heap->IsMovableObject(s)) {
1702       jchar* chars = new jchar[s->GetLength()];
1703       memcpy(chars, s->GetValue(), sizeof(jchar) * s->GetLength());
1704       if (is_copy != nullptr) {
1705         *is_copy = JNI_TRUE;
1706       }
1707       return chars;
1708     }
1709     if (is_copy != nullptr) {
1710       *is_copy = JNI_FALSE;
1711     }
1712     return static_cast<jchar*>(s->GetValue());
1713   }
1714 
ReleaseStringChars(JNIEnv * env,jstring java_string,const jchar * chars)1715   static void ReleaseStringChars(JNIEnv* env, jstring java_string, const jchar* chars) {
1716     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1717     ScopedObjectAccess soa(env);
1718     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1719     if (chars != s->GetValue()) {
1720       delete[] chars;
1721     }
1722   }
1723 
GetStringCritical(JNIEnv * env,jstring java_string,jboolean * is_copy)1724   static const jchar* GetStringCritical(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1725     CHECK_NON_NULL_ARGUMENT(java_string);
1726     ScopedObjectAccess soa(env);
1727     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1728     gc::Heap* heap = Runtime::Current()->GetHeap();
1729     if (heap->IsMovableObject(s)) {
1730       StackHandleScope<1> hs(soa.Self());
1731       HandleWrapper<mirror::String> h(hs.NewHandleWrapper(&s));
1732       heap->IncrementDisableMovingGC(soa.Self());
1733     }
1734     if (is_copy != nullptr) {
1735       *is_copy = JNI_FALSE;
1736     }
1737     return static_cast<jchar*>(s->GetValue());
1738   }
1739 
ReleaseStringCritical(JNIEnv * env,jstring java_string,const jchar * chars)1740   static void ReleaseStringCritical(JNIEnv* env, jstring java_string, const jchar* chars) {
1741     UNUSED(chars);
1742     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_string);
1743     ScopedObjectAccess soa(env);
1744     gc::Heap* heap = Runtime::Current()->GetHeap();
1745     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1746     if (heap->IsMovableObject(s)) {
1747       heap->DecrementDisableMovingGC(soa.Self());
1748     }
1749   }
1750 
GetStringUTFChars(JNIEnv * env,jstring java_string,jboolean * is_copy)1751   static const char* GetStringUTFChars(JNIEnv* env, jstring java_string, jboolean* is_copy) {
1752     if (java_string == nullptr) {
1753       return nullptr;
1754     }
1755     if (is_copy != nullptr) {
1756       *is_copy = JNI_TRUE;
1757     }
1758     ScopedObjectAccess soa(env);
1759     mirror::String* s = soa.Decode<mirror::String*>(java_string);
1760     size_t byte_count = s->GetUtfLength();
1761     char* bytes = new char[byte_count + 1];
1762     CHECK(bytes != nullptr);  // bionic aborts anyway.
1763     const uint16_t* chars = s->GetValue();
1764     ConvertUtf16ToModifiedUtf8(bytes, chars, s->GetLength());
1765     bytes[byte_count] = '\0';
1766     return bytes;
1767   }
1768 
ReleaseStringUTFChars(JNIEnv *,jstring,const char * chars)1769   static void ReleaseStringUTFChars(JNIEnv*, jstring, const char* chars) {
1770     delete[] chars;
1771   }
1772 
GetArrayLength(JNIEnv * env,jarray java_array)1773   static jsize GetArrayLength(JNIEnv* env, jarray java_array) {
1774     CHECK_NON_NULL_ARGUMENT_RETURN_ZERO(java_array);
1775     ScopedObjectAccess soa(env);
1776     mirror::Object* obj = soa.Decode<mirror::Object*>(java_array);
1777     if (UNLIKELY(!obj->IsArrayInstance())) {
1778       soa.Vm()->JniAbortF("GetArrayLength", "not an array: %s", PrettyTypeOf(obj).c_str());
1779       return 0;
1780     }
1781     mirror::Array* array = obj->AsArray();
1782     return array->GetLength();
1783   }
1784 
GetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index)1785   static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
1786     CHECK_NON_NULL_ARGUMENT(java_array);
1787     ScopedObjectAccess soa(env);
1788     mirror::ObjectArray<mirror::Object>* array =
1789         soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1790     return soa.AddLocalReference<jobject>(array->Get(index));
1791   }
1792 
SetObjectArrayElement(JNIEnv * env,jobjectArray java_array,jsize index,jobject java_value)1793   static void SetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index,
1794                                     jobject java_value) {
1795     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1796     ScopedObjectAccess soa(env);
1797     mirror::ObjectArray<mirror::Object>* array =
1798         soa.Decode<mirror::ObjectArray<mirror::Object>*>(java_array);
1799     mirror::Object* value = soa.Decode<mirror::Object*>(java_value);
1800     array->Set<false>(index, value);
1801   }
1802 
NewBooleanArray(JNIEnv * env,jsize length)1803   static jbooleanArray NewBooleanArray(JNIEnv* env, jsize length) {
1804     return NewPrimitiveArray<jbooleanArray, mirror::BooleanArray>(env, length);
1805   }
1806 
NewByteArray(JNIEnv * env,jsize length)1807   static jbyteArray NewByteArray(JNIEnv* env, jsize length) {
1808     return NewPrimitiveArray<jbyteArray, mirror::ByteArray>(env, length);
1809   }
1810 
NewCharArray(JNIEnv * env,jsize length)1811   static jcharArray NewCharArray(JNIEnv* env, jsize length) {
1812     return NewPrimitiveArray<jcharArray, mirror::CharArray>(env, length);
1813   }
1814 
NewDoubleArray(JNIEnv * env,jsize length)1815   static jdoubleArray NewDoubleArray(JNIEnv* env, jsize length) {
1816     return NewPrimitiveArray<jdoubleArray, mirror::DoubleArray>(env, length);
1817   }
1818 
NewFloatArray(JNIEnv * env,jsize length)1819   static jfloatArray NewFloatArray(JNIEnv* env, jsize length) {
1820     return NewPrimitiveArray<jfloatArray, mirror::FloatArray>(env, length);
1821   }
1822 
NewIntArray(JNIEnv * env,jsize length)1823   static jintArray NewIntArray(JNIEnv* env, jsize length) {
1824     return NewPrimitiveArray<jintArray, mirror::IntArray>(env, length);
1825   }
1826 
NewLongArray(JNIEnv * env,jsize length)1827   static jlongArray NewLongArray(JNIEnv* env, jsize length) {
1828     return NewPrimitiveArray<jlongArray, mirror::LongArray>(env, length);
1829   }
1830 
NewObjectArray(JNIEnv * env,jsize length,jclass element_jclass,jobject initial_element)1831   static jobjectArray NewObjectArray(JNIEnv* env, jsize length, jclass element_jclass,
1832                                      jobject initial_element) {
1833     if (UNLIKELY(length < 0)) {
1834       JavaVmExtFromEnv(env)->JniAbortF("NewObjectArray", "negative array length: %d", length);
1835       return nullptr;
1836     }
1837     CHECK_NON_NULL_ARGUMENT(element_jclass);
1838 
1839     // Compute the array class corresponding to the given element class.
1840     ScopedObjectAccess soa(env);
1841     mirror::Class* array_class;
1842     {
1843       mirror::Class* element_class = soa.Decode<mirror::Class*>(element_jclass);
1844       if (UNLIKELY(element_class->IsPrimitive())) {
1845         soa.Vm()->JniAbortF("NewObjectArray", "not an object type: %s",
1846                             PrettyDescriptor(element_class).c_str());
1847         return nullptr;
1848       }
1849       ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1850       array_class = class_linker->FindArrayClass(soa.Self(), &element_class);
1851       if (UNLIKELY(array_class == nullptr)) {
1852         return nullptr;
1853       }
1854     }
1855 
1856     // Allocate and initialize if necessary.
1857     mirror::ObjectArray<mirror::Object>* result =
1858         mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), array_class, length);
1859     if (result != nullptr && initial_element != nullptr) {
1860       mirror::Object* initial_object = soa.Decode<mirror::Object*>(initial_element);
1861       if (initial_object != nullptr) {
1862         mirror::Class* element_class = result->GetClass()->GetComponentType();
1863         if (UNLIKELY(!element_class->IsAssignableFrom(initial_object->GetClass()))) {
1864           soa.Vm()->JniAbortF("NewObjectArray", "cannot assign object of type '%s' to array with "
1865                               "element type of '%s'",
1866                               PrettyDescriptor(initial_object->GetClass()).c_str(),
1867                               PrettyDescriptor(element_class).c_str());
1868           return nullptr;
1869         } else {
1870           for (jsize i = 0; i < length; ++i) {
1871             result->SetWithoutChecks<false>(i, initial_object);
1872           }
1873         }
1874       }
1875     }
1876     return soa.AddLocalReference<jobjectArray>(result);
1877   }
1878 
NewShortArray(JNIEnv * env,jsize length)1879   static jshortArray NewShortArray(JNIEnv* env, jsize length) {
1880     return NewPrimitiveArray<jshortArray, mirror::ShortArray>(env, length);
1881   }
1882 
GetPrimitiveArrayCritical(JNIEnv * env,jarray java_array,jboolean * is_copy)1883   static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray java_array, jboolean* is_copy) {
1884     CHECK_NON_NULL_ARGUMENT(java_array);
1885     ScopedObjectAccess soa(env);
1886     mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1887     if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
1888       soa.Vm()->JniAbortF("GetPrimitiveArrayCritical", "expected primitive array, given %s",
1889                           PrettyDescriptor(array->GetClass()).c_str());
1890       return nullptr;
1891     }
1892     gc::Heap* heap = Runtime::Current()->GetHeap();
1893     if (heap->IsMovableObject(array)) {
1894       heap->IncrementDisableMovingGC(soa.Self());
1895       // Re-decode in case the object moved since IncrementDisableGC waits for GC to complete.
1896       array = soa.Decode<mirror::Array*>(java_array);
1897     }
1898     if (is_copy != nullptr) {
1899       *is_copy = JNI_FALSE;
1900     }
1901     return array->GetRawData(array->GetClass()->GetComponentSize(), 0);
1902   }
1903 
ReleasePrimitiveArrayCritical(JNIEnv * env,jarray java_array,void * elements,jint mode)1904   static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray java_array, void* elements,
1905                                             jint mode) {
1906     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
1907     ScopedObjectAccess soa(env);
1908     mirror::Array* array = soa.Decode<mirror::Array*>(java_array);
1909     if (UNLIKELY(!array->GetClass()->IsPrimitiveArray())) {
1910       soa.Vm()->JniAbortF("ReleasePrimitiveArrayCritical", "expected primitive array, given %s",
1911                           PrettyDescriptor(array->GetClass()).c_str());
1912       return;
1913     }
1914     const size_t component_size = array->GetClass()->GetComponentSize();
1915     ReleasePrimitiveArray(soa, array, component_size, elements, mode);
1916   }
1917 
GetBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * is_copy)1918   static jboolean* GetBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* is_copy) {
1919     return GetPrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, is_copy);
1920   }
1921 
GetByteArrayElements(JNIEnv * env,jbyteArray array,jboolean * is_copy)1922   static jbyte* GetByteArrayElements(JNIEnv* env, jbyteArray array, jboolean* is_copy) {
1923     return GetPrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, is_copy);
1924   }
1925 
GetCharArrayElements(JNIEnv * env,jcharArray array,jboolean * is_copy)1926   static jchar* GetCharArrayElements(JNIEnv* env, jcharArray array, jboolean* is_copy) {
1927     return GetPrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, is_copy);
1928   }
1929 
GetDoubleArrayElements(JNIEnv * env,jdoubleArray array,jboolean * is_copy)1930   static jdouble* GetDoubleArrayElements(JNIEnv* env, jdoubleArray array, jboolean* is_copy) {
1931     return GetPrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, is_copy);
1932   }
1933 
GetFloatArrayElements(JNIEnv * env,jfloatArray array,jboolean * is_copy)1934   static jfloat* GetFloatArrayElements(JNIEnv* env, jfloatArray array, jboolean* is_copy) {
1935     return GetPrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, is_copy);
1936   }
1937 
GetIntArrayElements(JNIEnv * env,jintArray array,jboolean * is_copy)1938   static jint* GetIntArrayElements(JNIEnv* env, jintArray array, jboolean* is_copy) {
1939     return GetPrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, is_copy);
1940   }
1941 
GetLongArrayElements(JNIEnv * env,jlongArray array,jboolean * is_copy)1942   static jlong* GetLongArrayElements(JNIEnv* env, jlongArray array, jboolean* is_copy) {
1943     return GetPrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, is_copy);
1944   }
1945 
GetShortArrayElements(JNIEnv * env,jshortArray array,jboolean * is_copy)1946   static jshort* GetShortArrayElements(JNIEnv* env, jshortArray array, jboolean* is_copy) {
1947     return GetPrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, is_copy);
1948   }
1949 
ReleaseBooleanArrayElements(JNIEnv * env,jbooleanArray array,jboolean * elements,jint mode)1950   static void ReleaseBooleanArrayElements(JNIEnv* env, jbooleanArray array, jboolean* elements,
1951                                           jint mode) {
1952     ReleasePrimitiveArray<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, elements,
1953                                                                          mode);
1954   }
1955 
ReleaseByteArrayElements(JNIEnv * env,jbyteArray array,jbyte * elements,jint mode)1956   static void ReleaseByteArrayElements(JNIEnv* env, jbyteArray array, jbyte* elements, jint mode) {
1957     ReleasePrimitiveArray<jbyteArray, jbyte, mirror::ByteArray>(env, array, elements, mode);
1958   }
1959 
ReleaseCharArrayElements(JNIEnv * env,jcharArray array,jchar * elements,jint mode)1960   static void ReleaseCharArrayElements(JNIEnv* env, jcharArray array, jchar* elements, jint mode) {
1961     ReleasePrimitiveArray<jcharArray, jchar, mirror::CharArray>(env, array, elements, mode);
1962   }
1963 
ReleaseDoubleArrayElements(JNIEnv * env,jdoubleArray array,jdouble * elements,jint mode)1964   static void ReleaseDoubleArrayElements(JNIEnv* env, jdoubleArray array, jdouble* elements,
1965                                          jint mode) {
1966     ReleasePrimitiveArray<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, elements, mode);
1967   }
1968 
ReleaseFloatArrayElements(JNIEnv * env,jfloatArray array,jfloat * elements,jint mode)1969   static void ReleaseFloatArrayElements(JNIEnv* env, jfloatArray array, jfloat* elements,
1970                                         jint mode) {
1971     ReleasePrimitiveArray<jfloatArray, jfloat, mirror::FloatArray>(env, array, elements, mode);
1972   }
1973 
ReleaseIntArrayElements(JNIEnv * env,jintArray array,jint * elements,jint mode)1974   static void ReleaseIntArrayElements(JNIEnv* env, jintArray array, jint* elements, jint mode) {
1975     ReleasePrimitiveArray<jintArray, jint, mirror::IntArray>(env, array, elements, mode);
1976   }
1977 
ReleaseLongArrayElements(JNIEnv * env,jlongArray array,jlong * elements,jint mode)1978   static void ReleaseLongArrayElements(JNIEnv* env, jlongArray array, jlong* elements, jint mode) {
1979     ReleasePrimitiveArray<jlongArray, jlong, mirror::LongArray>(env, array, elements, mode);
1980   }
1981 
ReleaseShortArrayElements(JNIEnv * env,jshortArray array,jshort * elements,jint mode)1982   static void ReleaseShortArrayElements(JNIEnv* env, jshortArray array, jshort* elements,
1983                                         jint mode) {
1984     ReleasePrimitiveArray<jshortArray, jshort, mirror::ShortArray>(env, array, elements, mode);
1985   }
1986 
GetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,jboolean * buf)1987   static void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
1988                                     jboolean* buf) {
1989     GetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
1990                                                                            length, buf);
1991   }
1992 
GetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,jbyte * buf)1993   static void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
1994                                  jbyte* buf) {
1995     GetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
1996   }
1997 
GetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,jchar * buf)1998   static void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
1999                                  jchar* buf) {
2000     GetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2001   }
2002 
GetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,jdouble * buf)2003   static void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2004                                    jdouble* buf) {
2005     GetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2006                                                                         buf);
2007   }
2008 
GetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,jfloat * buf)2009   static void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2010                                   jfloat* buf) {
2011     GetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2012                                                                      buf);
2013   }
2014 
GetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,jint * buf)2015   static void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2016                                 jint* buf) {
2017     GetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2018   }
2019 
GetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,jlong * buf)2020   static void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2021                                  jlong* buf) {
2022     GetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2023   }
2024 
GetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,jshort * buf)2025   static void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2026                                   jshort* buf) {
2027     GetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2028                                                                      buf);
2029   }
2030 
SetBooleanArrayRegion(JNIEnv * env,jbooleanArray array,jsize start,jsize length,const jboolean * buf)2031   static void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize length,
2032                                     const jboolean* buf) {
2033     SetPrimitiveArrayRegion<jbooleanArray, jboolean, mirror::BooleanArray>(env, array, start,
2034                                                                            length, buf);
2035   }
2036 
SetByteArrayRegion(JNIEnv * env,jbyteArray array,jsize start,jsize length,const jbyte * buf)2037   static void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize length,
2038                                  const jbyte* buf) {
2039     SetPrimitiveArrayRegion<jbyteArray, jbyte, mirror::ByteArray>(env, array, start, length, buf);
2040   }
2041 
SetCharArrayRegion(JNIEnv * env,jcharArray array,jsize start,jsize length,const jchar * buf)2042   static void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize length,
2043                                  const jchar* buf) {
2044     SetPrimitiveArrayRegion<jcharArray, jchar, mirror::CharArray>(env, array, start, length, buf);
2045   }
2046 
SetDoubleArrayRegion(JNIEnv * env,jdoubleArray array,jsize start,jsize length,const jdouble * buf)2047   static void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize length,
2048                                    const jdouble* buf) {
2049     SetPrimitiveArrayRegion<jdoubleArray, jdouble, mirror::DoubleArray>(env, array, start, length,
2050                                                                         buf);
2051   }
2052 
SetFloatArrayRegion(JNIEnv * env,jfloatArray array,jsize start,jsize length,const jfloat * buf)2053   static void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize length,
2054                                   const jfloat* buf) {
2055     SetPrimitiveArrayRegion<jfloatArray, jfloat, mirror::FloatArray>(env, array, start, length,
2056                                                                      buf);
2057   }
2058 
SetIntArrayRegion(JNIEnv * env,jintArray array,jsize start,jsize length,const jint * buf)2059   static void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize length,
2060                                 const jint* buf) {
2061     SetPrimitiveArrayRegion<jintArray, jint, mirror::IntArray>(env, array, start, length, buf);
2062   }
2063 
SetLongArrayRegion(JNIEnv * env,jlongArray array,jsize start,jsize length,const jlong * buf)2064   static void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize length,
2065                                  const jlong* buf) {
2066     SetPrimitiveArrayRegion<jlongArray, jlong, mirror::LongArray>(env, array, start, length, buf);
2067   }
2068 
SetShortArrayRegion(JNIEnv * env,jshortArray array,jsize start,jsize length,const jshort * buf)2069   static void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize length,
2070                                   const jshort* buf) {
2071     SetPrimitiveArrayRegion<jshortArray, jshort, mirror::ShortArray>(env, array, start, length,
2072                                                                      buf);
2073   }
2074 
RegisterNatives(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count)2075   static jint RegisterNatives(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2076                               jint method_count) {
2077     return RegisterNativeMethods(env, java_class, methods, method_count, true);
2078   }
2079 
RegisterNativeMethods(JNIEnv * env,jclass java_class,const JNINativeMethod * methods,jint method_count,bool return_errors)2080   static jint RegisterNativeMethods(JNIEnv* env, jclass java_class, const JNINativeMethod* methods,
2081                                     jint method_count, bool return_errors) {
2082     if (UNLIKELY(method_count < 0)) {
2083       JavaVmExtFromEnv(env)->JniAbortF("RegisterNatives", "negative method count: %d",
2084                                        method_count);
2085       return JNI_ERR;  // Not reached except in unit tests.
2086     }
2087     CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", java_class, JNI_ERR);
2088     ScopedObjectAccess soa(env);
2089     mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2090     if (UNLIKELY(method_count == 0)) {
2091       LOG(WARNING) << "JNI RegisterNativeMethods: attempt to register 0 native methods for "
2092           << PrettyDescriptor(c);
2093       return JNI_OK;
2094     }
2095     CHECK_NON_NULL_ARGUMENT_FN_NAME("RegisterNatives", methods, JNI_ERR);
2096     for (jint i = 0; i < method_count; ++i) {
2097       const char* name = methods[i].name;
2098       const char* sig = methods[i].signature;
2099       const void* fnPtr = methods[i].fnPtr;
2100       if (UNLIKELY(name == nullptr)) {
2101         ReportInvalidJNINativeMethod(soa, c, "method name", i, return_errors);
2102         return JNI_ERR;
2103       } else if (UNLIKELY(sig == nullptr)) {
2104         ReportInvalidJNINativeMethod(soa, c, "method signature", i, return_errors);
2105         return JNI_ERR;
2106       } else if (UNLIKELY(fnPtr == nullptr)) {
2107         ReportInvalidJNINativeMethod(soa, c, "native function", i, return_errors);
2108         return JNI_ERR;
2109       }
2110       bool is_fast = false;
2111       // Notes about fast JNI calls:
2112       //
2113       // On a normal JNI call, the calling thread usually transitions
2114       // from the kRunnable state to the kNative state. But if the
2115       // called native function needs to access any Java object, it
2116       // will have to transition back to the kRunnable state.
2117       //
2118       // There is a cost to this double transition. For a JNI call
2119       // that should be quick, this cost may dominate the call cost.
2120       //
2121       // On a fast JNI call, the calling thread avoids this double
2122       // transition by not transitioning from kRunnable to kNative and
2123       // stays in the kRunnable state.
2124       //
2125       // There are risks to using a fast JNI call because it can delay
2126       // a response to a thread suspension request which is typically
2127       // used for a GC root scanning, etc. If a fast JNI call takes a
2128       // long time, it could cause longer thread suspension latency
2129       // and GC pauses.
2130       //
2131       // Thus, fast JNI should be used with care. It should be used
2132       // for a JNI call that takes a short amount of time (eg. no
2133       // long-running loop) and does not block (eg. no locks, I/O,
2134       // etc.)
2135       //
2136       // A '!' prefix in the signature in the JNINativeMethod
2137       // indicates that it's a fast JNI call and the runtime omits the
2138       // thread state transition from kRunnable to kNative at the
2139       // entry.
2140       if (*sig == '!') {
2141         is_fast = true;
2142         ++sig;
2143       }
2144 
2145       // Note: the right order is to try to find the method locally
2146       // first, either as a direct or a virtual method. Then move to
2147       // the parent.
2148       ArtMethod* m = nullptr;
2149       bool warn_on_going_to_parent = down_cast<JNIEnvExt*>(env)->vm->IsCheckJniEnabled();
2150       for (mirror::Class* current_class = c;
2151            current_class != nullptr;
2152            current_class = current_class->GetSuperClass()) {
2153         // Search first only comparing methods which are native.
2154         m = FindMethod<true>(current_class, name, sig);
2155         if (m != nullptr) {
2156           break;
2157         }
2158 
2159         // Search again comparing to all methods, to find non-native methods that match.
2160         m = FindMethod<false>(current_class, name, sig);
2161         if (m != nullptr) {
2162           break;
2163         }
2164 
2165         if (warn_on_going_to_parent) {
2166           LOG(WARNING) << "CheckJNI: method to register \"" << name << "\" not in the given class. "
2167                        << "This is slow, consider changing your RegisterNatives calls.";
2168           warn_on_going_to_parent = false;
2169         }
2170       }
2171 
2172       if (m == nullptr) {
2173         LOG(return_errors ? ERROR : INTERNAL_FATAL) << "Failed to register native method "
2174             << PrettyDescriptor(c) << "." << name << sig << " in "
2175             << c->GetDexCache()->GetLocation()->ToModifiedUtf8();
2176         // Safe to pass in LOG(FATAL) since the log object aborts in destructor and only goes
2177         // out of scope after the DumpClass is done executing.
2178         c->DumpClass(LOG(return_errors ? ERROR : FATAL), mirror::Class::kDumpClassFullDetail);
2179         ThrowNoSuchMethodError(soa, c, name, sig, "static or non-static");
2180         return JNI_ERR;
2181       } else if (!m->IsNative()) {
2182         LOG(return_errors ? ERROR : FATAL) << "Failed to register non-native method "
2183             << PrettyDescriptor(c) << "." << name << sig
2184             << " as native";
2185         ThrowNoSuchMethodError(soa, c, name, sig, "native");
2186         return JNI_ERR;
2187       }
2188 
2189       VLOG(jni) << "[Registering JNI native method " << PrettyMethod(m) << "]";
2190 
2191       m->RegisterNative(fnPtr, is_fast);
2192     }
2193     return JNI_OK;
2194   }
2195 
UnregisterNatives(JNIEnv * env,jclass java_class)2196   static jint UnregisterNatives(JNIEnv* env, jclass java_class) {
2197     CHECK_NON_NULL_ARGUMENT_RETURN(java_class, JNI_ERR);
2198     ScopedObjectAccess soa(env);
2199     mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
2200 
2201     VLOG(jni) << "[Unregistering JNI native methods for " << PrettyClass(c) << "]";
2202 
2203     size_t unregistered_count = 0;
2204     auto pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
2205     for (auto& m : c->GetDirectMethods(pointer_size)) {
2206       if (m.IsNative()) {
2207         m.UnregisterNative();
2208         unregistered_count++;
2209       }
2210     }
2211     for (auto& m : c->GetVirtualMethods(pointer_size)) {
2212       if (m.IsNative()) {
2213         m.UnregisterNative();
2214         unregistered_count++;
2215       }
2216     }
2217 
2218     if (unregistered_count == 0) {
2219       LOG(WARNING) << "JNI UnregisterNatives: attempt to unregister native methods of class '"
2220           << PrettyDescriptor(c) << "' that contains no native methods";
2221     }
2222     return JNI_OK;
2223   }
2224 
MonitorEnter(JNIEnv * env,jobject java_object)2225   static jint MonitorEnter(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2226     CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2227     ScopedObjectAccess soa(env);
2228     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2229     o = o->MonitorEnter(soa.Self());
2230     if (soa.Self()->IsExceptionPending()) {
2231       return JNI_ERR;
2232     }
2233     soa.Env()->monitors.Add(o);
2234     return JNI_OK;
2235   }
2236 
MonitorExit(JNIEnv * env,jobject java_object)2237   static jint MonitorExit(JNIEnv* env, jobject java_object) NO_THREAD_SAFETY_ANALYSIS {
2238     CHECK_NON_NULL_ARGUMENT_RETURN(java_object, JNI_ERR);
2239     ScopedObjectAccess soa(env);
2240     mirror::Object* o = soa.Decode<mirror::Object*>(java_object);
2241     o->MonitorExit(soa.Self());
2242     if (soa.Self()->IsExceptionPending()) {
2243       return JNI_ERR;
2244     }
2245     soa.Env()->monitors.Remove(o);
2246     return JNI_OK;
2247   }
2248 
GetJavaVM(JNIEnv * env,JavaVM ** vm)2249   static jint GetJavaVM(JNIEnv* env, JavaVM** vm) {
2250     CHECK_NON_NULL_ARGUMENT_RETURN(vm, JNI_ERR);
2251     Runtime* runtime = Runtime::Current();
2252     if (runtime != nullptr) {
2253       *vm = runtime->GetJavaVM();
2254     } else {
2255       *vm = nullptr;
2256     }
2257     return (*vm != nullptr) ? JNI_OK : JNI_ERR;
2258   }
2259 
NewDirectByteBuffer(JNIEnv * env,void * address,jlong capacity)2260   static jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
2261     if (capacity < 0) {
2262       JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer", "negative buffer capacity: %" PRId64,
2263                                        capacity);
2264       return nullptr;
2265     }
2266     if (address == nullptr && capacity != 0) {
2267       JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2268                                        "non-zero capacity for nullptr pointer: %" PRId64, capacity);
2269       return nullptr;
2270     }
2271 
2272     // At the moment, the capacity of DirectByteBuffer is limited to a signed int.
2273     if (capacity > INT_MAX) {
2274       JavaVmExtFromEnv(env)->JniAbortF("NewDirectByteBuffer",
2275                                        "buffer capacity greater than maximum jint: %" PRId64,
2276                                        capacity);
2277       return nullptr;
2278     }
2279     jlong address_arg = reinterpret_cast<jlong>(address);
2280     jint capacity_arg = static_cast<jint>(capacity);
2281 
2282     jobject result = env->NewObject(WellKnownClasses::java_nio_DirectByteBuffer,
2283                                     WellKnownClasses::java_nio_DirectByteBuffer_init,
2284                                     address_arg, capacity_arg);
2285     return static_cast<JNIEnvExt*>(env)->self->IsExceptionPending() ? nullptr : result;
2286   }
2287 
GetDirectBufferAddress(JNIEnv * env,jobject java_buffer)2288   static void* GetDirectBufferAddress(JNIEnv* env, jobject java_buffer) {
2289     return reinterpret_cast<void*>(env->GetLongField(
2290         java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_effectiveDirectAddress));
2291   }
2292 
GetDirectBufferCapacity(JNIEnv * env,jobject java_buffer)2293   static jlong GetDirectBufferCapacity(JNIEnv* env, jobject java_buffer) {
2294     return static_cast<jlong>(env->GetIntField(
2295         java_buffer, WellKnownClasses::java_nio_DirectByteBuffer_capacity));
2296   }
2297 
GetObjectRefType(JNIEnv * env ATTRIBUTE_UNUSED,jobject java_object)2298   static jobjectRefType GetObjectRefType(JNIEnv* env ATTRIBUTE_UNUSED, jobject java_object) {
2299     if (java_object == nullptr) {
2300       return JNIInvalidRefType;
2301     }
2302 
2303     // Do we definitely know what kind of reference this is?
2304     IndirectRef ref = reinterpret_cast<IndirectRef>(java_object);
2305     IndirectRefKind kind = GetIndirectRefKind(ref);
2306     switch (kind) {
2307     case kLocal:
2308       return JNILocalRefType;
2309     case kGlobal:
2310       return JNIGlobalRefType;
2311     case kWeakGlobal:
2312       return JNIWeakGlobalRefType;
2313     case kHandleScopeOrInvalid:
2314       // Assume value is in a handle scope.
2315       return JNILocalRefType;
2316     }
2317     LOG(FATAL) << "IndirectRefKind[" << kind << "]";
2318     UNREACHABLE();
2319   }
2320 
2321  private:
EnsureLocalCapacityInternal(ScopedObjectAccess & soa,jint desired_capacity,const char * caller)2322   static jint EnsureLocalCapacityInternal(ScopedObjectAccess& soa, jint desired_capacity,
2323                                           const char* caller)
2324       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2325     // TODO: we should try to expand the table if necessary.
2326     if (desired_capacity < 0 || desired_capacity > static_cast<jint>(kLocalsMax)) {
2327       LOG(ERROR) << "Invalid capacity given to " << caller << ": " << desired_capacity;
2328       return JNI_ERR;
2329     }
2330     // TODO: this isn't quite right, since "capacity" includes holes.
2331     const size_t capacity = soa.Env()->locals.Capacity();
2332     bool okay = (static_cast<jint>(kLocalsMax - capacity) >= desired_capacity);
2333     if (!okay) {
2334       soa.Self()->ThrowOutOfMemoryError(caller);
2335     }
2336     return okay ? JNI_OK : JNI_ERR;
2337   }
2338 
2339   template<typename JniT, typename ArtT>
NewPrimitiveArray(JNIEnv * env,jsize length)2340   static JniT NewPrimitiveArray(JNIEnv* env, jsize length) {
2341     ScopedObjectAccess soa(env);
2342     if (UNLIKELY(length < 0)) {
2343       soa.Vm()->JniAbortF("NewPrimitiveArray", "negative array length: %d", length);
2344       return nullptr;
2345     }
2346     ArtT* result = ArtT::Alloc(soa.Self(), length);
2347     return soa.AddLocalReference<JniT>(result);
2348   }
2349 
2350   template <typename JArrayT, typename ElementT, typename ArtArrayT>
DecodeAndCheckArrayType(ScopedObjectAccess & soa,JArrayT java_array,const char * fn_name,const char * operation)2351   static ArtArrayT* DecodeAndCheckArrayType(ScopedObjectAccess& soa, JArrayT java_array,
2352                                            const char* fn_name, const char* operation)
2353       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2354     ArtArrayT* array = soa.Decode<ArtArrayT*>(java_array);
2355     if (UNLIKELY(ArtArrayT::GetArrayClass() != array->GetClass())) {
2356       soa.Vm()->JniAbortF(fn_name,
2357                           "attempt to %s %s primitive array elements with an object of type %s",
2358                           operation,
2359                           PrettyDescriptor(ArtArrayT::GetArrayClass()->GetComponentType()).c_str(),
2360                           PrettyDescriptor(array->GetClass()).c_str());
2361       return nullptr;
2362     }
2363     DCHECK_EQ(sizeof(ElementT), array->GetClass()->GetComponentSize());
2364     return array;
2365   }
2366 
2367   template <typename ArrayT, typename ElementT, typename ArtArrayT>
GetPrimitiveArray(JNIEnv * env,ArrayT java_array,jboolean * is_copy)2368   static ElementT* GetPrimitiveArray(JNIEnv* env, ArrayT java_array, jboolean* is_copy) {
2369     CHECK_NON_NULL_ARGUMENT(java_array);
2370     ScopedObjectAccess soa(env);
2371     ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2372                                                                             "GetArrayElements",
2373                                                                             "get");
2374     if (UNLIKELY(array == nullptr)) {
2375       return nullptr;
2376     }
2377     // Only make a copy if necessary.
2378     if (Runtime::Current()->GetHeap()->IsMovableObject(array)) {
2379       if (is_copy != nullptr) {
2380         *is_copy = JNI_TRUE;
2381       }
2382       const size_t component_size = sizeof(ElementT);
2383       size_t size = array->GetLength() * component_size;
2384       void* data = new uint64_t[RoundUp(size, 8) / 8];
2385       memcpy(data, array->GetData(), size);
2386       return reinterpret_cast<ElementT*>(data);
2387     } else {
2388       if (is_copy != nullptr) {
2389         *is_copy = JNI_FALSE;
2390       }
2391       return reinterpret_cast<ElementT*>(array->GetData());
2392     }
2393   }
2394 
2395   template <typename ArrayT, typename ElementT, typename ArtArrayT>
ReleasePrimitiveArray(JNIEnv * env,ArrayT java_array,ElementT * elements,jint mode)2396   static void ReleasePrimitiveArray(JNIEnv* env, ArrayT java_array, ElementT* elements, jint mode) {
2397     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2398     ScopedObjectAccess soa(env);
2399     ArtArrayT* array = DecodeAndCheckArrayType<ArrayT, ElementT, ArtArrayT>(soa, java_array,
2400                                                                             "ReleaseArrayElements",
2401                                                                             "release");
2402     if (array == nullptr) {
2403       return;
2404     }
2405     ReleasePrimitiveArray(soa, array, sizeof(ElementT), elements, mode);
2406   }
2407 
ReleasePrimitiveArray(ScopedObjectAccess & soa,mirror::Array * array,size_t component_size,void * elements,jint mode)2408   static void ReleasePrimitiveArray(ScopedObjectAccess& soa, mirror::Array* array,
2409                                     size_t component_size, void* elements, jint mode)
2410       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2411     void* array_data = array->GetRawData(component_size, 0);
2412     gc::Heap* heap = Runtime::Current()->GetHeap();
2413     bool is_copy = array_data != elements;
2414     size_t bytes = array->GetLength() * component_size;
2415     VLOG(heap) << "Release primitive array " << soa.Env() << " array_data " << array_data
2416                << " elements " << elements;
2417     if (is_copy) {
2418       // Sanity check: If elements is not the same as the java array's data, it better not be a
2419       // heap address. TODO: This might be slow to check, may be worth keeping track of which
2420       // copies we make?
2421       if (heap->IsNonDiscontinuousSpaceHeapAddress(reinterpret_cast<mirror::Object*>(elements))) {
2422         soa.Vm()->JniAbortF("ReleaseArrayElements",
2423                             "invalid element pointer %p, array elements are %p",
2424                             reinterpret_cast<void*>(elements), array_data);
2425         return;
2426       }
2427       if (mode != JNI_ABORT) {
2428         memcpy(array_data, elements, bytes);
2429       } else if (kWarnJniAbort && memcmp(array_data, elements, bytes) != 0) {
2430         // Warn if we have JNI_ABORT and the arrays don't match since this is usually an error.
2431         LOG(WARNING) << "Possible incorrect JNI_ABORT in Release*ArrayElements";
2432         soa.Self()->DumpJavaStack(LOG(WARNING));
2433       }
2434     }
2435     if (mode != JNI_COMMIT) {
2436       if (is_copy) {
2437         delete[] reinterpret_cast<uint64_t*>(elements);
2438       } else if (heap->IsMovableObject(array)) {
2439         // Non copy to a movable object must means that we had disabled the moving GC.
2440         heap->DecrementDisableMovingGC(soa.Self());
2441       }
2442     }
2443   }
2444 
2445   template <typename JArrayT, typename ElementT, typename ArtArrayT>
GetPrimitiveArrayRegion(JNIEnv * env,JArrayT java_array,jsize start,jsize length,ElementT * buf)2446   static void GetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2447                                       jsize start, jsize length, ElementT* buf) {
2448     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2449     ScopedObjectAccess soa(env);
2450     ArtArrayT* array =
2451         DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2452                                                               "GetPrimitiveArrayRegion",
2453                                                               "get region of");
2454     if (array != nullptr) {
2455       if (start < 0 || length < 0 || start + length > array->GetLength()) {
2456         ThrowAIOOBE(soa, array, start, length, "src");
2457       } else {
2458         CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2459         ElementT* data = array->GetData();
2460         memcpy(buf, data + start, length * sizeof(ElementT));
2461       }
2462     }
2463   }
2464 
2465   template <typename JArrayT, typename ElementT, typename ArtArrayT>
SetPrimitiveArrayRegion(JNIEnv * env,JArrayT java_array,jsize start,jsize length,const ElementT * buf)2466   static void SetPrimitiveArrayRegion(JNIEnv* env, JArrayT java_array,
2467                                       jsize start, jsize length, const ElementT* buf) {
2468     CHECK_NON_NULL_ARGUMENT_RETURN_VOID(java_array);
2469     ScopedObjectAccess soa(env);
2470     ArtArrayT* array =
2471         DecodeAndCheckArrayType<JArrayT, ElementT, ArtArrayT>(soa, java_array,
2472                                                               "SetPrimitiveArrayRegion",
2473                                                               "set region of");
2474     if (array != nullptr) {
2475       if (start < 0 || length < 0 || start + length > array->GetLength()) {
2476         ThrowAIOOBE(soa, array, start, length, "dst");
2477       } else {
2478         CHECK_NON_NULL_MEMCPY_ARGUMENT(length, buf);
2479         ElementT* data = array->GetData();
2480         memcpy(data + start, buf, length * sizeof(ElementT));
2481       }
2482     }
2483   }
2484 };
2485 
2486 const JNINativeInterface gJniNativeInterface = {
2487   nullptr,  // reserved0.
2488   nullptr,  // reserved1.
2489   nullptr,  // reserved2.
2490   nullptr,  // reserved3.
2491   JNI::GetVersion,
2492   JNI::DefineClass,
2493   JNI::FindClass,
2494   JNI::FromReflectedMethod,
2495   JNI::FromReflectedField,
2496   JNI::ToReflectedMethod,
2497   JNI::GetSuperclass,
2498   JNI::IsAssignableFrom,
2499   JNI::ToReflectedField,
2500   JNI::Throw,
2501   JNI::ThrowNew,
2502   JNI::ExceptionOccurred,
2503   JNI::ExceptionDescribe,
2504   JNI::ExceptionClear,
2505   JNI::FatalError,
2506   JNI::PushLocalFrame,
2507   JNI::PopLocalFrame,
2508   JNI::NewGlobalRef,
2509   JNI::DeleteGlobalRef,
2510   JNI::DeleteLocalRef,
2511   JNI::IsSameObject,
2512   JNI::NewLocalRef,
2513   JNI::EnsureLocalCapacity,
2514   JNI::AllocObject,
2515   JNI::NewObject,
2516   JNI::NewObjectV,
2517   JNI::NewObjectA,
2518   JNI::GetObjectClass,
2519   JNI::IsInstanceOf,
2520   JNI::GetMethodID,
2521   JNI::CallObjectMethod,
2522   JNI::CallObjectMethodV,
2523   JNI::CallObjectMethodA,
2524   JNI::CallBooleanMethod,
2525   JNI::CallBooleanMethodV,
2526   JNI::CallBooleanMethodA,
2527   JNI::CallByteMethod,
2528   JNI::CallByteMethodV,
2529   JNI::CallByteMethodA,
2530   JNI::CallCharMethod,
2531   JNI::CallCharMethodV,
2532   JNI::CallCharMethodA,
2533   JNI::CallShortMethod,
2534   JNI::CallShortMethodV,
2535   JNI::CallShortMethodA,
2536   JNI::CallIntMethod,
2537   JNI::CallIntMethodV,
2538   JNI::CallIntMethodA,
2539   JNI::CallLongMethod,
2540   JNI::CallLongMethodV,
2541   JNI::CallLongMethodA,
2542   JNI::CallFloatMethod,
2543   JNI::CallFloatMethodV,
2544   JNI::CallFloatMethodA,
2545   JNI::CallDoubleMethod,
2546   JNI::CallDoubleMethodV,
2547   JNI::CallDoubleMethodA,
2548   JNI::CallVoidMethod,
2549   JNI::CallVoidMethodV,
2550   JNI::CallVoidMethodA,
2551   JNI::CallNonvirtualObjectMethod,
2552   JNI::CallNonvirtualObjectMethodV,
2553   JNI::CallNonvirtualObjectMethodA,
2554   JNI::CallNonvirtualBooleanMethod,
2555   JNI::CallNonvirtualBooleanMethodV,
2556   JNI::CallNonvirtualBooleanMethodA,
2557   JNI::CallNonvirtualByteMethod,
2558   JNI::CallNonvirtualByteMethodV,
2559   JNI::CallNonvirtualByteMethodA,
2560   JNI::CallNonvirtualCharMethod,
2561   JNI::CallNonvirtualCharMethodV,
2562   JNI::CallNonvirtualCharMethodA,
2563   JNI::CallNonvirtualShortMethod,
2564   JNI::CallNonvirtualShortMethodV,
2565   JNI::CallNonvirtualShortMethodA,
2566   JNI::CallNonvirtualIntMethod,
2567   JNI::CallNonvirtualIntMethodV,
2568   JNI::CallNonvirtualIntMethodA,
2569   JNI::CallNonvirtualLongMethod,
2570   JNI::CallNonvirtualLongMethodV,
2571   JNI::CallNonvirtualLongMethodA,
2572   JNI::CallNonvirtualFloatMethod,
2573   JNI::CallNonvirtualFloatMethodV,
2574   JNI::CallNonvirtualFloatMethodA,
2575   JNI::CallNonvirtualDoubleMethod,
2576   JNI::CallNonvirtualDoubleMethodV,
2577   JNI::CallNonvirtualDoubleMethodA,
2578   JNI::CallNonvirtualVoidMethod,
2579   JNI::CallNonvirtualVoidMethodV,
2580   JNI::CallNonvirtualVoidMethodA,
2581   JNI::GetFieldID,
2582   JNI::GetObjectField,
2583   JNI::GetBooleanField,
2584   JNI::GetByteField,
2585   JNI::GetCharField,
2586   JNI::GetShortField,
2587   JNI::GetIntField,
2588   JNI::GetLongField,
2589   JNI::GetFloatField,
2590   JNI::GetDoubleField,
2591   JNI::SetObjectField,
2592   JNI::SetBooleanField,
2593   JNI::SetByteField,
2594   JNI::SetCharField,
2595   JNI::SetShortField,
2596   JNI::SetIntField,
2597   JNI::SetLongField,
2598   JNI::SetFloatField,
2599   JNI::SetDoubleField,
2600   JNI::GetStaticMethodID,
2601   JNI::CallStaticObjectMethod,
2602   JNI::CallStaticObjectMethodV,
2603   JNI::CallStaticObjectMethodA,
2604   JNI::CallStaticBooleanMethod,
2605   JNI::CallStaticBooleanMethodV,
2606   JNI::CallStaticBooleanMethodA,
2607   JNI::CallStaticByteMethod,
2608   JNI::CallStaticByteMethodV,
2609   JNI::CallStaticByteMethodA,
2610   JNI::CallStaticCharMethod,
2611   JNI::CallStaticCharMethodV,
2612   JNI::CallStaticCharMethodA,
2613   JNI::CallStaticShortMethod,
2614   JNI::CallStaticShortMethodV,
2615   JNI::CallStaticShortMethodA,
2616   JNI::CallStaticIntMethod,
2617   JNI::CallStaticIntMethodV,
2618   JNI::CallStaticIntMethodA,
2619   JNI::CallStaticLongMethod,
2620   JNI::CallStaticLongMethodV,
2621   JNI::CallStaticLongMethodA,
2622   JNI::CallStaticFloatMethod,
2623   JNI::CallStaticFloatMethodV,
2624   JNI::CallStaticFloatMethodA,
2625   JNI::CallStaticDoubleMethod,
2626   JNI::CallStaticDoubleMethodV,
2627   JNI::CallStaticDoubleMethodA,
2628   JNI::CallStaticVoidMethod,
2629   JNI::CallStaticVoidMethodV,
2630   JNI::CallStaticVoidMethodA,
2631   JNI::GetStaticFieldID,
2632   JNI::GetStaticObjectField,
2633   JNI::GetStaticBooleanField,
2634   JNI::GetStaticByteField,
2635   JNI::GetStaticCharField,
2636   JNI::GetStaticShortField,
2637   JNI::GetStaticIntField,
2638   JNI::GetStaticLongField,
2639   JNI::GetStaticFloatField,
2640   JNI::GetStaticDoubleField,
2641   JNI::SetStaticObjectField,
2642   JNI::SetStaticBooleanField,
2643   JNI::SetStaticByteField,
2644   JNI::SetStaticCharField,
2645   JNI::SetStaticShortField,
2646   JNI::SetStaticIntField,
2647   JNI::SetStaticLongField,
2648   JNI::SetStaticFloatField,
2649   JNI::SetStaticDoubleField,
2650   JNI::NewString,
2651   JNI::GetStringLength,
2652   JNI::GetStringChars,
2653   JNI::ReleaseStringChars,
2654   JNI::NewStringUTF,
2655   JNI::GetStringUTFLength,
2656   JNI::GetStringUTFChars,
2657   JNI::ReleaseStringUTFChars,
2658   JNI::GetArrayLength,
2659   JNI::NewObjectArray,
2660   JNI::GetObjectArrayElement,
2661   JNI::SetObjectArrayElement,
2662   JNI::NewBooleanArray,
2663   JNI::NewByteArray,
2664   JNI::NewCharArray,
2665   JNI::NewShortArray,
2666   JNI::NewIntArray,
2667   JNI::NewLongArray,
2668   JNI::NewFloatArray,
2669   JNI::NewDoubleArray,
2670   JNI::GetBooleanArrayElements,
2671   JNI::GetByteArrayElements,
2672   JNI::GetCharArrayElements,
2673   JNI::GetShortArrayElements,
2674   JNI::GetIntArrayElements,
2675   JNI::GetLongArrayElements,
2676   JNI::GetFloatArrayElements,
2677   JNI::GetDoubleArrayElements,
2678   JNI::ReleaseBooleanArrayElements,
2679   JNI::ReleaseByteArrayElements,
2680   JNI::ReleaseCharArrayElements,
2681   JNI::ReleaseShortArrayElements,
2682   JNI::ReleaseIntArrayElements,
2683   JNI::ReleaseLongArrayElements,
2684   JNI::ReleaseFloatArrayElements,
2685   JNI::ReleaseDoubleArrayElements,
2686   JNI::GetBooleanArrayRegion,
2687   JNI::GetByteArrayRegion,
2688   JNI::GetCharArrayRegion,
2689   JNI::GetShortArrayRegion,
2690   JNI::GetIntArrayRegion,
2691   JNI::GetLongArrayRegion,
2692   JNI::GetFloatArrayRegion,
2693   JNI::GetDoubleArrayRegion,
2694   JNI::SetBooleanArrayRegion,
2695   JNI::SetByteArrayRegion,
2696   JNI::SetCharArrayRegion,
2697   JNI::SetShortArrayRegion,
2698   JNI::SetIntArrayRegion,
2699   JNI::SetLongArrayRegion,
2700   JNI::SetFloatArrayRegion,
2701   JNI::SetDoubleArrayRegion,
2702   JNI::RegisterNatives,
2703   JNI::UnregisterNatives,
2704   JNI::MonitorEnter,
2705   JNI::MonitorExit,
2706   JNI::GetJavaVM,
2707   JNI::GetStringRegion,
2708   JNI::GetStringUTFRegion,
2709   JNI::GetPrimitiveArrayCritical,
2710   JNI::ReleasePrimitiveArrayCritical,
2711   JNI::GetStringCritical,
2712   JNI::ReleaseStringCritical,
2713   JNI::NewWeakGlobalRef,
2714   JNI::DeleteWeakGlobalRef,
2715   JNI::ExceptionCheck,
2716   JNI::NewDirectByteBuffer,
2717   JNI::GetDirectBufferAddress,
2718   JNI::GetDirectBufferCapacity,
2719   JNI::GetObjectRefType,
2720 };
2721 
GetJniNativeInterface()2722 const JNINativeInterface* GetJniNativeInterface() {
2723   return &gJniNativeInterface;
2724 }
2725 
RegisterNativeMethods(JNIEnv * env,const char * jni_class_name,const JNINativeMethod * methods,jint method_count)2726 void RegisterNativeMethods(JNIEnv* env, const char* jni_class_name, const JNINativeMethod* methods,
2727                            jint method_count) {
2728   ScopedLocalRef<jclass> c(env, env->FindClass(jni_class_name));
2729   if (c.get() == nullptr) {
2730     LOG(FATAL) << "Couldn't find class: " << jni_class_name;
2731   }
2732   JNI::RegisterNativeMethods(env, c.get(), methods, method_count, false);
2733 }
2734 
2735 }  // namespace art
2736 
operator <<(std::ostream & os,const jobjectRefType & rhs)2737 std::ostream& operator<<(std::ostream& os, const jobjectRefType& rhs) {
2738   switch (rhs) {
2739   case JNIInvalidRefType:
2740     os << "JNIInvalidRefType";
2741     return os;
2742   case JNILocalRefType:
2743     os << "JNILocalRefType";
2744     return os;
2745   case JNIGlobalRefType:
2746     os << "JNIGlobalRefType";
2747     return os;
2748   case JNIWeakGlobalRefType:
2749     os << "JNIWeakGlobalRefType";
2750     return os;
2751   default:
2752     LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
2753     UNREACHABLE();
2754   }
2755 }
2756