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