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