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