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