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