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