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