1 /* 2 * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "classfile/javaClasses.inline.hpp" 27 #include "classfile/vmClasses.hpp" 28 #include "classfile/vmSymbols.hpp" 29 #include "jni.h" 30 #include "jvm.h" 31 #include "logging/log.hpp" 32 #include "logging/logTag.hpp" 33 #include "memory/allocation.inline.hpp" 34 #include "memory/guardedMemory.hpp" 35 #include "oops/instanceKlass.hpp" 36 #include "oops/oop.inline.hpp" 37 #include "oops/symbol.hpp" 38 #include "prims/jniCheck.hpp" 39 #include "prims/jvm_misc.hpp" 40 #include "runtime/fieldDescriptor.inline.hpp" 41 #include "runtime/handles.inline.hpp" 42 #include "runtime/interfaceSupport.inline.hpp" 43 #include "runtime/javaThread.hpp" 44 #include "runtime/jfieldIDWorkaround.hpp" 45 #include "runtime/jniHandles.inline.hpp" 46 #include "utilities/formatBuffer.hpp" 47 #include "utilities/utf8.hpp" 48 49 // Heap objects are allowed to be directly referenced only in VM code, 50 // not in native code. 51 52 #define ASSERT_OOPS_ALLOWED \ 53 assert(JavaThread::current()->thread_state() == _thread_in_vm, \ 54 "jniCheck examining oops in bad state.") 55 56 57 // Execute the given block of source code with the thread in VM state. 58 // To do this, transition from the NATIVE state to the VM state, execute 59 // the code, and transition back. The ThreadInVMfromNative constructor 60 // performs the transition to VM state, its destructor restores the 61 // NATIVE state. 62 63 #define IN_VM(source_code) { \ 64 { \ 65 ThreadInVMfromNative __tiv(thr); \ 66 source_code \ 67 } \ 68 } 69 70 71 /* 72 * DECLARATIONS 73 */ 74 75 static struct JNINativeInterface_ * unchecked_jni_NativeInterface; 76 77 78 /* 79 * MACRO DEFINITIONS 80 */ 81 82 // All JNI checked functions here use JNI_ENTRY_CHECKED() instead of the 83 // QUICK_ENTRY or LEAF variants found in jni.cpp. This allows handles 84 // to be created if a fatal error should occur. 85 86 // Check for thread not attached to VM; need to catch this before 87 // assertions in the wrapper routines might fire 88 89 // Check for env being the one value appropriate for this thread. 90 91 #define JNI_ENTRY_CHECKED(result_type, header) \ 92 extern "C" { \ 93 result_type JNICALL header { \ 94 Thread* cur = Thread::current_or_null(); \ 95 if (cur == nullptr || !cur->is_Java_thread()) { \ 96 tty->print_cr("%s", fatal_using_jnienv_in_nonjava); \ 97 os::abort(true); \ 98 } \ 99 JavaThread* thr = JavaThread::cast(cur); \ 100 JNIEnv* xenv = thr->jni_environment(); \ 101 if (env != xenv) { \ 102 NativeReportJNIFatalError(thr, warn_wrong_jnienv); \ 103 } \ 104 MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thr)); \ 105 VM_ENTRY_BASE(result_type, header, thr) 106 107 108 #define UNCHECKED() (unchecked_jni_NativeInterface) 109 110 static const char * warn_wrong_jnienv = "Using JNIEnv in the wrong thread"; 111 static const char * warn_bad_class_descriptor1 = "JNI FindClass received a bad class descriptor \""; 112 static const char * warn_bad_class_descriptor2 = "\". A correct class descriptor " \ 113 "has no leading \"L\" or trailing \";\". Incorrect descriptors will not be accepted in future releases."; 114 static const char * fatal_using_jnienv_in_nonjava = "FATAL ERROR in native method: Using JNIEnv in non-Java thread"; 115 static const char * warn_other_function_in_critical = "Warning: Calling other JNI functions in the scope of " \ 116 "Get/ReleasePrimitiveArrayCritical or Get/ReleaseStringCritical"; 117 static const char * fatal_bad_ref_to_jni = "Bad global or local ref passed to JNI"; 118 static const char * fatal_received_null_class = "JNI received a null class"; 119 static const char * fatal_class_not_a_class = "JNI received a class argument that is not a class"; 120 static const char * fatal_class_not_a_throwable_class = "JNI Throw or ThrowNew received a class argument that is not a Throwable or Throwable subclass"; 121 static const char * fatal_wrong_class_or_method = "Wrong object class or methodID passed to JNI call"; 122 static const char * fatal_non_weak_method = "non-weak methodID passed to JNI call"; 123 static const char * fatal_unknown_array_object = "Unknown array object passed to JNI array operations"; 124 static const char * fatal_object_array_expected = "Object array expected but not received for JNI array operation"; 125 static const char * fatal_prim_type_array_expected = "Primitive type array expected but not received for JNI array operation"; 126 static const char * fatal_non_array = "Non-array passed to JNI array operations"; 127 static const char * fatal_element_type_mismatch = "Array element type mismatch in JNI"; 128 static const char * fatal_should_be_static = "Non-static field ID passed to JNI"; 129 static const char * fatal_wrong_static_field = "Wrong static field ID passed to JNI"; 130 static const char * fatal_static_field_not_found = "Static field not found in JNI get/set field operations"; 131 static const char * fatal_static_field_mismatch = "Field type (static) mismatch in JNI get/set field operations"; 132 static const char * fatal_should_be_nonstatic = "Static field ID passed to JNI"; 133 static const char * fatal_null_object = "Null object passed to JNI"; 134 static const char * fatal_wrong_field = "Wrong field ID passed to JNI"; 135 static const char * fatal_instance_field_not_found = "Instance field not found in JNI get/set field operations"; 136 static const char * fatal_instance_field_mismatch = "Field type (instance) mismatch in JNI get/set field operations"; 137 static const char * fatal_non_string = "JNI string operation received a non-string"; 138 static const char * fatal_non_utf8_class_name1 = "JNI class name is not a valid UTF8 string \""; 139 static const char * fatal_non_utf8_class_name2 = "\""; 140 141 142 // When in VM state: 143 static void ReportJNIWarning(JavaThread* thr, const char *msg) { 144 tty->print_cr("WARNING in native method: %s", msg); 145 thr->print_jni_stack(); 146 } 147 148 // When in NATIVE state: 149 static void NativeReportJNIFatalError(JavaThread* thr, const char *msg) { 150 IN_VM( 151 ReportJNIFatalError(thr, msg); 152 ) 153 } 154 155 static void NativeReportJNIWarning(JavaThread* thr, const char *msg) { 156 IN_VM( 157 ReportJNIWarning(thr, msg); 158 ) 159 } 160 161 162 163 164 /* 165 * SUPPORT FUNCTIONS 166 */ 167 168 /** 169 * Check whether or not a programmer has actually checked for exceptions. According 170 * to the JNI Specification ("jni/spec/design.html#java_exceptions"): 171 * 172 * There are two cases where the programmer needs to check for exceptions without 173 * being able to first check an error code: 174 * 175 * - The JNI functions that invoke a Java method return the result of the Java method. 176 * The programmer must call ExceptionOccurred() to check for possible exceptions 177 * that occurred during the execution of the Java method. 178 * 179 * - Some of the JNI array access functions do not return an error code, but may 180 * throw an ArrayIndexOutOfBoundsException or ArrayStoreException. 181 * 182 * In all other cases, a non-error return value guarantees that no exceptions have been thrown. 183 * 184 * Programmers often defend against ArrayIndexOutOfBoundsException, so warning 185 * for these functions would be pedantic. 186 */ 187 static inline void 188 check_pending_exception(JavaThread* thr) { 189 if (thr->has_pending_exception()) { 190 NativeReportJNIWarning(thr, "JNI call made with exception pending"); 191 } 192 if (thr->is_pending_jni_exception_check()) { 193 IN_VM( 194 tty->print_cr("WARNING in native method: JNI call made without checking exceptions when required to from %s", 195 thr->get_pending_jni_exception_check()); 196 thr->print_jni_stack(); 197 ) 198 thr->clear_pending_jni_exception_check(); // Just complain once 199 } 200 } 201 202 static inline void 203 functionEnterCritical(JavaThread* thr) 204 { 205 check_pending_exception(thr); 206 } 207 208 static inline void 209 functionEnterCriticalExceptionAllowed(JavaThread* thr) 210 { 211 } 212 213 static inline void 214 functionEnter(JavaThread* thr) 215 { 216 if (thr->in_critical()) { 217 tty->print_cr("%s", warn_other_function_in_critical); 218 } 219 check_pending_exception(thr); 220 } 221 222 static inline void 223 functionEnterExceptionAllowed(JavaThread* thr) 224 { 225 if (thr->in_critical()) { 226 tty->print_cr("%s", warn_other_function_in_critical); 227 } 228 } 229 230 static inline void 231 functionExit(JavaThread* thr) 232 { 233 // No checks at this time 234 } 235 236 static inline void 237 checkStaticFieldID(JavaThread* thr, jfieldID fid, jclass cls, int ftype) 238 { 239 fieldDescriptor fd; 240 241 /* make sure it is a static field */ 242 if (!jfieldIDWorkaround::is_static_jfieldID(fid)) 243 ReportJNIFatalError(thr, fatal_should_be_static); 244 245 /* validate the class being passed */ 246 ASSERT_OOPS_ALLOWED; 247 Klass* k_oop = jniCheck::validate_class(thr, cls, false); 248 249 /* check for proper subclass hierarchy */ 250 JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fid); 251 Klass* f_oop = id->holder(); 252 if (!k_oop->is_subtype_of(f_oop)) 253 ReportJNIFatalError(thr, fatal_wrong_static_field); 254 255 /* check for proper field type */ 256 if (!id->find_local_field(&fd)) 257 ReportJNIFatalError(thr, fatal_static_field_not_found); 258 if ((fd.field_type() != ftype) && 259 !(fd.field_type() == T_ARRAY && ftype == T_OBJECT) && 260 !(fd.field_type() == T_PRIMITIVE_OBJECT && ftype == T_OBJECT)) { 261 ReportJNIFatalError(thr, fatal_static_field_mismatch); 262 } 263 } 264 265 static inline void 266 checkInstanceFieldID(JavaThread* thr, jfieldID fid, jobject obj, int ftype) 267 { 268 fieldDescriptor fd; 269 270 /* make sure it is an instance field */ 271 if (jfieldIDWorkaround::is_static_jfieldID(fid)) 272 ReportJNIFatalError(thr, fatal_should_be_nonstatic); 273 274 /* validate the object being passed and then get its class */ 275 ASSERT_OOPS_ALLOWED; 276 oop oopObj = jniCheck::validate_object(thr, obj); 277 if (oopObj == nullptr) { 278 ReportJNIFatalError(thr, fatal_null_object); 279 } 280 Klass* k_oop = oopObj->klass(); 281 282 if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) { 283 ReportJNIFatalError(thr, fatal_wrong_field); 284 } 285 286 /* make sure the field exists */ 287 int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid); 288 if (!InstanceKlass::cast(k_oop)->contains_field_offset(offset)) 289 ReportJNIFatalError(thr, fatal_wrong_field); 290 291 /* check for proper field type */ 292 if (!InstanceKlass::cast(k_oop)->find_field_from_offset(offset, 293 false, &fd)) 294 ReportJNIFatalError(thr, fatal_instance_field_not_found); 295 296 if ((fd.field_type() != ftype) && 297 !(fd.field_type() == T_ARRAY && ftype == T_OBJECT) && 298 !(fd.field_type() == T_PRIMITIVE_OBJECT && ftype == T_OBJECT)) { 299 ReportJNIFatalError(thr, fatal_instance_field_mismatch); 300 } 301 } 302 303 static inline void 304 checkString(JavaThread* thr, jstring js) 305 { 306 ASSERT_OOPS_ALLOWED; 307 oop s = jniCheck::validate_object(thr, js); 308 if ((s == nullptr) || !java_lang_String::is_instance(s)) 309 ReportJNIFatalError(thr, fatal_non_string); 310 } 311 312 static inline arrayOop 313 check_is_array(JavaThread* thr, jarray jArray) 314 { 315 ASSERT_OOPS_ALLOWED; 316 arrayOop aOop; 317 318 aOop = (arrayOop)jniCheck::validate_object(thr, jArray); 319 if (aOop == nullptr || !aOop->is_array()) { 320 ReportJNIFatalError(thr, fatal_non_array); 321 } 322 return aOop; 323 } 324 325 static inline arrayOop 326 check_is_primitive_array(JavaThread* thr, jarray jArray) { 327 arrayOop aOop = check_is_array(thr, jArray); 328 329 if (!aOop->is_typeArray()) { 330 ReportJNIFatalError(thr, fatal_prim_type_array_expected); 331 } 332 return aOop; 333 } 334 335 static inline void 336 check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType) 337 { 338 BasicType array_type; 339 arrayOop aOop; 340 341 aOop = check_is_primitive_array(thr, jArray); 342 array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); 343 if (array_type != elementType) { 344 ReportJNIFatalError(thr, fatal_element_type_mismatch); 345 } 346 } 347 348 static inline void 349 check_is_obj_or_inline_array(JavaThread* thr, jarray jArray) { 350 arrayOop aOop = check_is_array(thr, jArray); 351 if (!aOop->is_objArray() && !aOop->is_flatArray()) { 352 ReportJNIFatalError(thr, fatal_object_array_expected); 353 } 354 } 355 356 /* 357 * Copy and wrap array elements for bounds checking. 358 * Remember the original elements (GuardedMemory::get_tag()) 359 */ 360 static void* check_jni_wrap_copy_array(JavaThread* thr, jarray array, 361 void* orig_elements) { 362 void* result; 363 IN_VM( 364 oop a = JNIHandles::resolve_non_null(array); 365 size_t len = arrayOop(a)->length() << 366 TypeArrayKlass::cast(a->klass())->log2_element_size(); 367 result = GuardedMemory::wrap_copy(orig_elements, len, orig_elements); 368 ) 369 return result; 370 } 371 372 static void* check_wrapped_array(JavaThread* thr, const char* fn_name, 373 void* obj, void* carray, size_t* rsz) { 374 if (carray == nullptr) { 375 tty->print_cr("%s: elements vector null" PTR_FORMAT, fn_name, p2i(obj)); 376 NativeReportJNIFatalError(thr, "Elements vector null"); 377 } 378 GuardedMemory guarded(carray); 379 void* orig_result = guarded.get_tag(); 380 if (!guarded.verify_guards()) { 381 tty->print_cr("%s: release array failed bounds check, incorrect pointer returned ? array: " 382 PTR_FORMAT " carray: " PTR_FORMAT, fn_name, p2i(obj), p2i(carray)); 383 DEBUG_ONLY(guarded.print_on(tty);) // This may crash. 384 NativeReportJNIFatalError(thr, err_msg("%s: failed bounds check", fn_name)); 385 } 386 if (orig_result == nullptr) { 387 tty->print_cr("%s: unrecognized elements. array: " PTR_FORMAT " carray: " PTR_FORMAT, 388 fn_name, p2i(obj), p2i(carray)); 389 DEBUG_ONLY(guarded.print_on(tty);) // This may crash. 390 NativeReportJNIFatalError(thr, err_msg("%s: unrecognized elements", fn_name)); 391 } 392 if (rsz != nullptr) { 393 *rsz = guarded.get_user_size(); 394 } 395 return orig_result; 396 } 397 398 static void* check_wrapped_array_release(JavaThread* thr, const char* fn_name, 399 void* obj, void* carray, jint mode, jboolean is_critical) { 400 size_t sz; 401 void* orig_result = check_wrapped_array(thr, fn_name, obj, carray, &sz); 402 switch (mode) { 403 case 0: 404 memcpy(orig_result, carray, sz); 405 GuardedMemory::free_copy(carray); 406 break; 407 case JNI_COMMIT: 408 memcpy(orig_result, carray, sz); 409 if (is_critical) { 410 // For ReleasePrimitiveArrayCritical we must free the internal buffer 411 // allocated through GuardedMemory. 412 GuardedMemory::free_copy(carray); 413 } 414 break; 415 case JNI_ABORT: 416 GuardedMemory::free_copy(carray); 417 break; 418 default: 419 tty->print_cr("%s: Unrecognized mode %i releasing array " 420 PTR_FORMAT " elements " PTR_FORMAT, fn_name, mode, p2i(obj), p2i(carray)); 421 NativeReportJNIFatalError(thr, "Unrecognized array release mode"); 422 } 423 return orig_result; 424 } 425 426 oop jniCheck::validate_handle(JavaThread* thr, jobject obj) { 427 if ((obj != nullptr) && (JNIHandles::handle_type(thr, obj) != JNIInvalidRefType)) { 428 ASSERT_OOPS_ALLOWED; 429 return JNIHandles::resolve_external_guard(obj); 430 } 431 ReportJNIFatalError(thr, fatal_bad_ref_to_jni); 432 return nullptr; 433 } 434 435 436 Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) { 437 ASSERT_OOPS_ALLOWED; 438 // do the fast jmethodID check first 439 Method* m = Method::checked_resolve_jmethod_id(method_id); 440 if (m == nullptr) { 441 ReportJNIFatalError(thr, fatal_wrong_class_or_method); 442 } 443 // jmethodIDs are handles in the class loader data, 444 // but that can be expensive so check it last 445 else if (!Method::is_method_id(method_id)) { 446 ReportJNIFatalError(thr, fatal_non_weak_method); 447 } 448 return m; 449 } 450 451 452 oop jniCheck::validate_object(JavaThread* thr, jobject obj) { 453 if (obj == nullptr) return nullptr; 454 ASSERT_OOPS_ALLOWED; 455 oop oopObj = jniCheck::validate_handle(thr, obj); 456 if (oopObj == nullptr) { 457 ReportJNIFatalError(thr, fatal_bad_ref_to_jni); 458 } 459 return oopObj; 460 } 461 462 // Warn if a class descriptor is in decorated form; class descriptors 463 // passed to JNI findClass should not be decorated unless they are 464 // array descriptors. 465 void jniCheck::validate_class_descriptor(JavaThread* thr, const char* name) { 466 if (name == nullptr) return; // implementation accepts null so just return 467 468 size_t len = strlen(name); 469 470 if (len >= 2 && 471 (name[0] == JVM_SIGNATURE_CLASS || name[0] == JVM_SIGNATURE_PRIMITIVE_OBJECT) && // 'L' or 'Q' 472 name[len-1] == JVM_SIGNATURE_ENDCLASS ) { // ';' 473 char msg[JVM_MAXPATHLEN]; 474 jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", 475 warn_bad_class_descriptor1, name, warn_bad_class_descriptor2); 476 ReportJNIWarning(thr, msg); 477 } 478 479 // Verify that the class name given is a valid utf8 string 480 if (!UTF8::is_legal_utf8((const unsigned char*)name, (int)strlen(name), false)) { 481 char msg[JVM_MAXPATHLEN]; 482 jio_snprintf(msg, JVM_MAXPATHLEN, "%s%s%s", fatal_non_utf8_class_name1, name, fatal_non_utf8_class_name2); 483 ReportJNIFatalError(thr, msg); 484 } 485 } 486 487 Klass* jniCheck::validate_class(JavaThread* thr, jclass clazz, bool allow_primitive) { 488 ASSERT_OOPS_ALLOWED; 489 oop mirror = jniCheck::validate_handle(thr, clazz); 490 if (mirror == nullptr) { 491 ReportJNIFatalError(thr, fatal_received_null_class); 492 } 493 494 if (mirror->klass() != vmClasses::Class_klass()) { 495 ReportJNIFatalError(thr, fatal_class_not_a_class); 496 } 497 498 Klass* k = java_lang_Class::as_Klass(mirror); 499 // Make allowances for primitive classes ... 500 if (!(k != nullptr || (allow_primitive && java_lang_Class::is_primitive(mirror)))) { 501 ReportJNIFatalError(thr, fatal_class_not_a_class); 502 } 503 return k; 504 } 505 506 void jniCheck::validate_throwable_klass(JavaThread* thr, Klass* klass) { 507 ASSERT_OOPS_ALLOWED; 508 assert(klass != nullptr, "klass argument must have a value"); 509 510 if (!klass->is_instance_klass() || 511 !klass->is_subclass_of(vmClasses::Throwable_klass())) { 512 ReportJNIFatalError(thr, fatal_class_not_a_throwable_class); 513 } 514 } 515 516 void jniCheck::validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj) { 517 ASSERT_OOPS_ALLOWED; 518 Method* m = jniCheck::validate_jmethod_id(thr, method_id); 519 InstanceKlass* holder = m->method_holder(); 520 521 if (clazz != nullptr) { 522 Klass* k = jniCheck::validate_class(thr, clazz, false); 523 // Check that method is in the class, must be InstanceKlass 524 if (!InstanceKlass::cast(k)->is_subtype_of(holder)) { 525 ReportJNIFatalError(thr, fatal_wrong_class_or_method); 526 } 527 } 528 529 if (obj != nullptr) { 530 oop recv = jniCheck::validate_object(thr, obj); 531 assert(recv != nullptr, "validate_object checks that"); 532 Klass* rk = recv->klass(); 533 534 // Check that the object is a subtype of method holder too. 535 if (!rk->is_subtype_of(holder)) { 536 ReportJNIFatalError(thr, fatal_wrong_class_or_method); 537 } 538 } 539 } 540 541 542 /* 543 * IMPLEMENTATION OF FUNCTIONS IN CHECKED TABLE 544 */ 545 546 JNI_ENTRY_CHECKED(jclass, 547 checked_jni_DefineClass(JNIEnv *env, 548 const char *name, 549 jobject loader, 550 const jbyte *buf, 551 jsize len)) 552 functionEnter(thr); 553 IN_VM( 554 jniCheck::validate_object(thr, loader); 555 ) 556 jclass result = UNCHECKED()->DefineClass(env, name, loader, buf, len); 557 functionExit(thr); 558 return result; 559 JNI_END 560 561 JNI_ENTRY_CHECKED(jclass, 562 checked_jni_FindClass(JNIEnv *env, 563 const char *name)) 564 functionEnter(thr); 565 IN_VM( 566 jniCheck::validate_class_descriptor(thr, name); 567 ) 568 jclass result = UNCHECKED()->FindClass(env, name); 569 functionExit(thr); 570 return result; 571 JNI_END 572 573 JNI_ENTRY_CHECKED(jmethodID, 574 checked_jni_FromReflectedMethod(JNIEnv *env, 575 jobject method)) 576 functionEnter(thr); 577 IN_VM( 578 jniCheck::validate_object(thr, method); 579 ) 580 jmethodID result = UNCHECKED()->FromReflectedMethod(env, method); 581 functionExit(thr); 582 return result; 583 JNI_END 584 585 JNI_ENTRY_CHECKED(jfieldID, 586 checked_jni_FromReflectedField(JNIEnv *env, 587 jobject field)) 588 functionEnter(thr); 589 IN_VM( 590 jniCheck::validate_object(thr, field); 591 ) 592 jfieldID result = UNCHECKED()->FromReflectedField(env, field); 593 functionExit(thr); 594 return result; 595 JNI_END 596 597 JNI_ENTRY_CHECKED(jobject, 598 checked_jni_ToReflectedMethod(JNIEnv *env, 599 jclass cls, 600 jmethodID methodID, 601 jboolean isStatic)) 602 functionEnter(thr); 603 IN_VM( 604 jniCheck::validate_call(thr, cls, methodID); 605 ) 606 jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID, 607 isStatic); 608 functionExit(thr); 609 return result; 610 JNI_END 611 612 JNI_ENTRY_CHECKED(jclass, 613 checked_jni_GetSuperclass(JNIEnv *env, 614 jclass sub)) 615 functionEnter(thr); 616 IN_VM( 617 jniCheck::validate_class(thr, sub, true); 618 ) 619 jclass result = UNCHECKED()->GetSuperclass(env, sub); 620 functionExit(thr); 621 return result; 622 JNI_END 623 624 JNI_ENTRY_CHECKED(jboolean, 625 checked_jni_IsAssignableFrom(JNIEnv *env, 626 jclass sub, 627 jclass sup)) 628 functionEnter(thr); 629 IN_VM( 630 jniCheck::validate_class(thr, sub, true); 631 jniCheck::validate_class(thr, sup, true); 632 ) 633 jboolean result = UNCHECKED()->IsAssignableFrom(env, sub, sup); 634 functionExit(thr); 635 return result; 636 JNI_END 637 638 JNI_ENTRY_CHECKED(jobject, 639 checked_jni_ToReflectedField(JNIEnv *env, 640 jclass cls, 641 jfieldID fieldID, 642 jboolean isStatic)) 643 functionEnter(thr); 644 IN_VM( 645 jniCheck::validate_class(thr, cls, false); 646 ) 647 jobject result = UNCHECKED()->ToReflectedField(env, cls, fieldID, 648 isStatic); 649 functionExit(thr); 650 return result; 651 JNI_END 652 653 JNI_ENTRY_CHECKED(jint, 654 checked_jni_Throw(JNIEnv *env, 655 jthrowable obj)) 656 functionEnter(thr); 657 IN_VM( 658 oop oopObj = jniCheck::validate_object(thr, obj); 659 if (oopObj == nullptr) { 660 // Unchecked Throw tolerates a null obj, so just warn 661 ReportJNIWarning(thr, "JNI Throw called with null throwable"); 662 } else { 663 jniCheck::validate_throwable_klass(thr, oopObj->klass()); 664 } 665 ) 666 jint result = UNCHECKED()->Throw(env, obj); 667 functionExit(thr); 668 return result; 669 JNI_END 670 671 JNI_ENTRY_CHECKED(jint, 672 checked_jni_ThrowNew(JNIEnv *env, 673 jclass clazz, 674 const char *msg)) 675 functionEnter(thr); 676 IN_VM( 677 Klass* k = jniCheck::validate_class(thr, clazz, false); 678 assert(k != nullptr, "validate_class shouldn't return null Klass*"); 679 jniCheck::validate_throwable_klass(thr, k); 680 ) 681 jint result = UNCHECKED()->ThrowNew(env, clazz, msg); 682 functionExit(thr); 683 return result; 684 JNI_END 685 686 JNI_ENTRY_CHECKED(jthrowable, 687 checked_jni_ExceptionOccurred(JNIEnv *env)) 688 thr->clear_pending_jni_exception_check(); 689 functionEnterExceptionAllowed(thr); 690 jthrowable result = UNCHECKED()->ExceptionOccurred(env); 691 functionExit(thr); 692 return result; 693 JNI_END 694 695 JNI_ENTRY_CHECKED(void, 696 checked_jni_ExceptionDescribe(JNIEnv *env)) 697 functionEnterExceptionAllowed(thr); 698 UNCHECKED()->ExceptionDescribe(env); 699 functionExit(thr); 700 JNI_END 701 702 JNI_ENTRY_CHECKED(void, 703 checked_jni_ExceptionClear(JNIEnv *env)) 704 thr->clear_pending_jni_exception_check(); 705 functionEnterExceptionAllowed(thr); 706 UNCHECKED()->ExceptionClear(env); 707 functionExit(thr); 708 JNI_END 709 710 JNI_ENTRY_CHECKED(void, 711 checked_jni_FatalError(JNIEnv *env, 712 const char *msg)) 713 thr->clear_pending_jni_exception_check(); 714 functionEnter(thr); 715 UNCHECKED()->FatalError(env, msg); 716 functionExit(thr); 717 JNI_END 718 719 JNI_ENTRY_CHECKED(jint, 720 checked_jni_PushLocalFrame(JNIEnv *env, 721 jint capacity)) 722 functionEnterExceptionAllowed(thr); 723 if (capacity < 0) 724 NativeReportJNIFatalError(thr, "negative capacity"); 725 jint result = UNCHECKED()->PushLocalFrame(env, capacity); 726 functionExit(thr); 727 return result; 728 JNI_END 729 730 JNI_ENTRY_CHECKED(jobject, 731 checked_jni_PopLocalFrame(JNIEnv *env, 732 jobject result)) 733 functionEnterExceptionAllowed(thr); 734 jobject res = UNCHECKED()->PopLocalFrame(env, result); 735 functionExit(thr); 736 return res; 737 JNI_END 738 739 JNI_ENTRY_CHECKED(jobject, 740 checked_jni_NewGlobalRef(JNIEnv *env, 741 jobject lobj)) 742 functionEnter(thr); 743 IN_VM( 744 if (lobj != nullptr) { 745 jniCheck::validate_handle(thr, lobj); 746 } 747 ) 748 jobject result = UNCHECKED()->NewGlobalRef(env,lobj); 749 functionExit(thr); 750 return result; 751 JNI_END 752 753 JNI_ENTRY_CHECKED(void, 754 checked_jni_DeleteGlobalRef(JNIEnv *env, 755 jobject gref)) 756 functionEnterExceptionAllowed(thr); 757 IN_VM( 758 jniCheck::validate_object(thr, gref); 759 if (gref && !JNIHandles::is_global_handle(gref)) { 760 ReportJNIFatalError(thr, 761 "Invalid global JNI handle passed to DeleteGlobalRef"); 762 } 763 ) 764 UNCHECKED()->DeleteGlobalRef(env,gref); 765 functionExit(thr); 766 JNI_END 767 768 JNI_ENTRY_CHECKED(void, 769 checked_jni_DeleteLocalRef(JNIEnv *env, 770 jobject obj)) 771 functionEnterExceptionAllowed(thr); 772 IN_VM( 773 jniCheck::validate_object(thr, obj); 774 if (obj && !(JNIHandles::is_local_handle(thr, obj) || 775 JNIHandles::is_frame_handle(thr, obj))) 776 ReportJNIFatalError(thr, 777 "Invalid local JNI handle passed to DeleteLocalRef"); 778 ) 779 UNCHECKED()->DeleteLocalRef(env, obj); 780 functionExit(thr); 781 JNI_END 782 783 JNI_ENTRY_CHECKED(jboolean, 784 checked_jni_IsSameObject(JNIEnv *env, 785 jobject obj1, 786 jobject obj2)) 787 functionEnterExceptionAllowed(thr); 788 IN_VM( 789 /* This JNI function can be used to compare weak global references 790 * to nullptr objects. If the handles are valid, but contain nullptr, 791 * then don't attempt to validate the object. 792 */ 793 if (obj1 != nullptr && jniCheck::validate_handle(thr, obj1) != nullptr) { 794 jniCheck::validate_object(thr, obj1); 795 } 796 if (obj2 != nullptr && jniCheck::validate_handle(thr, obj2) != nullptr) { 797 jniCheck::validate_object(thr, obj2); 798 } 799 ) 800 jboolean result = UNCHECKED()->IsSameObject(env,obj1,obj2); 801 functionExit(thr); 802 return result; 803 JNI_END 804 805 JNI_ENTRY_CHECKED(jobject, 806 checked_jni_NewLocalRef(JNIEnv *env, 807 jobject ref)) 808 functionEnter(thr); 809 IN_VM( 810 if (ref != nullptr) { 811 jniCheck::validate_handle(thr, ref); 812 } 813 ) 814 jobject result = UNCHECKED()->NewLocalRef(env, ref); 815 functionExit(thr); 816 return result; 817 JNI_END 818 819 JNI_ENTRY_CHECKED(jint, 820 checked_jni_EnsureLocalCapacity(JNIEnv *env, 821 jint capacity)) 822 functionEnter(thr); 823 if (capacity < 0) { 824 NativeReportJNIFatalError(thr, "negative capacity"); 825 } 826 jint result = UNCHECKED()->EnsureLocalCapacity(env, capacity); 827 functionExit(thr); 828 return result; 829 JNI_END 830 831 JNI_ENTRY_CHECKED(jobject, 832 checked_jni_AllocObject(JNIEnv *env, 833 jclass clazz)) 834 functionEnter(thr); 835 IN_VM( 836 jniCheck::validate_class(thr, clazz, false); 837 ) 838 jobject result = UNCHECKED()->AllocObject(env,clazz); 839 functionExit(thr); 840 return result; 841 JNI_END 842 843 JNI_ENTRY_CHECKED(jobject, 844 checked_jni_NewObject(JNIEnv *env, 845 jclass clazz, 846 jmethodID methodID, 847 ...)) 848 functionEnter(thr); 849 va_list args; 850 IN_VM( 851 jniCheck::validate_call(thr, clazz, methodID); 852 ) 853 va_start(args, methodID); 854 jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); 855 va_end(args); 856 functionExit(thr); 857 return result; 858 JNI_END 859 860 JNI_ENTRY_CHECKED(jobject, 861 checked_jni_NewObjectV(JNIEnv *env, 862 jclass clazz, 863 jmethodID methodID, 864 va_list args)) 865 functionEnter(thr); 866 IN_VM( 867 jniCheck::validate_call(thr, clazz, methodID); 868 ) 869 jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args); 870 functionExit(thr); 871 return result; 872 JNI_END 873 874 JNI_ENTRY_CHECKED(jobject, 875 checked_jni_NewObjectA(JNIEnv *env, 876 jclass clazz, 877 jmethodID methodID, 878 const jvalue *args)) 879 functionEnter(thr); 880 IN_VM( 881 jniCheck::validate_call(thr, clazz, methodID); 882 ) 883 jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args); 884 functionExit(thr); 885 return result; 886 JNI_END 887 888 JNI_ENTRY_CHECKED(jclass, 889 checked_jni_GetObjectClass(JNIEnv *env, 890 jobject obj)) 891 functionEnter(thr); 892 IN_VM( 893 jniCheck::validate_object(thr, obj); 894 ) 895 jclass result = UNCHECKED()->GetObjectClass(env,obj); 896 functionExit(thr); 897 return result; 898 JNI_END 899 900 JNI_ENTRY_CHECKED(jboolean, 901 checked_jni_IsInstanceOf(JNIEnv *env, 902 jobject obj, 903 jclass clazz)) 904 functionEnter(thr); 905 IN_VM( 906 jniCheck::validate_object(thr, obj); 907 jniCheck::validate_class(thr, clazz, true); 908 ) 909 jboolean result = UNCHECKED()->IsInstanceOf(env,obj,clazz); 910 functionExit(thr); 911 return result; 912 JNI_END 913 914 JNI_ENTRY_CHECKED(jmethodID, 915 checked_jni_GetMethodID(JNIEnv *env, 916 jclass clazz, 917 const char *name, 918 const char *sig)) 919 functionEnter(thr); 920 IN_VM( 921 jniCheck::validate_class(thr, clazz, false); 922 ) 923 jmethodID result = UNCHECKED()->GetMethodID(env,clazz,name,sig); 924 functionExit(thr); 925 return result; 926 JNI_END 927 928 #define WRAPPER_CallMethod(ResultType, Result) \ 929 JNI_ENTRY_CHECKED(ResultType, \ 930 checked_jni_Call##Result##Method(JNIEnv *env, \ 931 jobject obj, \ 932 jmethodID methodID, \ 933 ...)) \ 934 functionEnter(thr); \ 935 va_list args; \ 936 IN_VM( \ 937 jniCheck::validate_call(thr, nullptr, methodID, obj); \ 938 ) \ 939 va_start(args,methodID); \ 940 ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \ 941 args); \ 942 va_end(args); \ 943 thr->set_pending_jni_exception_check("Call"#Result"Method"); \ 944 functionExit(thr); \ 945 return result; \ 946 JNI_END \ 947 \ 948 JNI_ENTRY_CHECKED(ResultType, \ 949 checked_jni_Call##Result##MethodV(JNIEnv *env, \ 950 jobject obj, \ 951 jmethodID methodID, \ 952 va_list args)) \ 953 functionEnter(thr); \ 954 IN_VM(\ 955 jniCheck::validate_call(thr, nullptr, methodID, obj); \ 956 ) \ 957 ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\ 958 args); \ 959 thr->set_pending_jni_exception_check("Call"#Result"MethodV"); \ 960 functionExit(thr); \ 961 return result; \ 962 JNI_END \ 963 \ 964 JNI_ENTRY_CHECKED(ResultType, \ 965 checked_jni_Call##Result##MethodA(JNIEnv *env, \ 966 jobject obj, \ 967 jmethodID methodID, \ 968 const jvalue * args)) \ 969 functionEnter(thr); \ 970 IN_VM( \ 971 jniCheck::validate_call(thr, nullptr, methodID, obj); \ 972 ) \ 973 ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\ 974 args); \ 975 thr->set_pending_jni_exception_check("Call"#Result"MethodA"); \ 976 functionExit(thr); \ 977 return result; \ 978 JNI_END 979 980 WRAPPER_CallMethod(jobject,Object) 981 WRAPPER_CallMethod(jboolean,Boolean) 982 WRAPPER_CallMethod(jbyte,Byte) 983 WRAPPER_CallMethod(jshort,Short) 984 WRAPPER_CallMethod(jchar,Char) 985 WRAPPER_CallMethod(jint,Int) 986 WRAPPER_CallMethod(jlong,Long) 987 WRAPPER_CallMethod(jfloat,Float) 988 WRAPPER_CallMethod(jdouble,Double) 989 990 JNI_ENTRY_CHECKED(void, 991 checked_jni_CallVoidMethod(JNIEnv *env, \ 992 jobject obj, \ 993 jmethodID methodID, \ 994 ...)) 995 functionEnter(thr); 996 va_list args; 997 IN_VM( 998 jniCheck::validate_call(thr, nullptr, methodID, obj); 999 ) 1000 va_start(args,methodID); 1001 UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); 1002 va_end(args); 1003 thr->set_pending_jni_exception_check("CallVoidMethod"); 1004 functionExit(thr); 1005 JNI_END 1006 1007 JNI_ENTRY_CHECKED(void, 1008 checked_jni_CallVoidMethodV(JNIEnv *env, 1009 jobject obj, 1010 jmethodID methodID, 1011 va_list args)) 1012 functionEnter(thr); 1013 IN_VM( 1014 jniCheck::validate_call(thr, nullptr, methodID, obj); 1015 ) 1016 UNCHECKED()->CallVoidMethodV(env,obj,methodID,args); 1017 thr->set_pending_jni_exception_check("CallVoidMethodV"); 1018 functionExit(thr); 1019 JNI_END 1020 1021 JNI_ENTRY_CHECKED(void, 1022 checked_jni_CallVoidMethodA(JNIEnv *env, 1023 jobject obj, 1024 jmethodID methodID, 1025 const jvalue * args)) 1026 functionEnter(thr); 1027 IN_VM( 1028 jniCheck::validate_call(thr, nullptr, methodID, obj); 1029 ) 1030 UNCHECKED()->CallVoidMethodA(env,obj,methodID,args); 1031 thr->set_pending_jni_exception_check("CallVoidMethodA"); 1032 functionExit(thr); 1033 JNI_END 1034 1035 #define WRAPPER_CallNonvirtualMethod(ResultType, Result) \ 1036 JNI_ENTRY_CHECKED(ResultType, \ 1037 checked_jni_CallNonvirtual##Result##Method(JNIEnv *env, \ 1038 jobject obj, \ 1039 jclass clazz, \ 1040 jmethodID methodID, \ 1041 ...)) \ 1042 functionEnter(thr); \ 1043 va_list args; \ 1044 IN_VM( \ 1045 jniCheck::validate_call(thr, clazz, methodID, obj); \ 1046 ) \ 1047 va_start(args,methodID); \ 1048 ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ 1049 obj, \ 1050 clazz, \ 1051 methodID,\ 1052 args); \ 1053 va_end(args); \ 1054 thr->set_pending_jni_exception_check("CallNonvirtual"#Result"Method"); \ 1055 functionExit(thr); \ 1056 return result; \ 1057 JNI_END \ 1058 \ 1059 JNI_ENTRY_CHECKED(ResultType, \ 1060 checked_jni_CallNonvirtual##Result##MethodV(JNIEnv *env, \ 1061 jobject obj, \ 1062 jclass clazz, \ 1063 jmethodID methodID, \ 1064 va_list args)) \ 1065 functionEnter(thr); \ 1066 IN_VM( \ 1067 jniCheck::validate_call(thr, clazz, methodID, obj); \ 1068 ) \ 1069 ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \ 1070 obj, \ 1071 clazz, \ 1072 methodID,\ 1073 args); \ 1074 thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodV"); \ 1075 functionExit(thr); \ 1076 return result; \ 1077 JNI_END \ 1078 \ 1079 JNI_ENTRY_CHECKED(ResultType, \ 1080 checked_jni_CallNonvirtual##Result##MethodA(JNIEnv *env, \ 1081 jobject obj, \ 1082 jclass clazz, \ 1083 jmethodID methodID, \ 1084 const jvalue * args)) \ 1085 functionEnter(thr); \ 1086 IN_VM( \ 1087 jniCheck::validate_call(thr, clazz, methodID, obj); \ 1088 ) \ 1089 ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \ 1090 obj, \ 1091 clazz, \ 1092 methodID,\ 1093 args); \ 1094 thr->set_pending_jni_exception_check("CallNonvirtual"#Result"MethodA"); \ 1095 functionExit(thr); \ 1096 return result; \ 1097 JNI_END 1098 1099 WRAPPER_CallNonvirtualMethod(jobject,Object) 1100 WRAPPER_CallNonvirtualMethod(jboolean,Boolean) 1101 WRAPPER_CallNonvirtualMethod(jbyte,Byte) 1102 WRAPPER_CallNonvirtualMethod(jshort,Short) 1103 WRAPPER_CallNonvirtualMethod(jchar,Char) 1104 WRAPPER_CallNonvirtualMethod(jint,Int) 1105 WRAPPER_CallNonvirtualMethod(jlong,Long) 1106 WRAPPER_CallNonvirtualMethod(jfloat,Float) 1107 WRAPPER_CallNonvirtualMethod(jdouble,Double) 1108 1109 JNI_ENTRY_CHECKED(void, 1110 checked_jni_CallNonvirtualVoidMethod(JNIEnv *env, 1111 jobject obj, 1112 jclass clazz, 1113 jmethodID methodID, 1114 ...)) 1115 functionEnter(thr); 1116 va_list args; 1117 IN_VM( 1118 jniCheck::validate_call(thr, clazz, methodID, obj); 1119 ) 1120 va_start(args,methodID); 1121 UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); 1122 va_end(args); 1123 thr->set_pending_jni_exception_check("CallNonvirtualVoidMethod"); 1124 functionExit(thr); 1125 JNI_END 1126 1127 JNI_ENTRY_CHECKED(void, 1128 checked_jni_CallNonvirtualVoidMethodV(JNIEnv *env, 1129 jobject obj, 1130 jclass clazz, 1131 jmethodID methodID, 1132 va_list args)) 1133 functionEnter(thr); 1134 IN_VM( 1135 jniCheck::validate_call(thr, clazz, methodID, obj); 1136 ) 1137 UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args); 1138 thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV"); 1139 functionExit(thr); 1140 JNI_END 1141 1142 JNI_ENTRY_CHECKED(void, 1143 checked_jni_CallNonvirtualVoidMethodA(JNIEnv *env, 1144 jobject obj, 1145 jclass clazz, 1146 jmethodID methodID, 1147 const jvalue * args)) 1148 functionEnter(thr); 1149 IN_VM( 1150 jniCheck::validate_call(thr, clazz, methodID, obj); 1151 ) 1152 UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args); 1153 thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA"); 1154 functionExit(thr); 1155 JNI_END 1156 1157 JNI_ENTRY_CHECKED(jfieldID, 1158 checked_jni_GetFieldID(JNIEnv *env, 1159 jclass clazz, 1160 const char *name, 1161 const char *sig)) 1162 functionEnter(thr); 1163 IN_VM( 1164 jniCheck::validate_class(thr, clazz, false); 1165 ) 1166 jfieldID result = UNCHECKED()->GetFieldID(env,clazz,name,sig); 1167 functionExit(thr); 1168 return result; 1169 JNI_END 1170 1171 #define WRAPPER_GetField(ReturnType,Result,FieldType) \ 1172 JNI_ENTRY_CHECKED(ReturnType, \ 1173 checked_jni_Get##Result##Field(JNIEnv *env, \ 1174 jobject obj, \ 1175 jfieldID fieldID)) \ 1176 functionEnter(thr); \ 1177 IN_VM( \ 1178 checkInstanceFieldID(thr, fieldID, obj, FieldType); \ 1179 ) \ 1180 ReturnType result = UNCHECKED()->Get##Result##Field(env,obj,fieldID); \ 1181 functionExit(thr); \ 1182 return result; \ 1183 JNI_END 1184 1185 WRAPPER_GetField(jobject, Object, T_OBJECT) 1186 WRAPPER_GetField(jboolean, Boolean, T_BOOLEAN) 1187 WRAPPER_GetField(jbyte, Byte, T_BYTE) 1188 WRAPPER_GetField(jshort, Short, T_SHORT) 1189 WRAPPER_GetField(jchar, Char, T_CHAR) 1190 WRAPPER_GetField(jint, Int, T_INT) 1191 WRAPPER_GetField(jlong, Long, T_LONG) 1192 WRAPPER_GetField(jfloat, Float, T_FLOAT) 1193 WRAPPER_GetField(jdouble, Double, T_DOUBLE) 1194 1195 #define WRAPPER_SetField(ValueType,Result,FieldType) \ 1196 JNI_ENTRY_CHECKED(void, \ 1197 checked_jni_Set##Result##Field(JNIEnv *env, \ 1198 jobject obj, \ 1199 jfieldID fieldID, \ 1200 ValueType val)) \ 1201 functionEnter(thr); \ 1202 IN_VM( \ 1203 checkInstanceFieldID(thr, fieldID, obj, FieldType); \ 1204 ) \ 1205 UNCHECKED()->Set##Result##Field(env,obj,fieldID,val); \ 1206 functionExit(thr); \ 1207 JNI_END 1208 1209 WRAPPER_SetField(jobject, Object, T_OBJECT) 1210 WRAPPER_SetField(jboolean, Boolean, T_BOOLEAN) 1211 WRAPPER_SetField(jbyte, Byte, T_BYTE) 1212 WRAPPER_SetField(jshort, Short, T_SHORT) 1213 WRAPPER_SetField(jchar, Char, T_CHAR) 1214 WRAPPER_SetField(jint, Int, T_INT) 1215 WRAPPER_SetField(jlong, Long, T_LONG) 1216 WRAPPER_SetField(jfloat, Float, T_FLOAT) 1217 WRAPPER_SetField(jdouble, Double, T_DOUBLE) 1218 1219 1220 JNI_ENTRY_CHECKED(jmethodID, 1221 checked_jni_GetStaticMethodID(JNIEnv *env, 1222 jclass clazz, 1223 const char *name, 1224 const char *sig)) 1225 functionEnter(thr); 1226 IN_VM( 1227 jniCheck::validate_class(thr, clazz, false); 1228 ) 1229 jmethodID result = UNCHECKED()->GetStaticMethodID(env,clazz,name,sig); 1230 functionExit(thr); 1231 return result; 1232 JNI_END 1233 1234 #define WRAPPER_CallStaticMethod(ReturnType,Result) \ 1235 JNI_ENTRY_CHECKED(ReturnType, \ 1236 checked_jni_CallStatic##Result##Method(JNIEnv *env, \ 1237 jclass clazz, \ 1238 jmethodID methodID, \ 1239 ...)) \ 1240 functionEnter(thr); \ 1241 va_list args; \ 1242 IN_VM( \ 1243 jniCheck::validate_call(thr, clazz, methodID); \ 1244 ) \ 1245 va_start(args,methodID); \ 1246 ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ 1247 clazz, \ 1248 methodID, \ 1249 args); \ 1250 va_end(args); \ 1251 thr->set_pending_jni_exception_check("CallStatic"#Result"Method"); \ 1252 functionExit(thr); \ 1253 return result; \ 1254 JNI_END \ 1255 \ 1256 JNI_ENTRY_CHECKED(ReturnType, \ 1257 checked_jni_CallStatic##Result##MethodV(JNIEnv *env, \ 1258 jclass clazz, \ 1259 jmethodID methodID,\ 1260 va_list args)) \ 1261 functionEnter(thr); \ 1262 IN_VM( \ 1263 jniCheck::validate_call(thr, clazz, methodID); \ 1264 ) \ 1265 ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \ 1266 clazz, \ 1267 methodID, \ 1268 args); \ 1269 thr->set_pending_jni_exception_check("CallStatic"#Result"MethodV"); \ 1270 functionExit(thr); \ 1271 return result; \ 1272 JNI_END \ 1273 \ 1274 JNI_ENTRY_CHECKED(ReturnType, \ 1275 checked_jni_CallStatic##Result##MethodA(JNIEnv *env, \ 1276 jclass clazz, \ 1277 jmethodID methodID, \ 1278 const jvalue *args)) \ 1279 functionEnter(thr); \ 1280 IN_VM( \ 1281 jniCheck::validate_call(thr, clazz, methodID); \ 1282 ) \ 1283 ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \ 1284 clazz, \ 1285 methodID, \ 1286 args); \ 1287 thr->set_pending_jni_exception_check("CallStatic"#Result"MethodA"); \ 1288 functionExit(thr); \ 1289 return result; \ 1290 JNI_END 1291 1292 WRAPPER_CallStaticMethod(jobject,Object) 1293 WRAPPER_CallStaticMethod(jboolean,Boolean) 1294 WRAPPER_CallStaticMethod(jbyte,Byte) 1295 WRAPPER_CallStaticMethod(jshort,Short) 1296 WRAPPER_CallStaticMethod(jchar,Char) 1297 WRAPPER_CallStaticMethod(jint,Int) 1298 WRAPPER_CallStaticMethod(jlong,Long) 1299 WRAPPER_CallStaticMethod(jfloat,Float) 1300 WRAPPER_CallStaticMethod(jdouble,Double) 1301 1302 JNI_ENTRY_CHECKED(void, 1303 checked_jni_CallStaticVoidMethod(JNIEnv *env, 1304 jclass cls, 1305 jmethodID methodID, 1306 ...)) 1307 functionEnter(thr); 1308 va_list args; 1309 IN_VM( 1310 jniCheck::validate_call(thr, cls, methodID); 1311 ) 1312 va_start(args,methodID); 1313 UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); 1314 va_end(args); 1315 thr->set_pending_jni_exception_check("CallStaticVoidMethod"); 1316 functionExit(thr); 1317 JNI_END 1318 1319 JNI_ENTRY_CHECKED(void, 1320 checked_jni_CallStaticVoidMethodV(JNIEnv *env, 1321 jclass cls, 1322 jmethodID methodID, 1323 va_list args)) 1324 functionEnter(thr); 1325 IN_VM( 1326 jniCheck::validate_call(thr, cls, methodID); 1327 ) 1328 UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args); 1329 thr->set_pending_jni_exception_check("CallStaticVoidMethodV"); 1330 functionExit(thr); 1331 JNI_END 1332 1333 JNI_ENTRY_CHECKED(void, 1334 checked_jni_CallStaticVoidMethodA(JNIEnv *env, 1335 jclass cls, 1336 jmethodID methodID, 1337 const jvalue * args)) 1338 functionEnter(thr); 1339 IN_VM( 1340 jniCheck::validate_call(thr, cls, methodID); 1341 ) 1342 UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args); 1343 thr->set_pending_jni_exception_check("CallStaticVoidMethodA"); 1344 functionExit(thr); 1345 JNI_END 1346 1347 JNI_ENTRY_CHECKED(jfieldID, 1348 checked_jni_GetStaticFieldID(JNIEnv *env, 1349 jclass clazz, 1350 const char *name, 1351 const char *sig)) 1352 functionEnter(thr); 1353 IN_VM( 1354 jniCheck::validate_class(thr, clazz, false); 1355 ) 1356 jfieldID result = UNCHECKED()->GetStaticFieldID(env,clazz,name,sig); 1357 functionExit(thr); 1358 return result; 1359 JNI_END 1360 1361 #define WRAPPER_GetStaticField(ReturnType,Result,FieldType) \ 1362 JNI_ENTRY_CHECKED(ReturnType, \ 1363 checked_jni_GetStatic##Result##Field(JNIEnv *env, \ 1364 jclass clazz, \ 1365 jfieldID fieldID)) \ 1366 functionEnter(thr); \ 1367 IN_VM( \ 1368 jniCheck::validate_class(thr, clazz, false); \ 1369 checkStaticFieldID(thr, fieldID, clazz, FieldType); \ 1370 ) \ 1371 ReturnType result = UNCHECKED()->GetStatic##Result##Field(env, \ 1372 clazz, \ 1373 fieldID); \ 1374 functionExit(thr); \ 1375 return result; \ 1376 JNI_END 1377 1378 WRAPPER_GetStaticField(jobject, Object, T_OBJECT) 1379 WRAPPER_GetStaticField(jboolean, Boolean, T_BOOLEAN) 1380 WRAPPER_GetStaticField(jbyte, Byte, T_BYTE) 1381 WRAPPER_GetStaticField(jshort, Short, T_SHORT) 1382 WRAPPER_GetStaticField(jchar, Char, T_CHAR) 1383 WRAPPER_GetStaticField(jint, Int, T_INT) 1384 WRAPPER_GetStaticField(jlong, Long, T_LONG) 1385 WRAPPER_GetStaticField(jfloat, Float, T_FLOAT) 1386 WRAPPER_GetStaticField(jdouble, Double, T_DOUBLE) 1387 1388 #define WRAPPER_SetStaticField(ValueType,Result,FieldType) \ 1389 JNI_ENTRY_CHECKED(void, \ 1390 checked_jni_SetStatic##Result##Field(JNIEnv *env, \ 1391 jclass clazz, \ 1392 jfieldID fieldID, \ 1393 ValueType value)) \ 1394 functionEnter(thr); \ 1395 IN_VM( \ 1396 jniCheck::validate_class(thr, clazz, false); \ 1397 checkStaticFieldID(thr, fieldID, clazz, FieldType); \ 1398 ) \ 1399 UNCHECKED()->SetStatic##Result##Field(env,clazz,fieldID,value); \ 1400 functionExit(thr); \ 1401 JNI_END 1402 1403 WRAPPER_SetStaticField(jobject, Object, T_OBJECT) 1404 WRAPPER_SetStaticField(jboolean, Boolean, T_BOOLEAN) 1405 WRAPPER_SetStaticField(jbyte, Byte, T_BYTE) 1406 WRAPPER_SetStaticField(jshort, Short, T_SHORT) 1407 WRAPPER_SetStaticField(jchar, Char, T_CHAR) 1408 WRAPPER_SetStaticField(jint, Int, T_INT) 1409 WRAPPER_SetStaticField(jlong, Long, T_LONG) 1410 WRAPPER_SetStaticField(jfloat, Float, T_FLOAT) 1411 WRAPPER_SetStaticField(jdouble, Double, T_DOUBLE) 1412 1413 1414 JNI_ENTRY_CHECKED(jstring, 1415 checked_jni_NewString(JNIEnv *env, 1416 const jchar *unicode, 1417 jsize len)) 1418 functionEnter(thr); 1419 jstring result = UNCHECKED()->NewString(env,unicode,len); 1420 functionExit(thr); 1421 return result; 1422 JNI_END 1423 1424 JNI_ENTRY_CHECKED(jsize, 1425 checked_jni_GetStringLength(JNIEnv *env, 1426 jstring str)) 1427 functionEnter(thr); 1428 IN_VM( 1429 checkString(thr, str); 1430 ) 1431 jsize result = UNCHECKED()->GetStringLength(env,str); 1432 functionExit(thr); 1433 return result; 1434 JNI_END 1435 1436 // Arbitrary (but well-known) tag 1437 const void* STRING_TAG = (void*)0x47114711; 1438 1439 JNI_ENTRY_CHECKED(const jchar *, 1440 checked_jni_GetStringChars(JNIEnv *env, 1441 jstring str, 1442 jboolean *isCopy)) 1443 functionEnter(thr); 1444 IN_VM( 1445 checkString(thr, str); 1446 ) 1447 jchar* new_result = nullptr; 1448 const jchar *result = UNCHECKED()->GetStringChars(env,str,isCopy); 1449 assert (isCopy == nullptr || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected"); 1450 if (result != nullptr) { 1451 size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for null termination 1452 len *= sizeof(jchar); 1453 new_result = (jchar*) GuardedMemory::wrap_copy(result, len, STRING_TAG); 1454 if (new_result == nullptr) { 1455 vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringChars"); 1456 } 1457 // Avoiding call to UNCHECKED()->ReleaseStringChars() since that will fire unexpected dtrace probes 1458 // Note that the dtrace arguments for the allocated memory will not match up with this solution. 1459 FreeHeap((char*)result); 1460 } 1461 functionExit(thr); 1462 return new_result; 1463 JNI_END 1464 1465 JNI_ENTRY_CHECKED(void, 1466 checked_jni_ReleaseStringChars(JNIEnv *env, 1467 jstring str, 1468 const jchar *chars)) 1469 functionEnterExceptionAllowed(thr); 1470 IN_VM( 1471 checkString(thr, str); 1472 ) 1473 if (chars == nullptr) { 1474 // still do the unchecked call to allow dtrace probes 1475 UNCHECKED()->ReleaseStringChars(env,str,chars); 1476 } 1477 else { 1478 GuardedMemory guarded((void*)chars); 1479 if (!guarded.verify_guards()) { 1480 tty->print_cr("ReleaseStringChars: release chars failed bounds check. " 1481 "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars)); 1482 guarded.print_on(tty); 1483 NativeReportJNIFatalError(thr, "ReleaseStringChars: " 1484 "release chars failed bounds check."); 1485 } 1486 if (guarded.get_tag() != STRING_TAG) { 1487 tty->print_cr("ReleaseStringChars: called on something not allocated " 1488 "by GetStringChars. string: " PTR_FORMAT " chars: " PTR_FORMAT, 1489 p2i(str), p2i(chars)); 1490 NativeReportJNIFatalError(thr, "ReleaseStringChars called on something " 1491 "not allocated by GetStringChars"); 1492 } 1493 UNCHECKED()->ReleaseStringChars(env, str, 1494 (const jchar*) guarded.release_for_freeing()); 1495 } 1496 functionExit(thr); 1497 JNI_END 1498 1499 JNI_ENTRY_CHECKED(jstring, 1500 checked_jni_NewStringUTF(JNIEnv *env, 1501 const char *utf)) 1502 functionEnter(thr); 1503 jstring result = UNCHECKED()->NewStringUTF(env,utf); 1504 functionExit(thr); 1505 return result; 1506 JNI_END 1507 1508 JNI_ENTRY_CHECKED(jsize, 1509 checked_jni_GetStringUTFLength(JNIEnv *env, 1510 jstring str)) 1511 functionEnter(thr); 1512 IN_VM( 1513 checkString(thr, str); 1514 ) 1515 jsize result = UNCHECKED()->GetStringUTFLength(env,str); 1516 functionExit(thr); 1517 return result; 1518 JNI_END 1519 1520 // Arbitrary (but well-known) tag - different than GetStringChars 1521 const void* STRING_UTF_TAG = (void*) 0x48124812; 1522 1523 JNI_ENTRY_CHECKED(const char *, 1524 checked_jni_GetStringUTFChars(JNIEnv *env, 1525 jstring str, 1526 jboolean *isCopy)) 1527 functionEnter(thr); 1528 IN_VM( 1529 checkString(thr, str); 1530 ) 1531 char* new_result = nullptr; 1532 const char *result = UNCHECKED()->GetStringUTFChars(env,str,isCopy); 1533 assert (isCopy == nullptr || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected"); 1534 if (result != nullptr) { 1535 size_t len = strlen(result) + 1; // + 1 for null termination 1536 new_result = (char*) GuardedMemory::wrap_copy(result, len, STRING_UTF_TAG); 1537 if (new_result == nullptr) { 1538 vm_exit_out_of_memory(len, OOM_MALLOC_ERROR, "checked_jni_GetStringUTFChars"); 1539 } 1540 // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes 1541 // Note that the dtrace arguments for the allocated memory will not match up with this solution. 1542 FreeHeap((char*)result); 1543 } 1544 functionExit(thr); 1545 return new_result; 1546 JNI_END 1547 1548 JNI_ENTRY_CHECKED(void, 1549 checked_jni_ReleaseStringUTFChars(JNIEnv *env, 1550 jstring str, 1551 const char* chars)) 1552 functionEnterExceptionAllowed(thr); 1553 IN_VM( 1554 checkString(thr, str); 1555 ) 1556 if (chars == nullptr) { 1557 // still do the unchecked call to allow dtrace probes 1558 UNCHECKED()->ReleaseStringUTFChars(env,str,chars); 1559 } 1560 else { 1561 GuardedMemory guarded((void*)chars); 1562 if (!guarded.verify_guards()) { 1563 tty->print_cr("ReleaseStringUTFChars: release chars failed bounds check. " 1564 "string: " PTR_FORMAT " chars: " PTR_FORMAT, p2i(str), p2i(chars)); 1565 guarded.print_on(tty); 1566 NativeReportJNIFatalError(thr, "ReleaseStringUTFChars: " 1567 "release chars failed bounds check."); 1568 } 1569 if (guarded.get_tag() != STRING_UTF_TAG) { 1570 tty->print_cr("ReleaseStringUTFChars: called on something not " 1571 "allocated by GetStringUTFChars. string: " PTR_FORMAT " chars: " 1572 PTR_FORMAT, p2i(str), p2i(chars)); 1573 NativeReportJNIFatalError(thr, "ReleaseStringUTFChars " 1574 "called on something not allocated by GetStringUTFChars"); 1575 } 1576 UNCHECKED()->ReleaseStringUTFChars(env, str, 1577 (const char*) guarded.release_for_freeing()); 1578 } 1579 functionExit(thr); 1580 JNI_END 1581 1582 JNI_ENTRY_CHECKED(jsize, 1583 checked_jni_GetArrayLength(JNIEnv *env, 1584 jarray array)) 1585 functionEnter(thr); 1586 IN_VM( 1587 check_is_array(thr, array); 1588 ) 1589 jsize result = UNCHECKED()->GetArrayLength(env,array); 1590 functionExit(thr); 1591 return result; 1592 JNI_END 1593 1594 JNI_ENTRY_CHECKED(jobjectArray, 1595 checked_jni_NewObjectArray(JNIEnv *env, 1596 jsize len, 1597 jclass clazz, 1598 jobject init)) 1599 functionEnter(thr); 1600 jobjectArray result = UNCHECKED()->NewObjectArray(env,len,clazz,init); 1601 functionExit(thr); 1602 return result; 1603 JNI_END 1604 1605 JNI_ENTRY_CHECKED(jobject, 1606 checked_jni_GetObjectArrayElement(JNIEnv *env, 1607 jobjectArray array, 1608 jsize index)) 1609 functionEnter(thr); 1610 IN_VM( 1611 check_is_obj_or_inline_array(thr, array); 1612 ) 1613 jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); 1614 functionExit(thr); 1615 return result; 1616 JNI_END 1617 1618 JNI_ENTRY_CHECKED(void, 1619 checked_jni_SetObjectArrayElement(JNIEnv *env, 1620 jobjectArray array, 1621 jsize index, 1622 jobject val)) 1623 functionEnter(thr); 1624 IN_VM( 1625 check_is_obj_or_inline_array(thr, array); 1626 ) 1627 UNCHECKED()->SetObjectArrayElement(env,array,index,val); 1628 functionExit(thr); 1629 JNI_END 1630 1631 #define WRAPPER_NewScalarArray(Return, Result) \ 1632 JNI_ENTRY_CHECKED(Return, \ 1633 checked_jni_New##Result##Array(JNIEnv *env, \ 1634 jsize len)) \ 1635 functionEnter(thr); \ 1636 Return result = UNCHECKED()->New##Result##Array(env,len); \ 1637 functionExit(thr); \ 1638 return (Return) result; \ 1639 JNI_END 1640 1641 WRAPPER_NewScalarArray(jbooleanArray, Boolean) 1642 WRAPPER_NewScalarArray(jbyteArray, Byte) 1643 WRAPPER_NewScalarArray(jshortArray, Short) 1644 WRAPPER_NewScalarArray(jcharArray, Char) 1645 WRAPPER_NewScalarArray(jintArray, Int) 1646 WRAPPER_NewScalarArray(jlongArray, Long) 1647 WRAPPER_NewScalarArray(jfloatArray, Float) 1648 WRAPPER_NewScalarArray(jdoubleArray, Double) 1649 1650 #define WRAPPER_GetScalarArrayElements(ElementTag,ElementType,Result) \ 1651 JNI_ENTRY_CHECKED(ElementType *, \ 1652 checked_jni_Get##Result##ArrayElements(JNIEnv *env, \ 1653 ElementType##Array array, \ 1654 jboolean *isCopy)) \ 1655 functionEnter(thr); \ 1656 IN_VM( \ 1657 check_primitive_array_type(thr, array, ElementTag); \ 1658 ) \ 1659 ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \ 1660 array, \ 1661 isCopy); \ 1662 if (result != nullptr) { \ 1663 result = (ElementType *) check_jni_wrap_copy_array(thr, array, result); \ 1664 } \ 1665 functionExit(thr); \ 1666 return result; \ 1667 JNI_END 1668 1669 WRAPPER_GetScalarArrayElements(T_BOOLEAN, jboolean, Boolean) 1670 WRAPPER_GetScalarArrayElements(T_BYTE, jbyte, Byte) 1671 WRAPPER_GetScalarArrayElements(T_SHORT, jshort, Short) 1672 WRAPPER_GetScalarArrayElements(T_CHAR, jchar, Char) 1673 WRAPPER_GetScalarArrayElements(T_INT, jint, Int) 1674 WRAPPER_GetScalarArrayElements(T_LONG, jlong, Long) 1675 WRAPPER_GetScalarArrayElements(T_FLOAT, jfloat, Float) 1676 WRAPPER_GetScalarArrayElements(T_DOUBLE, jdouble, Double) 1677 1678 #define WRAPPER_ReleaseScalarArrayElements(ElementTag,ElementType,Result,Tag) \ 1679 JNI_ENTRY_CHECKED(void, \ 1680 checked_jni_Release##Result##ArrayElements(JNIEnv *env, \ 1681 ElementType##Array array, \ 1682 ElementType *elems, \ 1683 jint mode)) \ 1684 functionEnterExceptionAllowed(thr); \ 1685 IN_VM( \ 1686 check_primitive_array_type(thr, array, ElementTag); \ 1687 ASSERT_OOPS_ALLOWED; \ 1688 typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ 1689 ) \ 1690 ElementType* orig_result = (ElementType *) check_wrapped_array_release( \ 1691 thr, "checked_jni_Release"#Result"ArrayElements", array, elems, mode, JNI_FALSE); \ 1692 UNCHECKED()->Release##Result##ArrayElements(env, array, orig_result, mode); \ 1693 functionExit(thr); \ 1694 JNI_END 1695 1696 WRAPPER_ReleaseScalarArrayElements(T_BOOLEAN,jboolean, Boolean, bool) 1697 WRAPPER_ReleaseScalarArrayElements(T_BYTE, jbyte, Byte, byte) 1698 WRAPPER_ReleaseScalarArrayElements(T_SHORT, jshort, Short, short) 1699 WRAPPER_ReleaseScalarArrayElements(T_CHAR, jchar, Char, char) 1700 WRAPPER_ReleaseScalarArrayElements(T_INT, jint, Int, int) 1701 WRAPPER_ReleaseScalarArrayElements(T_LONG, jlong, Long, long) 1702 WRAPPER_ReleaseScalarArrayElements(T_FLOAT, jfloat, Float, float) 1703 WRAPPER_ReleaseScalarArrayElements(T_DOUBLE, jdouble, Double, double) 1704 1705 #define WRAPPER_GetScalarArrayRegion(ElementTag,ElementType,Result) \ 1706 JNI_ENTRY_CHECKED(void, \ 1707 checked_jni_Get##Result##ArrayRegion(JNIEnv *env, \ 1708 ElementType##Array array, \ 1709 jsize start, \ 1710 jsize len, \ 1711 ElementType *buf)) \ 1712 functionEnter(thr); \ 1713 IN_VM( \ 1714 check_primitive_array_type(thr, array, ElementTag); \ 1715 ) \ 1716 UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ 1717 functionExit(thr); \ 1718 JNI_END 1719 1720 WRAPPER_GetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) 1721 WRAPPER_GetScalarArrayRegion(T_BYTE, jbyte, Byte) 1722 WRAPPER_GetScalarArrayRegion(T_SHORT, jshort, Short) 1723 WRAPPER_GetScalarArrayRegion(T_CHAR, jchar, Char) 1724 WRAPPER_GetScalarArrayRegion(T_INT, jint, Int) 1725 WRAPPER_GetScalarArrayRegion(T_LONG, jlong, Long) 1726 WRAPPER_GetScalarArrayRegion(T_FLOAT, jfloat, Float) 1727 WRAPPER_GetScalarArrayRegion(T_DOUBLE, jdouble, Double) 1728 1729 #define WRAPPER_SetScalarArrayRegion(ElementTag,ElementType,Result) \ 1730 JNI_ENTRY_CHECKED(void, \ 1731 checked_jni_Set##Result##ArrayRegion(JNIEnv *env, \ 1732 ElementType##Array array, \ 1733 jsize start, \ 1734 jsize len, \ 1735 const ElementType *buf)) \ 1736 functionEnter(thr); \ 1737 IN_VM( \ 1738 check_primitive_array_type(thr, array, ElementTag); \ 1739 ) \ 1740 UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ 1741 functionExit(thr); \ 1742 JNI_END 1743 1744 WRAPPER_SetScalarArrayRegion(T_BOOLEAN, jboolean, Boolean) 1745 WRAPPER_SetScalarArrayRegion(T_BYTE, jbyte, Byte) 1746 WRAPPER_SetScalarArrayRegion(T_SHORT, jshort, Short) 1747 WRAPPER_SetScalarArrayRegion(T_CHAR, jchar, Char) 1748 WRAPPER_SetScalarArrayRegion(T_INT, jint, Int) 1749 WRAPPER_SetScalarArrayRegion(T_LONG, jlong, Long) 1750 WRAPPER_SetScalarArrayRegion(T_FLOAT, jfloat, Float) 1751 WRAPPER_SetScalarArrayRegion(T_DOUBLE, jdouble, Double) 1752 1753 JNI_ENTRY_CHECKED(jint, 1754 checked_jni_RegisterNatives(JNIEnv *env, 1755 jclass clazz, 1756 const JNINativeMethod *methods, 1757 jint nMethods)) 1758 functionEnter(thr); 1759 jint result = UNCHECKED()->RegisterNatives(env,clazz,methods,nMethods); 1760 functionExit(thr); 1761 return result; 1762 JNI_END 1763 1764 JNI_ENTRY_CHECKED(jint, 1765 checked_jni_UnregisterNatives(JNIEnv *env, 1766 jclass clazz)) 1767 functionEnter(thr); 1768 jint result = UNCHECKED()->UnregisterNatives(env,clazz); 1769 functionExit(thr); 1770 return result; 1771 JNI_END 1772 1773 JNI_ENTRY_CHECKED(jint, 1774 checked_jni_MonitorEnter(JNIEnv *env, 1775 jobject obj)) 1776 functionEnter(thr); 1777 IN_VM( 1778 jniCheck::validate_object(thr, obj); 1779 ) 1780 jint result = UNCHECKED()->MonitorEnter(env,obj); 1781 functionExit(thr); 1782 return result; 1783 JNI_END 1784 1785 JNI_ENTRY_CHECKED(jint, 1786 checked_jni_MonitorExit(JNIEnv *env, 1787 jobject obj)) 1788 functionEnterExceptionAllowed(thr); 1789 IN_VM( 1790 jniCheck::validate_object(thr, obj); 1791 ) 1792 jint result = UNCHECKED()->MonitorExit(env,obj); 1793 functionExit(thr); 1794 return result; 1795 JNI_END 1796 1797 JNI_ENTRY_CHECKED(jint, 1798 checked_jni_GetJavaVM(JNIEnv *env, 1799 JavaVM **vm)) 1800 functionEnter(thr); 1801 jint result = UNCHECKED()->GetJavaVM(env,vm); 1802 functionExit(thr); 1803 return result; 1804 JNI_END 1805 1806 JNI_ENTRY_CHECKED(void, 1807 checked_jni_GetStringRegion(JNIEnv *env, 1808 jstring str, 1809 jsize start, 1810 jsize len, 1811 jchar *buf)) 1812 functionEnter(thr); 1813 IN_VM( 1814 checkString(thr, str); 1815 ) 1816 UNCHECKED()->GetStringRegion(env, str, start, len, buf); 1817 functionExit(thr); 1818 JNI_END 1819 1820 JNI_ENTRY_CHECKED(void, 1821 checked_jni_GetStringUTFRegion(JNIEnv *env, 1822 jstring str, 1823 jsize start, 1824 jsize len, 1825 char *buf)) 1826 functionEnter(thr); 1827 IN_VM( 1828 checkString(thr, str); 1829 ) 1830 UNCHECKED()->GetStringUTFRegion(env, str, start, len, buf); 1831 functionExit(thr); 1832 JNI_END 1833 1834 JNI_ENTRY_CHECKED(void *, 1835 checked_jni_GetPrimitiveArrayCritical(JNIEnv *env, 1836 jarray array, 1837 jboolean *isCopy)) 1838 functionEnterCritical(thr); 1839 IN_VM( 1840 check_is_primitive_array(thr, array); 1841 ) 1842 void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy); 1843 if (result != nullptr) { 1844 result = check_jni_wrap_copy_array(thr, array, result); 1845 } 1846 functionExit(thr); 1847 return result; 1848 JNI_END 1849 1850 JNI_ENTRY_CHECKED(void, 1851 checked_jni_ReleasePrimitiveArrayCritical(JNIEnv *env, 1852 jarray array, 1853 void *carray, 1854 jint mode)) 1855 functionEnterCriticalExceptionAllowed(thr); 1856 IN_VM( 1857 check_is_primitive_array(thr, array); 1858 ) 1859 // Check the element array... 1860 void* orig_result = check_wrapped_array_release(thr, "ReleasePrimitiveArrayCritical", 1861 array, carray, mode, JNI_TRUE); 1862 UNCHECKED()->ReleasePrimitiveArrayCritical(env, array, orig_result, mode); 1863 functionExit(thr); 1864 JNI_END 1865 1866 JNI_ENTRY_CHECKED(const jchar*, 1867 checked_jni_GetStringCritical(JNIEnv *env, 1868 jstring string, 1869 jboolean *isCopy)) 1870 functionEnterCritical(thr); 1871 IN_VM( 1872 checkString(thr, string); 1873 ) 1874 const jchar *result = UNCHECKED()->GetStringCritical(env, string, isCopy); 1875 functionExit(thr); 1876 return result; 1877 JNI_END 1878 1879 JNI_ENTRY_CHECKED(void, 1880 checked_jni_ReleaseStringCritical(JNIEnv *env, 1881 jstring str, 1882 const jchar *chars)) 1883 functionEnterCriticalExceptionAllowed(thr); 1884 IN_VM( 1885 checkString(thr, str); 1886 ) 1887 /* The Hotspot JNI code does not use the parameters, so just check the 1888 * string parameter as a minor sanity check 1889 */ 1890 UNCHECKED()->ReleaseStringCritical(env, str, chars); 1891 functionExit(thr); 1892 JNI_END 1893 1894 JNI_ENTRY_CHECKED(jweak, 1895 checked_jni_NewWeakGlobalRef(JNIEnv *env, 1896 jobject obj)) 1897 functionEnter(thr); 1898 IN_VM( 1899 if (obj != nullptr) { 1900 jniCheck::validate_handle(thr, obj); 1901 } 1902 ) 1903 jweak result = UNCHECKED()->NewWeakGlobalRef(env, obj); 1904 functionExit(thr); 1905 return result; 1906 JNI_END 1907 1908 JNI_ENTRY_CHECKED(void, 1909 checked_jni_DeleteWeakGlobalRef(JNIEnv *env, 1910 jweak ref)) 1911 functionEnterExceptionAllowed(thr); 1912 IN_VM( 1913 if (ref && !JNIHandles::is_weak_global_handle(ref)) { 1914 ReportJNIFatalError(thr, 1915 "Invalid weak global JNI handle passed to DeleteWeakGlobalRef"); 1916 } 1917 ) 1918 UNCHECKED()->DeleteWeakGlobalRef(env, ref); 1919 functionExit(thr); 1920 JNI_END 1921 1922 JNI_ENTRY_CHECKED(jboolean, 1923 checked_jni_ExceptionCheck(JNIEnv *env)) 1924 thr->clear_pending_jni_exception_check(); 1925 functionEnterExceptionAllowed(thr); 1926 jboolean result = UNCHECKED()->ExceptionCheck(env); 1927 functionExit(thr); 1928 return result; 1929 JNI_END 1930 1931 JNI_ENTRY_CHECKED(jobject, 1932 checked_jni_NewDirectByteBuffer(JNIEnv *env, 1933 void *address, 1934 jlong capacity)) 1935 functionEnter(thr); 1936 jobject result = UNCHECKED()->NewDirectByteBuffer(env, address, capacity); 1937 functionExit(thr); 1938 return result; 1939 JNI_END 1940 1941 JNI_ENTRY_CHECKED(void *, 1942 checked_jni_GetDirectBufferAddress(JNIEnv *env, 1943 jobject buf)) 1944 functionEnter(thr); 1945 void* result = UNCHECKED()->GetDirectBufferAddress(env, buf); 1946 functionExit(thr); 1947 return result; 1948 JNI_END 1949 1950 JNI_ENTRY_CHECKED(jlong, 1951 checked_jni_GetDirectBufferCapacity(JNIEnv *env, 1952 jobject buf)) 1953 functionEnter(thr); 1954 jlong result = UNCHECKED()->GetDirectBufferCapacity(env, buf); 1955 functionExit(thr); 1956 return result; 1957 JNI_END 1958 1959 JNI_ENTRY_CHECKED(jobjectRefType, 1960 checked_jni_GetObjectRefType(JNIEnv *env, 1961 jobject obj)) 1962 functionEnter(thr); 1963 /* validate the object being passed */ 1964 IN_VM( 1965 jniCheck::validate_object(thr, obj); 1966 ) 1967 jobjectRefType result = UNCHECKED()->GetObjectRefType(env, obj); 1968 functionExit(thr); 1969 return result; 1970 JNI_END 1971 1972 1973 JNI_ENTRY_CHECKED(jint, 1974 checked_jni_GetVersion(JNIEnv *env)) 1975 functionEnter(thr); 1976 jint result = UNCHECKED()->GetVersion(env); 1977 functionExit(thr); 1978 return result; 1979 JNI_END 1980 1981 JNI_ENTRY_CHECKED(jobject, 1982 checked_jni_GetModule(JNIEnv *env, 1983 jclass clazz)) 1984 functionEnter(thr); 1985 jobject result = UNCHECKED()->GetModule(env, clazz); 1986 functionExit(thr); 1987 return result; 1988 JNI_END 1989 1990 JNI_ENTRY_CHECKED(jboolean, 1991 checked_jni_IsVirtualThread(JNIEnv *env, 1992 jobject obj)) 1993 functionEnter(thr); 1994 jboolean result = UNCHECKED()->IsVirtualThread(env, obj); 1995 functionExit(thr); 1996 return result; 1997 JNI_END 1998 1999 /* 2000 * Structure containing all checked jni functions 2001 */ 2002 struct JNINativeInterface_ checked_jni_NativeInterface = { 2003 nullptr, 2004 nullptr, 2005 nullptr, 2006 2007 nullptr, 2008 2009 checked_jni_GetVersion, 2010 2011 checked_jni_DefineClass, 2012 checked_jni_FindClass, 2013 2014 checked_jni_FromReflectedMethod, 2015 checked_jni_FromReflectedField, 2016 2017 checked_jni_ToReflectedMethod, 2018 2019 checked_jni_GetSuperclass, 2020 checked_jni_IsAssignableFrom, 2021 2022 checked_jni_ToReflectedField, 2023 2024 checked_jni_Throw, 2025 checked_jni_ThrowNew, 2026 checked_jni_ExceptionOccurred, 2027 checked_jni_ExceptionDescribe, 2028 checked_jni_ExceptionClear, 2029 checked_jni_FatalError, 2030 2031 checked_jni_PushLocalFrame, 2032 checked_jni_PopLocalFrame, 2033 2034 checked_jni_NewGlobalRef, 2035 checked_jni_DeleteGlobalRef, 2036 checked_jni_DeleteLocalRef, 2037 checked_jni_IsSameObject, 2038 2039 checked_jni_NewLocalRef, 2040 checked_jni_EnsureLocalCapacity, 2041 2042 checked_jni_AllocObject, 2043 checked_jni_NewObject, 2044 checked_jni_NewObjectV, 2045 checked_jni_NewObjectA, 2046 2047 checked_jni_GetObjectClass, 2048 checked_jni_IsInstanceOf, 2049 2050 checked_jni_GetMethodID, 2051 2052 checked_jni_CallObjectMethod, 2053 checked_jni_CallObjectMethodV, 2054 checked_jni_CallObjectMethodA, 2055 checked_jni_CallBooleanMethod, 2056 checked_jni_CallBooleanMethodV, 2057 checked_jni_CallBooleanMethodA, 2058 checked_jni_CallByteMethod, 2059 checked_jni_CallByteMethodV, 2060 checked_jni_CallByteMethodA, 2061 checked_jni_CallCharMethod, 2062 checked_jni_CallCharMethodV, 2063 checked_jni_CallCharMethodA, 2064 checked_jni_CallShortMethod, 2065 checked_jni_CallShortMethodV, 2066 checked_jni_CallShortMethodA, 2067 checked_jni_CallIntMethod, 2068 checked_jni_CallIntMethodV, 2069 checked_jni_CallIntMethodA, 2070 checked_jni_CallLongMethod, 2071 checked_jni_CallLongMethodV, 2072 checked_jni_CallLongMethodA, 2073 checked_jni_CallFloatMethod, 2074 checked_jni_CallFloatMethodV, 2075 checked_jni_CallFloatMethodA, 2076 checked_jni_CallDoubleMethod, 2077 checked_jni_CallDoubleMethodV, 2078 checked_jni_CallDoubleMethodA, 2079 checked_jni_CallVoidMethod, 2080 checked_jni_CallVoidMethodV, 2081 checked_jni_CallVoidMethodA, 2082 2083 checked_jni_CallNonvirtualObjectMethod, 2084 checked_jni_CallNonvirtualObjectMethodV, 2085 checked_jni_CallNonvirtualObjectMethodA, 2086 checked_jni_CallNonvirtualBooleanMethod, 2087 checked_jni_CallNonvirtualBooleanMethodV, 2088 checked_jni_CallNonvirtualBooleanMethodA, 2089 checked_jni_CallNonvirtualByteMethod, 2090 checked_jni_CallNonvirtualByteMethodV, 2091 checked_jni_CallNonvirtualByteMethodA, 2092 checked_jni_CallNonvirtualCharMethod, 2093 checked_jni_CallNonvirtualCharMethodV, 2094 checked_jni_CallNonvirtualCharMethodA, 2095 checked_jni_CallNonvirtualShortMethod, 2096 checked_jni_CallNonvirtualShortMethodV, 2097 checked_jni_CallNonvirtualShortMethodA, 2098 checked_jni_CallNonvirtualIntMethod, 2099 checked_jni_CallNonvirtualIntMethodV, 2100 checked_jni_CallNonvirtualIntMethodA, 2101 checked_jni_CallNonvirtualLongMethod, 2102 checked_jni_CallNonvirtualLongMethodV, 2103 checked_jni_CallNonvirtualLongMethodA, 2104 checked_jni_CallNonvirtualFloatMethod, 2105 checked_jni_CallNonvirtualFloatMethodV, 2106 checked_jni_CallNonvirtualFloatMethodA, 2107 checked_jni_CallNonvirtualDoubleMethod, 2108 checked_jni_CallNonvirtualDoubleMethodV, 2109 checked_jni_CallNonvirtualDoubleMethodA, 2110 checked_jni_CallNonvirtualVoidMethod, 2111 checked_jni_CallNonvirtualVoidMethodV, 2112 checked_jni_CallNonvirtualVoidMethodA, 2113 2114 checked_jni_GetFieldID, 2115 2116 checked_jni_GetObjectField, 2117 checked_jni_GetBooleanField, 2118 checked_jni_GetByteField, 2119 checked_jni_GetCharField, 2120 checked_jni_GetShortField, 2121 checked_jni_GetIntField, 2122 checked_jni_GetLongField, 2123 checked_jni_GetFloatField, 2124 checked_jni_GetDoubleField, 2125 2126 checked_jni_SetObjectField, 2127 checked_jni_SetBooleanField, 2128 checked_jni_SetByteField, 2129 checked_jni_SetCharField, 2130 checked_jni_SetShortField, 2131 checked_jni_SetIntField, 2132 checked_jni_SetLongField, 2133 checked_jni_SetFloatField, 2134 checked_jni_SetDoubleField, 2135 2136 checked_jni_GetStaticMethodID, 2137 2138 checked_jni_CallStaticObjectMethod, 2139 checked_jni_CallStaticObjectMethodV, 2140 checked_jni_CallStaticObjectMethodA, 2141 checked_jni_CallStaticBooleanMethod, 2142 checked_jni_CallStaticBooleanMethodV, 2143 checked_jni_CallStaticBooleanMethodA, 2144 checked_jni_CallStaticByteMethod, 2145 checked_jni_CallStaticByteMethodV, 2146 checked_jni_CallStaticByteMethodA, 2147 checked_jni_CallStaticCharMethod, 2148 checked_jni_CallStaticCharMethodV, 2149 checked_jni_CallStaticCharMethodA, 2150 checked_jni_CallStaticShortMethod, 2151 checked_jni_CallStaticShortMethodV, 2152 checked_jni_CallStaticShortMethodA, 2153 checked_jni_CallStaticIntMethod, 2154 checked_jni_CallStaticIntMethodV, 2155 checked_jni_CallStaticIntMethodA, 2156 checked_jni_CallStaticLongMethod, 2157 checked_jni_CallStaticLongMethodV, 2158 checked_jni_CallStaticLongMethodA, 2159 checked_jni_CallStaticFloatMethod, 2160 checked_jni_CallStaticFloatMethodV, 2161 checked_jni_CallStaticFloatMethodA, 2162 checked_jni_CallStaticDoubleMethod, 2163 checked_jni_CallStaticDoubleMethodV, 2164 checked_jni_CallStaticDoubleMethodA, 2165 checked_jni_CallStaticVoidMethod, 2166 checked_jni_CallStaticVoidMethodV, 2167 checked_jni_CallStaticVoidMethodA, 2168 2169 checked_jni_GetStaticFieldID, 2170 2171 checked_jni_GetStaticObjectField, 2172 checked_jni_GetStaticBooleanField, 2173 checked_jni_GetStaticByteField, 2174 checked_jni_GetStaticCharField, 2175 checked_jni_GetStaticShortField, 2176 checked_jni_GetStaticIntField, 2177 checked_jni_GetStaticLongField, 2178 checked_jni_GetStaticFloatField, 2179 checked_jni_GetStaticDoubleField, 2180 2181 checked_jni_SetStaticObjectField, 2182 checked_jni_SetStaticBooleanField, 2183 checked_jni_SetStaticByteField, 2184 checked_jni_SetStaticCharField, 2185 checked_jni_SetStaticShortField, 2186 checked_jni_SetStaticIntField, 2187 checked_jni_SetStaticLongField, 2188 checked_jni_SetStaticFloatField, 2189 checked_jni_SetStaticDoubleField, 2190 2191 checked_jni_NewString, 2192 checked_jni_GetStringLength, 2193 checked_jni_GetStringChars, 2194 checked_jni_ReleaseStringChars, 2195 2196 checked_jni_NewStringUTF, 2197 checked_jni_GetStringUTFLength, 2198 checked_jni_GetStringUTFChars, 2199 checked_jni_ReleaseStringUTFChars, 2200 2201 checked_jni_GetArrayLength, 2202 2203 checked_jni_NewObjectArray, 2204 checked_jni_GetObjectArrayElement, 2205 checked_jni_SetObjectArrayElement, 2206 2207 checked_jni_NewBooleanArray, 2208 checked_jni_NewByteArray, 2209 checked_jni_NewCharArray, 2210 checked_jni_NewShortArray, 2211 checked_jni_NewIntArray, 2212 checked_jni_NewLongArray, 2213 checked_jni_NewFloatArray, 2214 checked_jni_NewDoubleArray, 2215 2216 checked_jni_GetBooleanArrayElements, 2217 checked_jni_GetByteArrayElements, 2218 checked_jni_GetCharArrayElements, 2219 checked_jni_GetShortArrayElements, 2220 checked_jni_GetIntArrayElements, 2221 checked_jni_GetLongArrayElements, 2222 checked_jni_GetFloatArrayElements, 2223 checked_jni_GetDoubleArrayElements, 2224 2225 checked_jni_ReleaseBooleanArrayElements, 2226 checked_jni_ReleaseByteArrayElements, 2227 checked_jni_ReleaseCharArrayElements, 2228 checked_jni_ReleaseShortArrayElements, 2229 checked_jni_ReleaseIntArrayElements, 2230 checked_jni_ReleaseLongArrayElements, 2231 checked_jni_ReleaseFloatArrayElements, 2232 checked_jni_ReleaseDoubleArrayElements, 2233 2234 checked_jni_GetBooleanArrayRegion, 2235 checked_jni_GetByteArrayRegion, 2236 checked_jni_GetCharArrayRegion, 2237 checked_jni_GetShortArrayRegion, 2238 checked_jni_GetIntArrayRegion, 2239 checked_jni_GetLongArrayRegion, 2240 checked_jni_GetFloatArrayRegion, 2241 checked_jni_GetDoubleArrayRegion, 2242 2243 checked_jni_SetBooleanArrayRegion, 2244 checked_jni_SetByteArrayRegion, 2245 checked_jni_SetCharArrayRegion, 2246 checked_jni_SetShortArrayRegion, 2247 checked_jni_SetIntArrayRegion, 2248 checked_jni_SetLongArrayRegion, 2249 checked_jni_SetFloatArrayRegion, 2250 checked_jni_SetDoubleArrayRegion, 2251 2252 checked_jni_RegisterNatives, 2253 checked_jni_UnregisterNatives, 2254 2255 checked_jni_MonitorEnter, 2256 checked_jni_MonitorExit, 2257 2258 checked_jni_GetJavaVM, 2259 2260 checked_jni_GetStringRegion, 2261 checked_jni_GetStringUTFRegion, 2262 2263 checked_jni_GetPrimitiveArrayCritical, 2264 checked_jni_ReleasePrimitiveArrayCritical, 2265 2266 checked_jni_GetStringCritical, 2267 checked_jni_ReleaseStringCritical, 2268 2269 checked_jni_NewWeakGlobalRef, 2270 checked_jni_DeleteWeakGlobalRef, 2271 2272 checked_jni_ExceptionCheck, 2273 2274 checked_jni_NewDirectByteBuffer, 2275 checked_jni_GetDirectBufferAddress, 2276 checked_jni_GetDirectBufferCapacity, 2277 2278 // New 1.6 Features 2279 2280 checked_jni_GetObjectRefType, 2281 2282 // Module Features 2283 2284 checked_jni_GetModule, 2285 2286 // Virtual threads 2287 2288 checked_jni_IsVirtualThread 2289 }; 2290 2291 2292 // Returns the function structure 2293 struct JNINativeInterface_* jni_functions_check() { 2294 2295 unchecked_jni_NativeInterface = jni_functions_nocheck(); 2296 2297 // make sure the last pointer in the checked table is not null, indicating 2298 // an addition to the JNINativeInterface_ structure without initializing 2299 // it in the checked table. 2300 debug_only(int *lastPtr = (int *)((char *)&checked_jni_NativeInterface + \ 2301 sizeof(*unchecked_jni_NativeInterface) - sizeof(char *));) 2302 assert(*lastPtr != 0, 2303 "Mismatched JNINativeInterface tables, check for new entries"); 2304 2305 // with -verbose:jni this message will print 2306 log_debug(jni, resolve)("Checked JNI functions are being used to validate JNI usage"); 2307 2308 return &checked_jni_NativeInterface; 2309 }