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