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