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