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