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