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