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