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