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