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