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