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