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