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