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