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