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