src/share/vm/prims/jni.cpp
author acorn
Fri Sep 04 12:53:02 2009 -0400 (2 months ago)
changeset 973 ad6585fd4087
parent 657715dceaa89b7
permissions -rw-r--r--
6830542: Performance: JVM_DefineClass already verified.
Reviewed-by: kamg, phh
        1 /*
        2  * Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
        3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        4  *
        5  * This code is free software; you can redistribute it and/or modify it
        6  * under the terms of the GNU General Public License version 2 only, as
        7  * published by the Free Software Foundation.
        8  *
        9  * This code is distributed in the hope that it will be useful, but WITHOUT
       10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       12  * version 2 for more details (a copy is included in the LICENSE file that
       13  * accompanied this code).
       14  *
       15  * You should have received a copy of the GNU General Public License version
       16  * 2 along with this work; if not, write to the Free Software Foundation,
       17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       18  *
       19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       20  * CA 95054 USA or visit www.sun.com if you need additional information or
       21  * have any questions.
       22  *
       23  */
       24 
       25 # include "incls/_precompiled.incl"
       26 # include "incls/_jni.cpp.incl"
       27 
       28 static jint CurrentVersion = JNI_VERSION_1_6;
       29 
       30 
       31 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
       32 // '-return' probe regardless of the return path is taken out of the function.
       33 // Methods that have multiple return paths use this to avoid having to
       34 // instrument each return path.  Methods that use CHECK or THROW must use this
       35 // since those macros can cause an immedate uninstrumented return.
       36 //
       37 // In order to get the return value, a reference to the variable containing
       38 // the return value must be passed to the contructor of the object, and
       39 // the return value must be set before return (since the mark object has
       40 // a reference to it).
       41 //
       42 // Example:
       43 // DT_RETURN_MARK_DECL(SomeFunc, int);
       44 // JNI_ENTRY(int, SomeFunc, ...)
       45 //   int return_value = 0;
       46 //   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
       47 //   foo(CHECK_0)
       48 //   return_value = 5;
       49 //   return return_value;
       50 // JNI_END
       51 #define DT_RETURN_MARK_DECL(name, type)                                    \
       52   HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type);                \
       53   DTRACE_ONLY(                                                             \
       54     class DTraceReturnProbeMark_##name {                                   \
       55      public:                                                               \
       56       const type& _ret_ref;                                                \
       57       DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
       58       ~DTraceReturnProbeMark_##name() {                                    \
       59         HS_DTRACE_PROBE1(hotspot_jni, name##__return, _ret_ref);           \
       60       }                                                                    \
       61     }                                                                      \
       62   )
       63 // Void functions are simpler since there's no return value
       64 #define DT_VOID_RETURN_MARK_DECL(name)                                     \
       65   HS_DTRACE_PROBE_DECL0(hotspot_jni, name##__return);                      \
       66   DTRACE_ONLY(                                                             \
       67     class DTraceReturnProbeMark_##name {                                   \
       68      public:                                                               \
       69       ~DTraceReturnProbeMark_##name() {                                    \
       70         HS_DTRACE_PROBE0(hotspot_jni, name##__return);                     \
       71       }                                                                    \
       72     }                                                                      \
       73   )
       74 
       75 
       76 // Place these macros in the function to mark the return.  Non-void
       77 // functions need the type and address of the return value.
       78 #define DT_RETURN_MARK(name, type, ref) \
       79   DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )
       80 #define DT_VOID_RETURN_MARK(name) \
       81   DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )
       82 
       83 
       84 // Use these to select distinct code for floating-point vs. non-floating point
       85 // situations.  Used from within common macros where we need slightly
       86 // different behavior for Float/Double
       87 #define FP_SELECT_Boolean(intcode, fpcode) intcode
       88 #define FP_SELECT_Byte(intcode, fpcode)    intcode
       89 #define FP_SELECT_Char(intcode, fpcode)    intcode
       90 #define FP_SELECT_Short(intcode, fpcode)   intcode
       91 #define FP_SELECT_Object(intcode, fpcode)  intcode
       92 #define FP_SELECT_Int(intcode, fpcode)     intcode
       93 #define FP_SELECT_Long(intcode, fpcode)    intcode
       94 #define FP_SELECT_Float(intcode, fpcode)   fpcode
       95 #define FP_SELECT_Double(intcode, fpcode)  fpcode
       96 #define FP_SELECT(TypeName, intcode, fpcode) \
       97   FP_SELECT_##TypeName(intcode, fpcode)
       98 
       99 #define COMMA ,
      100 
      101 // Choose DT_RETURN_MARK macros  based on the type: float/double -> void
      102 // (dtrace doesn't do FP yet)
      103 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \
      104   FP_SELECT(TypeName, \
      105     DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) )
      106 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
      107   FP_SELECT(TypeName, \
      108     DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
      109 
      110 
      111 // out-of-line helpers for class jfieldIDWorkaround:
      112 
      113 bool jfieldIDWorkaround::is_valid_jfieldID(klassOop k, jfieldID id) {
      114   if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
      115     uintptr_t as_uint = (uintptr_t) id;
      116     intptr_t offset = raw_instance_offset(id);
      117     if (is_checked_jfieldID(id)) {
      118       if (!klass_hash_ok(k, id)) {
      119         return false;
      120       }
      121     }
      122     return instanceKlass::cast(k)->contains_field_offset(offset);
      123   } else {
      124     JNIid* result = (JNIid*) id;
      125 #ifdef ASSERT
      126     return result != NULL && result->is_static_field_id();
      127 #else
      128     return result != NULL;
      129 #endif
      130   }
      131 }
      132 
      133 
      134 intptr_t jfieldIDWorkaround::encode_klass_hash(klassOop k, intptr_t offset) {
      135   if (offset <= small_offset_mask) {
      136     klassOop field_klass = k;
      137     klassOop super_klass = Klass::cast(field_klass)->super();
      138     // With compressed oops the most super class with nonstatic fields would
      139     // be the owner of fields embedded in the header.
      140     while (instanceKlass::cast(super_klass)->has_nonstatic_fields() &&
      141            instanceKlass::cast(super_klass)->contains_field_offset(offset)) {
      142       field_klass = super_klass;   // super contains the field also
      143       super_klass = Klass::cast(field_klass)->super();
      144     }
      145     debug_only(No_Safepoint_Verifier nosafepoint;)
      146     uintptr_t klass_hash = field_klass->identity_hash();
      147     return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
      148   } else {
      149 #if 0
      150     #ifndef PRODUCT
      151     {
      152       ResourceMark rm;
      153       warning("VerifyJNIFields: long offset %d in %s", offset, Klass::cast(k)->external_name());
      154     }
      155     #endif
      156 #endif
      157     return 0;
      158   }
      159 }
      160 
      161 bool jfieldIDWorkaround::klass_hash_ok(klassOop k, jfieldID id) {
      162   uintptr_t as_uint = (uintptr_t) id;
      163   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
      164   do {
      165     debug_only(No_Safepoint_Verifier nosafepoint;)
      166     // Could use a non-blocking query for identity_hash here...
      167     if ((k->identity_hash() & klass_mask) == klass_hash)
      168       return true;
      169     k = Klass::cast(k)->super();
      170   } while (k != NULL);
      171   return false;
      172 }
      173 
      174 void jfieldIDWorkaround::verify_instance_jfieldID(klassOop k, jfieldID id) {
      175   guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
      176   uintptr_t as_uint = (uintptr_t) id;
      177   intptr_t offset = raw_instance_offset(id);
      178   if (VerifyJNIFields) {
      179     if (is_checked_jfieldID(id)) {
      180       guarantee(klass_hash_ok(k, id),
      181     "Bug in native code: jfieldID class must match object");
      182     } else {
      183 #if 0
      184       #ifndef PRODUCT
      185       if (Verbose) {
      186   ResourceMark rm;
      187   warning("VerifyJNIFields: unverified offset %d for %s", offset, Klass::cast(k)->external_name());
      188       }
      189       #endif
      190 #endif
      191     }
      192   }
      193   guarantee(instanceKlass::cast(k)->contains_field_offset(offset),
      194       "Bug in native code: jfieldID offset must address interior of object");
      195 }
      196 
      197 // Pick a reasonable higher bound for local capacity requested
      198 // for EnsureLocalCapacity and PushLocalFrame.  We don't want it too
      199 // high because a test (or very unusual application) may try to allocate
      200 // that many handles and run out of swap space.  An implementation is
      201 // permitted to allocate more handles than the ensured capacity, so this
      202 // value is set high enough to prevent compatibility problems.
      203 const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K;
      204 
      205 
      206 // Wrapper to trace JNI functions
      207 
      208 #ifdef ASSERT
      209   Histogram* JNIHistogram;
      210   static volatile jint JNIHistogram_lock = 0;
      211 
      212   class JNITraceWrapper : public StackObj {
      213    public:
      214     JNITraceWrapper(const char* format, ...) {
      215       if (TraceJNICalls) {
      216         va_list ap;
      217         va_start(ap, format);
      218         tty->print("JNI ");
      219         tty->vprint_cr(format, ap);
      220         va_end(ap);
      221       }
      222     }
      223   };
      224 
      225   class JNIHistogramElement : public HistogramElement {
      226     public:
      227      JNIHistogramElement(const char* name);
      228   };
      229 
      230   JNIHistogramElement::JNIHistogramElement(const char* elementName) {
      231     _name = elementName;
      232     uintx count = 0;
      233 
      234     while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) {
      235       while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) {
      236         count +=1;
      237         if ( (WarnOnStalledSpinLock > 0)
      238           && (count % WarnOnStalledSpinLock == 0)) {
      239           warning("JNIHistogram_lock seems to be stalled");
      240         }
      241       }
      242      }
      243 
      244 
      245     if(JNIHistogram == NULL)
      246       JNIHistogram = new Histogram("JNI Call Counts",100);
      247 
      248     JNIHistogram->add_element(this);
      249     Atomic::dec(&JNIHistogram_lock);
      250   }
      251 
      252   #define JNICountWrapper(arg)                                     \
      253      static JNIHistogramElement* e = new JNIHistogramElement(arg); \
      254       /* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \
      255      if (e != NULL) e->increment_count()
      256   #define JNIWrapper(arg) JNICountWrapper(arg); JNITraceWrapper(arg)
      257 #else
      258   #define JNIWrapper(arg)
      259 #endif
      260 
      261 
      262 // Implementation of JNI entries
      263 
      264 DT_RETURN_MARK_DECL(DefineClass, jclass);
      265 
      266 JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,
      267                                   const jbyte *buf, jsize bufLen))
      268   JNIWrapper("DefineClass");
      269 
      270   DTRACE_PROBE5(hotspot_jni, DefineClass__entry,
      271     env, name, loaderRef, buf, bufLen);
      272   jclass cls = NULL;
      273   DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
      274 
      275   // Since exceptions can be thrown, class initialization can take place
      276   // if name is NULL no check for class name in .class stream has to be made.
      277   symbolHandle class_name;
      278   if (name != NULL) {
      279     const int str_len = (int)strlen(name);
      280     if (str_len > symbolOopDesc::max_length()) {
      281       // It's impossible to create this class;  the name cannot fit
      282       // into the constant pool.
      283       THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
      284     }
      285     class_name = oopFactory::new_symbol_handle(name, str_len, CHECK_NULL);
      286   }
      287 
      288   ResourceMark rm(THREAD);
      289   ClassFileStream st((u1*) buf, bufLen, NULL);
      290   Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
      291 
      292   if (UsePerfData && !class_loader.is_null()) {
      293     // check whether the current caller thread holds the lock or not.
      294     // If not, increment the corresponding counter
      295     if (ObjectSynchronizer::
      296         query_lock_ownership((JavaThread*)THREAD, class_loader) !=
      297         ObjectSynchronizer::owner_self) {
      298       ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
      299     }
      300   }
      301   klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
      302                                                      Handle(), &st, true,
      303                                                      CHECK_NULL);
      304 
      305   if (TraceClassResolution && k != NULL) {
      306     trace_class_resolution(k);
      307   }
      308 
      309   cls = (jclass)JNIHandles::make_local(
      310     env, Klass::cast(k)->java_mirror());
      311   return cls;
      312 JNI_END
      313 
      314 
      315 
      316 static bool first_time_FindClass = true;
      317 
      318 DT_RETURN_MARK_DECL(FindClass, jclass);
      319 
      320 JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
      321   JNIWrapper("FindClass");
      322   DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);
      323 
      324   jclass result = NULL;
      325   DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
      326 
      327   // Remember if we are the first invocation of jni_FindClass
      328   bool first_time = first_time_FindClass;
      329   first_time_FindClass = false;
      330 
      331   // Sanity check the name:  it cannot be null or larger than the maximum size
      332   // name we can fit in the constant pool.
      333   if (name == NULL || (int)strlen(name) > symbolOopDesc::max_length()) {
      334     THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
      335   }
      336 
      337   //%note jni_3
      338   Handle loader;
      339   Handle protection_domain;
      340   // Find calling class
      341   instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));
      342   if (k.not_null()) {
      343     loader = Handle(THREAD, k->class_loader());
      344     // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
      345     // in the correct class context.
      346     if (loader.is_null() &&
      347         k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
      348       JavaValue result(T_OBJECT);
      349       JavaCalls::call_static(&result, k,
      350                                       vmSymbolHandles::getFromClass_name(),
      351                                       vmSymbolHandles::void_class_signature(),
      352                                       thread);
      353       if (HAS_PENDING_EXCEPTION) {
      354         Handle ex(thread, thread->pending_exception());
      355         CLEAR_PENDING_EXCEPTION;
      356         THROW_HANDLE_0(ex);
      357       }
      358       oop mirror = (oop) result.get_jobject();
      359       loader = Handle(THREAD,
      360         instanceKlass::cast(java_lang_Class::as_klassOop(mirror))->class_loader());
      361       protection_domain = Handle(THREAD,
      362         instanceKlass::cast(java_lang_Class::as_klassOop(mirror))->protection_domain());
      363     }
      364   } else {
      365     // We call ClassLoader.getSystemClassLoader to obtain the system class loader.
      366     loader = Handle(THREAD, SystemDictionary::java_system_loader());
      367   }
      368 
      369   symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL);
      370   result = find_class_from_class_loader(env, sym, true, loader,
      371                                         protection_domain, true, thread);
      372 
      373   if (TraceClassResolution && result != NULL) {
      374     trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
      375   }
      376 
      377   // If we were the first invocation of jni_FindClass, we enable compilation again
      378   // rather than just allowing invocation counter to overflow and decay.
      379   // Controlled by flag DelayCompilationDuringStartup.
      380   if (first_time && !CompileTheWorld)
      381     CompilationPolicy::completed_vm_startup();
      382 
      383   return result;
      384 JNI_END
      385 
      386 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);
      387 
      388 JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
      389   JNIWrapper("FromReflectedMethod");
      390   DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method);
      391   jmethodID ret = NULL;
      392   DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
      393 
      394   // method is a handle to a java.lang.reflect.Method object
      395   oop reflected  = JNIHandles::resolve_non_null(method);
      396   oop mirror     = NULL;
      397   int slot       = 0;
      398 
      399   if (reflected->klass() == SystemDictionary::reflect_constructor_klass()) {
      400     mirror = java_lang_reflect_Constructor::clazz(reflected);
      401     slot   = java_lang_reflect_Constructor::slot(reflected);
      402   } else {
      403     assert(reflected->klass() == SystemDictionary::reflect_method_klass(), "wrong type");
      404     mirror = java_lang_reflect_Method::clazz(reflected);
      405     slot   = java_lang_reflect_Method::slot(reflected);
      406   }
      407   klassOop k     = java_lang_Class::as_klassOop(mirror);
      408 
      409   KlassHandle k1(THREAD, k);
      410   // Make sure class is initialized before handing id's out to methods
      411   Klass::cast(k1())->initialize(CHECK_NULL);
      412   methodOop m = instanceKlass::cast(k1())->method_with_idnum(slot);
      413   ret = m==NULL? NULL : m->jmethod_id();  // return NULL if reflected method deleted
      414   return ret;
      415 JNI_END
      416 
      417 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);
      418 
      419 JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
      420   JNIWrapper("FromReflectedField");
      421   DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field);
      422   jfieldID ret = NULL;
      423   DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
      424 
      425   // field is a handle to a java.lang.reflect.Field object
      426   oop reflected   = JNIHandles::resolve_non_null(field);
      427   oop mirror      = java_lang_reflect_Field::clazz(reflected);
      428   klassOop k      = java_lang_Class::as_klassOop(mirror);
      429   int slot        = java_lang_reflect_Field::slot(reflected);
      430   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
      431 
      432   KlassHandle k1(THREAD, k);
      433   // Make sure class is initialized before handing id's out to fields
      434   Klass::cast(k1())->initialize(CHECK_NULL);
      435 
      436   // First check if this is a static field
      437   if (modifiers & JVM_ACC_STATIC) {
      438     intptr_t offset = instanceKlass::cast(k1())->offset_from_fields( slot );
      439     JNIid* id = instanceKlass::cast(k1())->jni_id_for(offset);
      440     assert(id != NULL, "corrupt Field object");
      441     debug_only(id->set_is_static_field_id();)
      442     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the klassOop
      443     ret = jfieldIDWorkaround::to_static_jfieldID(id);
      444     return ret;
      445   }
      446 
      447   // The slot is the index of the field description in the field-array
      448   // The jfieldID is the offset of the field within the object
      449   // It may also have hash bits for k, if VerifyJNIFields is turned on.
      450   intptr_t offset = instanceKlass::cast(k1())->offset_from_fields( slot );
      451   assert(instanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
      452   ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);
      453   return ret;
      454 JNI_END
      455 
      456 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);
      457 
      458 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
      459   JNIWrapper("ToReflectedMethod");
      460   DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic);
      461   jobject ret = NULL;
      462   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
      463 
      464   methodHandle m (THREAD, JNIHandles::resolve_jmethod_id(method_id));
      465   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
      466   oop reflection_method;
      467   if (m->is_initializer()) {
      468     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
      469   } else {
      470     reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL);
      471   }
      472   ret = JNIHandles::make_local(env, reflection_method);
      473   return ret;
      474 JNI_END
      475 
      476 DT_RETURN_MARK_DECL(GetSuperclass, jclass);
      477 
      478 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
      479   JNIWrapper("GetSuperclass");
      480   DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub);
      481   jclass obj = NULL;
      482   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
      483 
      484   oop mirror = JNIHandles::resolve_non_null(sub);
      485   // primitive classes return NULL
      486   if (java_lang_Class::is_primitive(mirror)) return NULL;
      487 
      488   // Rules of Class.getSuperClass as implemented by KLass::java_super:
      489   // arrays return Object
      490   // interfaces return NULL
      491   // proper classes return Klass::super()
      492   klassOop k = java_lang_Class::as_klassOop(mirror);
      493   if (Klass::cast(k)->is_interface()) return NULL;
      494 
      495   // return mirror for superclass
      496   klassOop super = Klass::cast(k)->java_super();
      497   // super2 is the value computed by the compiler's getSuperClass intrinsic:
      498   debug_only(klassOop super2 = ( Klass::cast(k)->oop_is_javaArray()
      499                                  ? SystemDictionary::object_klass()
      500                                  : Klass::cast(k)->super() ) );
      501   assert(super == super2,
      502          "java_super computation depends on interface, array, other super");
      503   obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(Klass::cast(super)->java_mirror());
      504   return obj;
      505 JNI_END
      506 
      507 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
      508   JNIWrapper("IsSubclassOf");
      509   DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super);
      510   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
      511   oop super_mirror = JNIHandles::resolve_non_null(super);
      512   if (java_lang_Class::is_primitive(sub_mirror) ||
      513       java_lang_Class::is_primitive(super_mirror)) {
      514     jboolean ret = (sub_mirror == super_mirror);
      515     DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
      516     return ret;
      517   }
      518   klassOop sub_klass   = java_lang_Class::as_klassOop(sub_mirror);
      519   klassOop super_klass = java_lang_Class::as_klassOop(super_mirror);
      520   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
      521   jboolean ret = Klass::cast(sub_klass)->is_subtype_of(super_klass) ?
      522                    JNI_TRUE : JNI_FALSE;
      523   DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
      524   return ret;
      525 JNI_END
      526 
      527 DT_RETURN_MARK_DECL(Throw, jint);
      528 
      529 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
      530   JNIWrapper("Throw");
      531   DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj);
      532   jint ret = JNI_OK;
      533   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
      534 
      535   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
      536   ShouldNotReachHere();
      537 JNI_END
      538 
      539 DT_RETURN_MARK_DECL(ThrowNew, jint);
      540 
      541 JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
      542   JNIWrapper("ThrowNew");
      543   DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message);
      544   jint ret = JNI_OK;
      545   DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
      546 
      547   instanceKlass* k = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
      548   symbolHandle name = symbolHandle(THREAD, k->name());
      549   Handle class_loader (THREAD,  k->class_loader());
      550   Handle protection_domain (THREAD, k->protection_domain());
      551   THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);
      552   ShouldNotReachHere();
      553 JNI_END
      554 
      555 
      556 // JNI functions only transform a pending async exception to a synchronous
      557 // exception in ExceptionOccurred and ExceptionCheck calls, since
      558 // delivering an async exception in other places won't change the native
      559 // code's control flow and would be harmful when native code further calls
      560 // JNI functions with a pending exception. Async exception is also checked
      561 // during the call, so ExceptionOccurred/ExceptionCheck won't return
      562 // false but deliver the async exception at the very end during
      563 // state transition.
      564 
      565 static void jni_check_async_exceptions(JavaThread *thread) {
      566   assert(thread == Thread::current(), "must be itself");
      567   thread->check_and_handle_async_exceptions();
      568 }
      569 
      570 JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
      571   JNIWrapper("ExceptionOccurred");
      572   DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env);
      573   jni_check_async_exceptions(thread);
      574   oop exception = thread->pending_exception();
      575   jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
      576   DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret);
      577   return ret;
      578 JNI_END
      579 
      580 
      581 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
      582   JNIWrapper("ExceptionDescribe");
      583   DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env);
      584   if (thread->has_pending_exception()) {
      585     Handle ex(thread, thread->pending_exception());
      586     thread->clear_pending_exception();
      587     if (ex->is_a(SystemDictionary::threaddeath_klass())) {
      588       // Don't print anything if we are being killed.
      589     } else {
      590       jio_fprintf(defaultStream::error_stream(), "Exception ");
      591       if (thread != NULL && thread->threadObj() != NULL) {
      592         ResourceMark rm(THREAD);
      593         jio_fprintf(defaultStream::error_stream(),
      594         "in thread \"%s\" ", thread->get_thread_name());
      595       }
      596       if (ex->is_a(SystemDictionary::throwable_klass())) {
      597         JavaValue result(T_VOID);
      598         JavaCalls::call_virtual(&result,
      599                                 ex,
      600                                 KlassHandle(THREAD,
      601                                   SystemDictionary::throwable_klass()),
      602                                 vmSymbolHandles::printStackTrace_name(),
      603                                 vmSymbolHandles::void_method_signature(),
      604                                 THREAD);
      605         // If an exception is thrown in the call it gets thrown away. Not much
      606         // we can do with it. The native code that calls this, does not check
      607         // for the exception - hence, it might still be in the thread when DestroyVM gets
      608         // called, potentially causing a few asserts to trigger - since no pending exception
      609         // is expected.
      610         CLEAR_PENDING_EXCEPTION;
      611       } else {
      612         ResourceMark rm(THREAD);
      613         jio_fprintf(defaultStream::error_stream(),
      614         ". Uncaught exception of type %s.",
      615         Klass::cast(ex->klass())->external_name());
      616       }
      617     }
      618   }
      619   DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return);
      620 JNI_END
      621 
      622 
      623 JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env))
      624   JNIWrapper("ExceptionClear");
      625   DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env);
      626 
      627   // The jni code might be using this API to clear java thrown exception.
      628   // So just mark jvmti thread exception state as exception caught.
      629   JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();
      630   if (state != NULL && state->is_exception_detected()) {
      631     state->set_exception_caught();
      632   }
      633   thread->clear_pending_exception();
      634   DTRACE_PROBE(hotspot_jni, ExceptionClear__return);
      635 JNI_END
      636 
      637 
      638 JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
      639   JNIWrapper("FatalError");
      640   DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);
      641   tty->print_cr("FATAL ERROR in native method: %s", msg);
      642   thread->print_stack();
      643   os::abort(); // Dump core and abort
      644 JNI_END
      645 
      646 
      647 JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
      648   JNIWrapper("PushLocalFrame");
      649   DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity);
      650   //%note jni_11
      651   if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
      652     DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
      653     return JNI_ERR;
      654   }
      655   JNIHandleBlock* old_handles = thread->active_handles();
      656   JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
      657   assert(new_handles != NULL, "should not be NULL");
      658   new_handles->set_pop_frame_link(old_handles);
      659   thread->set_active_handles(new_handles);
      660   jint ret = JNI_OK;
      661   DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret);
      662   return ret;
      663 JNI_END
      664 
      665 
      666 JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
      667   JNIWrapper("PopLocalFrame");
      668   DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result);
      669   //%note jni_11
      670   Handle result_handle(thread, JNIHandles::resolve(result));
      671   JNIHandleBlock* old_handles = thread->active_handles();
      672   JNIHandleBlock* new_handles = old_handles->pop_frame_link();
      673   if (new_handles != NULL) {
      674     // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.
      675     // This way code will still work if PopLocalFrame is called without a corresponding
      676     // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise
      677     // the release_block call will release the blocks.
      678     thread->set_active_handles(new_handles);
      679     old_handles->set_pop_frame_link(NULL);              // clear link we won't release new_handles below
      680     JNIHandleBlock::release_block(old_handles, thread); // may block
      681     result = JNIHandles::make_local(thread, result_handle());
      682   }
      683   DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result);
      684   return result;
      685 JNI_END
      686 
      687 
      688 JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
      689   JNIWrapper("NewGlobalRef");
      690   DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref);
      691   Handle ref_handle(thread, JNIHandles::resolve(ref));
      692   jobject ret = JNIHandles::make_global(ref_handle);
      693   DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret);
      694   return ret;
      695 JNI_END
      696 
      697 // Must be JNI_ENTRY (with HandleMark)
      698 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
      699   JNIWrapper("DeleteGlobalRef");
      700   DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref);
      701   JNIHandles::destroy_global(ref);
      702   DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return);
      703 JNI_END
      704 
      705 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
      706   JNIWrapper("DeleteLocalRef");
      707   DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj);
      708   JNIHandles::destroy_local(obj);
      709   DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return);
      710 JNI_END
      711 
      712 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
      713   JNIWrapper("IsSameObject");
      714   DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2);
      715   oop a = JNIHandles::resolve(r1);
      716   oop b = JNIHandles::resolve(r2);
      717   jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
      718   DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret);
      719   return ret;
      720 JNI_END
      721 
      722 
      723 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
      724   JNIWrapper("NewLocalRef");
      725   DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref);
      726   jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
      727   DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret);
      728   return ret;
      729 JNI_END
      730 
      731 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
      732   JNIWrapper("EnsureLocalCapacity");
      733   DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity);
      734   jint ret;
      735   if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
      736     ret = JNI_OK;
      737   } else {
      738     ret = JNI_ERR;
      739   }
      740   DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret);
      741   return ret;
      742 JNI_END
      743 
      744 // Return the Handle Type
      745 JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
      746   JNIWrapper("GetObjectRefType");
      747   DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj);
      748   jobjectRefType ret;
      749   if (JNIHandles::is_local_handle(thread, obj) ||
      750       JNIHandles::is_frame_handle(thread, obj))
      751     ret = JNILocalRefType;
      752   else if (JNIHandles::is_global_handle(obj))
      753     ret = JNIGlobalRefType;
      754   else if (JNIHandles::is_weak_global_handle(obj))
      755     ret = JNIWeakGlobalRefType;
      756   else
      757     ret = JNIInvalidRefType;
      758   DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret);
      759   return ret;
      760 JNI_END
      761 
      762 
      763 class JNI_ArgumentPusher : public SignatureIterator {
      764  protected:
      765   JavaCallArguments*  _arguments;
      766 
      767   virtual void get_bool   () = 0;
      768   virtual void get_char   () = 0;
      769   virtual void get_short  () = 0;
      770   virtual void get_byte   () = 0;
      771   virtual void get_int    () = 0;
      772   virtual void get_long   () = 0;
      773   virtual void get_float  () = 0;
      774   virtual void get_double () = 0;
      775   virtual void get_object () = 0;
      776 
      777   JNI_ArgumentPusher(Thread *thread, symbolOop signature)
      778        : SignatureIterator(thread, signature) {
      779     this->_return_type = T_ILLEGAL;
      780     _arguments = NULL;
      781   }
      782 
      783  public:
      784   virtual void iterate( uint64_t fingerprint ) = 0;
      785 
      786   void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }
      787 
      788   inline void do_bool()                     { if (!is_return_type()) get_bool();   }
      789   inline void do_char()                     { if (!is_return_type()) get_char();   }
      790   inline void do_short()                    { if (!is_return_type()) get_short();  }
      791   inline void do_byte()                     { if (!is_return_type()) get_byte();   }
      792   inline void do_int()                      { if (!is_return_type()) get_int();    }
      793   inline void do_long()                     { if (!is_return_type()) get_long();   }
      794   inline void do_float()                    { if (!is_return_type()) get_float();  }
      795   inline void do_double()                   { if (!is_return_type()) get_double(); }
      796   inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }
      797   inline void do_array(int begin, int end)  { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array
      798   inline void do_void()                     { }
      799 
      800   JavaCallArguments* arguments()     { return _arguments; }
      801   void push_receiver(Handle h)       { _arguments->push_oop(h); }
      802 };
      803 
      804 
      805 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
      806  protected:
      807   va_list _ap;
      808 
      809   inline void get_bool()   { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg
      810   inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
      811   inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
      812   inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
      813   inline void get_int()    { _arguments->push_int(va_arg(_ap, jint)); }
      814 
      815   // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
      816 
      817   inline void get_long()   { _arguments->push_long(va_arg(_ap, jlong)); }
      818   inline void get_float()  { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
      819   inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
      820   inline void get_object() { jobject l = va_arg(_ap, jobject);
      821                              _arguments->push_oop(Handle((oop *)l, false)); }
      822 
      823   inline void set_ap(va_list rap) {
      824 #ifdef va_copy
      825     va_copy(_ap, rap);
      826 #elif defined (__va_copy)
      827     __va_copy(_ap, rap);
      828 #else
      829     _ap = rap;
      830 #endif
      831   }
      832 
      833  public:
      834   JNI_ArgumentPusherVaArg(Thread *thread, symbolOop signature, va_list rap)
      835        : JNI_ArgumentPusher(thread, signature) {
      836     set_ap(rap);
      837   }
      838   JNI_ArgumentPusherVaArg(Thread *thread, jmethodID method_id, va_list rap)
      839       : JNI_ArgumentPusher(thread, JNIHandles::resolve_jmethod_id(method_id)->signature()) {
      840     set_ap(rap);
      841   }
      842 
      843   // Optimized path if we have the bitvector form of signature
      844   void iterate( uint64_t fingerprint ) {
      845     if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments
      846     else {
      847       _return_type = (BasicType)((fingerprint >> static_feature_size) &
      848                                   result_feature_mask);
      849 
      850       assert(fingerprint, "Fingerprint should not be 0");
      851       fingerprint = fingerprint >> (static_feature_size + result_feature_size);
      852       while ( 1 ) {
      853         switch ( fingerprint & parameter_feature_mask ) {
      854           case bool_parm:
      855           case char_parm:
      856           case short_parm:
      857           case byte_parm:
      858           case int_parm:
      859             get_int();
      860             break;
      861           case obj_parm:
      862             get_object();
      863             break;
      864           case long_parm:
      865             get_long();
      866             break;
      867           case float_parm:
      868             get_float();
      869             break;
      870           case double_parm:
      871             get_double();
      872             break;
      873           case done_parm:
      874             return;
      875             break;
      876           default:
      877             ShouldNotReachHere();
      878             break;
      879         }
      880         fingerprint >>= parameter_feature_size;
      881       }
      882     }
      883   }
      884 };
      885 
      886 
      887 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
      888  protected:
      889   const jvalue *_ap;
      890 
      891   inline void get_bool()   { _arguments->push_int((jint)(_ap++)->z); }
      892   inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
      893   inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
      894   inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
      895   inline void get_int()    { _arguments->push_int((jint)(_ap++)->i); }
      896 
      897   inline void get_long()   { _arguments->push_long((_ap++)->j);  }
      898   inline void get_float()  { _arguments->push_float((_ap++)->f); }
      899   inline void get_double() { _arguments->push_double((_ap++)->d);}
      900   inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); }
      901 
      902   inline void set_ap(const jvalue *rap) { _ap = rap; }
      903 
      904  public:
      905   JNI_ArgumentPusherArray(Thread *thread, symbolOop signature, const jvalue *rap)
      906        : JNI_ArgumentPusher(thread, signature) {
      907     set_ap(rap);
      908   }
      909   JNI_ArgumentPusherArray(Thread *thread, jmethodID method_id, const jvalue *rap)
      910       : JNI_ArgumentPusher(thread, JNIHandles::resolve_jmethod_id(method_id)->signature()) {
      911     set_ap(rap);
      912   }
      913 
      914   // Optimized path if we have the bitvector form of signature
      915   void iterate( uint64_t fingerprint ) {
      916     if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments
      917     else {
      918       _return_type = (BasicType)((fingerprint >> static_feature_size) &
      919                                   result_feature_mask);
      920       assert(fingerprint, "Fingerprint should not be 0");
      921       fingerprint = fingerprint >> (static_feature_size + result_feature_size);
      922       while ( 1 ) {
      923         switch ( fingerprint & parameter_feature_mask ) {
      924           case bool_parm:
      925             get_bool();
      926             break;
      927           case char_parm:
      928             get_char();
      929             break;
      930           case short_parm:
      931             get_short();
      932             break;
      933           case byte_parm:
      934             get_byte();
      935             break;
      936           case int_parm:
      937             get_int();
      938             break;
      939           case obj_parm:
      940             get_object();
      941             break;
      942           case long_parm:
      943             get_long();
      944             break;
      945           case float_parm:
      946             get_float();
      947             break;
      948           case double_parm:
      949             get_double();
      950             break;
      951           case done_parm:
      952             return;
      953             break;
      954           default:
      955             ShouldNotReachHere();
      956             break;
      957         }
      958         fingerprint >>= parameter_feature_size;
      959       }
      960     }
      961   }
      962 };
      963 
      964 
      965 enum JNICallType {
      966   JNI_STATIC,
      967   JNI_VIRTUAL,
      968   JNI_NONVIRTUAL
      969 };
      970 
      971 static methodHandle jni_resolve_interface_call(Handle recv, methodHandle method, TRAPS) {
      972   assert(!method.is_null() , "method should not be null");
      973 
      974   KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc)
      975   if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass());
      976   KlassHandle spec_klass (THREAD, method->method_holder());
      977   symbolHandle name (THREAD, method->name());
      978   symbolHandle signature (THREAD, method->signature());
      979   CallInfo info;
      980   LinkResolver::resolve_interface_call(info, recv, recv_klass,  spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle()));
      981   return info.selected_method();
      982 }
      983 
      984 static methodHandle jni_resolve_virtual_call(Handle recv, methodHandle method, TRAPS) {
      985   assert(!method.is_null() , "method should not be null");
      986 
      987   KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc)
      988   if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass());
      989   KlassHandle spec_klass (THREAD, method->method_holder());
      990   symbolHandle name (THREAD, method->name());
      991   symbolHandle signature (THREAD, method->signature());
      992   CallInfo info;
      993   LinkResolver::resolve_virtual_call(info, recv, recv_klass,  spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle()));
      994   return info.selected_method();
      995 }
      996 
      997 
      998 
      999 static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
     1000   methodHandle method(THREAD, JNIHandles::resolve_jmethod_id(method_id));
     1001 
     1002   // Create object to hold arguments for the JavaCall, and associate it with
     1003   // the jni parser
     1004   ResourceMark rm(THREAD);
     1005   int number_of_parameters = method->size_of_parameters();
     1006   JavaCallArguments java_args(number_of_parameters);
     1007   args->set_java_argument_object(&java_args);
     1008 
     1009   assert(method->is_static(), "method should be static");
     1010 
     1011   // Fill out JavaCallArguments object
     1012   args->iterate( Fingerprinter(THREAD, method).fingerprint() );
     1013   // Initialize result type
     1014   result->set_type(args->get_ret_type());
     1015 
     1016   // Invoke the method. Result is returned as oop.
     1017   JavaCalls::call(result, method, &java_args, CHECK);
     1018 
     1019   // Convert result
     1020   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
     1021     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
     1022   }
     1023 }
     1024 
     1025 
     1026 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
     1027   oop recv = JNIHandles::resolve(receiver);
     1028   if (recv == NULL) {
     1029     THROW(vmSymbols::java_lang_NullPointerException());
     1030   }
     1031   Handle h_recv(THREAD, recv);
     1032 
     1033   int number_of_parameters;
     1034   methodOop selected_method;
     1035   {
     1036     methodOop m = JNIHandles::resolve_jmethod_id(method_id);
     1037     number_of_parameters = m->size_of_parameters();
     1038     klassOop holder = m->method_holder();
     1039     if (!(Klass::cast(holder))->is_interface()) {
     1040       // non-interface call -- for that little speed boost, don't handlize
     1041       debug_only(No_Safepoint_Verifier nosafepoint;)
     1042       if (call_type == JNI_VIRTUAL) {
     1043         // jni_GetMethodID makes sure class is linked and initialized
     1044         // so m should have a valid vtable index.
     1045         int vtbl_index = m->vtable_index();
     1046         if (vtbl_index != methodOopDesc::nonvirtual_vtable_index) {
     1047           klassOop k = h_recv->klass();
     1048           // k might be an arrayKlassOop but all vtables start at
     1049           // the same place. The cast is to avoid virtual call and assertion.
     1050           instanceKlass *ik = (instanceKlass*)k->klass_part();
     1051           selected_method = ik->method_at_vtable(vtbl_index);
     1052         } else {
     1053           // final method
     1054           selected_method = m;
     1055         }
     1056       } else {
     1057         // JNI_NONVIRTUAL call
     1058         selected_method = m;
     1059       }
     1060     } else {
     1061       // interface call
     1062       KlassHandle h_holder(THREAD, holder);
     1063 
     1064       int itbl_index = m->cached_itable_index();
     1065       if (itbl_index == -1) {
     1066         itbl_index = klassItable::compute_itable_index(m);
     1067         m->set_cached_itable_index(itbl_index);
     1068         // the above may have grabbed a lock, 'm' and anything non-handlized can't be used again
     1069       }
     1070       klassOop k = h_recv->klass();
     1071       selected_method = instanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
     1072     }
     1073   }
     1074 
     1075   methodHandle method(THREAD, selected_method);
     1076 
     1077   // Create object to hold arguments for the JavaCall, and associate it with
     1078   // the jni parser
     1079   ResourceMark rm(THREAD);
     1080   JavaCallArguments java_args(number_of_parameters);
     1081   args->set_java_argument_object(&java_args);
     1082 
     1083   // handle arguments
     1084   assert(!method->is_static(), "method should not be static");
     1085   args->push_receiver(h_recv); // Push jobject handle
     1086 
     1087   // Fill out JavaCallArguments object
     1088   args->iterate( Fingerprinter(THREAD, method).fingerprint() );
     1089   // Initialize result type
     1090   result->set_type(args->get_ret_type());
     1091 
     1092   // Invoke the method. Result is returned as oop.
     1093   JavaCalls::call(result, method, &java_args, CHECK);
     1094 
     1095   // Convert result
     1096   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
     1097     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
     1098   }
     1099 }
     1100 
     1101 
     1102 static instanceOop alloc_object(jclass clazz, TRAPS) {
     1103   KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
     1104   Klass::cast(k())->check_valid_for_instantiation(false, CHECK_NULL);
     1105   instanceKlass::cast(k())->initialize(CHECK_NULL);
     1106   instanceOop ih = instanceKlass::cast(k())->allocate_instance(THREAD);
     1107   return ih;
     1108 }
     1109 
     1110 DT_RETURN_MARK_DECL(AllocObject, jobject);
     1111 
     1112 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
     1113   JNIWrapper("AllocObject");
     1114 
     1115   DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz);
     1116   jobject ret = NULL;
     1117   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
     1118 
     1119   instanceOop i = alloc_object(clazz, CHECK_NULL);
     1120   ret = JNIHandles::make_local(env, i);
     1121   return ret;
     1122 JNI_END
     1123 
     1124 DT_RETURN_MARK_DECL(NewObjectA, jobject);
     1125 
     1126 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
     1127   JNIWrapper("NewObjectA");
     1128   DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID);
     1129   jobject obj = NULL;
     1130   DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
     1131 
     1132   instanceOop i = alloc_object(clazz, CHECK_NULL);
     1133   obj = JNIHandles::make_local(env, i);
     1134   JavaValue jvalue(T_VOID);
     1135   JNI_ArgumentPusherArray ap(THREAD, methodID, args);
     1136   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
     1137   return obj;
     1138 JNI_END
     1139 
     1140 DT_RETURN_MARK_DECL(NewObjectV, jobject);
     1141 
     1142 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
     1143   JNIWrapper("NewObjectV");
     1144   DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID);
     1145   jobject obj = NULL;
     1146   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
     1147 
     1148   instanceOop i = alloc_object(clazz, CHECK_NULL);
     1149   obj = JNIHandles::make_local(env, i);
     1150   JavaValue jvalue(T_VOID);
     1151   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1152   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
     1153   return obj;
     1154 JNI_END
     1155 
     1156 DT_RETURN_MARK_DECL(NewObject, jobject);
     1157 
     1158 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
     1159   JNIWrapper("NewObject");
     1160   DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID);
     1161   jobject obj = NULL;
     1162   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
     1163 
     1164   instanceOop i = alloc_object(clazz, CHECK_NULL);
     1165   obj = JNIHandles::make_local(env, i);
     1166   va_list args;
     1167   va_start(args, methodID);
     1168   JavaValue jvalue(T_VOID);
     1169   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1170   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
     1171   va_end(args);
     1172   return obj;
     1173 JNI_END
     1174 
     1175 
     1176 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
     1177   JNIWrapper("GetObjectClass");
     1178   DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj);
     1179   klassOop k = JNIHandles::resolve_non_null(obj)->klass();
     1180   jclass ret =
     1181     (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
     1182   DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);
     1183   return ret;
     1184 JNI_END
     1185 
     1186 JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
     1187   JNIWrapper("IsInstanceOf");
     1188   DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz);
     1189   jboolean ret = JNI_TRUE;
     1190   if (obj != NULL) {
     1191     ret = JNI_FALSE;
     1192     klassOop k = java_lang_Class::as_klassOop(
     1193       JNIHandles::resolve_non_null(clazz));
     1194     if (k != NULL) {
     1195       ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
     1196     }
     1197   }
     1198   DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret);
     1199   return ret;
     1200 JNI_END
     1201 
     1202 
     1203 static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
     1204                                const char *sig, bool is_static, TRAPS) {
     1205   // %%%% This code should probably just call into a method in the LinkResolver
     1206   //
     1207   // The class should have been loaded (we have an instance of the class
     1208   // passed in) so the method and signature should already be in the symbol
     1209   // table.  If they're not there, the method doesn't exist.
     1210   symbolHandle signature =
     1211            symbolHandle(THREAD, SymbolTable::probe(sig, (int)strlen(sig)));
     1212   symbolHandle name;
     1213   if (name_str == NULL) {
     1214     name = vmSymbolHandles::object_initializer_name();
     1215   } else {
     1216     name = symbolHandle(THREAD,
     1217                         SymbolTable::probe(name_str, (int)strlen(name_str)));
     1218   }
     1219   if (name.is_null() || signature.is_null()) {
     1220     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
     1221   }
     1222 
     1223   // Throw a NoSuchMethodError exception if we have an instance of a
     1224   // primitive java.lang.Class
     1225   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
     1226     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
     1227   }
     1228 
     1229   KlassHandle klass(THREAD,
     1230                java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
     1231 
     1232   // Make sure class is linked and initialized before handing id's out to
     1233   // methodOops.
     1234   Klass::cast(klass())->initialize(CHECK_NULL);
     1235 
     1236   methodOop m;
     1237   if (name() == vmSymbols::object_initializer_name() ||
     1238       name() == vmSymbols::class_initializer_name()) {
     1239     // Never search superclasses for constructors
     1240     if (klass->oop_is_instance()) {
     1241       m = instanceKlass::cast(klass())->find_method(name(), signature());
     1242     } else {
     1243       m = NULL;
     1244     }
     1245   } else {
     1246     m = klass->lookup_method(name(), signature());
     1247     // Look up interfaces
     1248     if (m == NULL && klass->oop_is_instance()) {
     1249       m = instanceKlass::cast(klass())->lookup_method_in_all_interfaces(name(),
     1250                                                                    signature());
     1251     }
     1252   }
     1253   if (m == NULL || (m->is_static() != is_static)) {
     1254     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
     1255   }
     1256   return m->jmethod_id();
     1257 }
     1258 
     1259 
     1260 JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
     1261           const char *name, const char *sig))
     1262   JNIWrapper("GetMethodID");
     1263   DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig);
     1264   jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
     1265   DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret);
     1266   return ret;
     1267 JNI_END
     1268 
     1269 
     1270 JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
     1271           const char *name, const char *sig))
     1272   JNIWrapper("GetStaticMethodID");
     1273   DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig);
     1274   jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
     1275   DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret);
     1276   return ret;
     1277 JNI_END
     1278 
     1279 
     1280 
     1281 //
     1282 // Calling Methods
     1283 //
     1284 
     1285 
     1286 #define DEFINE_CALLMETHOD(ResultType, Result, Tag) \
     1287 \
     1288   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\
     1289   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType);\
     1290   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType);\
     1291 \
     1292 JNI_ENTRY(ResultType, \
     1293           jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
     1294   JNIWrapper("Call" XSTR(Result) "Method"); \
     1295 \
     1296   DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID);\
     1297   ResultType ret = 0;\
     1298   DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
     1299                      (const ResultType&)ret);\
     1300 \
     1301   va_list args; \
     1302   va_start(args, methodID); \
     1303   JavaValue jvalue(Tag); \
     1304   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \
     1305   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
     1306   va_end(args); \
     1307   ret = jvalue.get_##ResultType(); \
     1308   return ret;\
     1309 JNI_END \
     1310 \
     1311 \
     1312 JNI_ENTRY(ResultType, \
     1313           jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
     1314   JNIWrapper("Call" XSTR(Result) "MethodV"); \
     1315 \
     1316   DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID);\
     1317   ResultType ret = 0;\
     1318   DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
     1319                      (const ResultType&)ret);\
     1320 \
     1321   JavaValue jvalue(Tag); \
     1322   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \
     1323   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
     1324   ret = jvalue.get_##ResultType(); \
     1325   return ret;\
     1326 JNI_END \
     1327 \
     1328 \
     1329 JNI_ENTRY(ResultType, \
     1330           jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
     1331   JNIWrapper("Call" XSTR(Result) "MethodA"); \
     1332   DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID);\
     1333   ResultType ret = 0;\
     1334   DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
     1335                      (const ResultType&)ret);\
     1336 \
     1337   JavaValue jvalue(Tag); \
     1338   JNI_ArgumentPusherArray ap(THREAD, methodID, args); \
     1339   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
     1340   ret = jvalue.get_##ResultType(); \
     1341   return ret;\
     1342 JNI_END
     1343 
     1344 // the runtime type of subword integral basic types is integer
     1345 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN)
     1346 DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE)
     1347 DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR)
     1348 DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT)
     1349 
     1350 DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT)
     1351 DEFINE_CALLMETHOD(jint,     Int,     T_INT)
     1352 DEFINE_CALLMETHOD(jlong,    Long,    T_LONG)
     1353 DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT)
     1354 DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE)
     1355 
     1356 DT_VOID_RETURN_MARK_DECL(CallVoidMethod);
     1357 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV);
     1358 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA);
     1359 
     1360 JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
     1361   JNIWrapper("CallVoidMethod");
     1362   DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID);
     1363   DT_VOID_RETURN_MARK(CallVoidMethod);
     1364 
     1365   va_list args;
     1366   va_start(args, methodID);
     1367   JavaValue jvalue(T_VOID);
     1368   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1369   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
     1370   va_end(args);
     1371 JNI_END
     1372 
     1373 
     1374 JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
     1375   JNIWrapper("CallVoidMethodV");
     1376   DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID);
     1377   DT_VOID_RETURN_MARK(CallVoidMethodV);
     1378 
     1379   JavaValue jvalue(T_VOID);
     1380   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1381   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
     1382 JNI_END
     1383 
     1384 
     1385 JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
     1386   JNIWrapper("CallVoidMethodA");
     1387   DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID);
     1388   DT_VOID_RETURN_MARK(CallVoidMethodA);
     1389 
     1390   JavaValue jvalue(T_VOID);
     1391   JNI_ArgumentPusherArray ap(THREAD, methodID, args);
     1392   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
     1393 JNI_END
     1394 
     1395 
     1396 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \
     1397 \
     1398   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\
     1399   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType);\
     1400   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType);\
     1401 \
     1402 JNI_ENTRY(ResultType, \
     1403           jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
     1404   JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
     1405 \
     1406   DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##Method__entry, env, obj, cls, methodID);\
     1407   ResultType ret;\
     1408   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
     1409                      (const ResultType&)ret);\
     1410 \
     1411   va_list args; \
     1412   va_start(args, methodID); \
     1413   JavaValue jvalue(Tag); \
     1414   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \
     1415   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
     1416   va_end(args); \
     1417   ret = jvalue.get_##ResultType(); \
     1418   return ret;\
     1419 JNI_END \
     1420 \
     1421 JNI_ENTRY(ResultType, \
     1422           jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
     1423   JNIWrapper("CallNonvitual" XSTR(Result) "#MethodV"); \
     1424   DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodV__entry, env, obj, cls, methodID);\
     1425   ResultType ret;\
     1426   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
     1427                      (const ResultType&)ret);\
     1428 \
     1429   JavaValue jvalue(Tag); \
     1430   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \
     1431   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
     1432   ret = jvalue.get_##ResultType(); \
     1433   return ret;\
     1434 JNI_END \
     1435 \
     1436 JNI_ENTRY(ResultType, \
     1437           jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
     1438   JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
     1439   DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodA__entry, env, obj, cls, methodID);\
     1440   ResultType ret;\
     1441   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
     1442                      (const ResultType&)ret);\
     1443 \
     1444   JavaValue jvalue(Tag); \
     1445   JNI_ArgumentPusherArray ap(THREAD, methodID, args); \
     1446   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
     1447   ret = jvalue.get_##ResultType(); \
     1448   return ret;\
     1449 JNI_END
     1450 
     1451 // the runtime type of subword integral basic types is integer
     1452 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN)
     1453 DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE)
     1454 DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR)
     1455 DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT)
     1456 
     1457 DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT)
     1458 DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT)
     1459 DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG)
     1460 DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT)
     1461 DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE)
     1462 
     1463 
     1464 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod);
     1465 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV);
     1466 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA);
     1467 
     1468 JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
     1469   JNIWrapper("CallNonvirtualVoidMethod");
     1470 
     1471   DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry,
     1472                env, obj, cls, methodID);
     1473   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
     1474 
     1475   va_list args;
     1476   va_start(args, methodID);
     1477   JavaValue jvalue(T_VOID);
     1478   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1479   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
     1480   va_end(args);
     1481 JNI_END
     1482 
     1483 
     1484 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
     1485   JNIWrapper("CallNonvirtualVoidMethodV");
     1486 
     1487   DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry,
     1488                env, obj, cls, methodID);
     1489   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);
     1490 
     1491   JavaValue jvalue(T_VOID);
     1492   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1493   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
     1494 JNI_END
     1495 
     1496 
     1497 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))
     1498   JNIWrapper("CallNonvirtualVoidMethodA");
     1499   DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodA__entry,
     1500                 env, obj, cls, methodID);
     1501   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);
     1502   JavaValue jvalue(T_VOID);
     1503   JNI_ArgumentPusherArray ap(THREAD, methodID, args);
     1504   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
     1505 JNI_END
     1506 
     1507 
     1508 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag) \
     1509 \
     1510   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType);\
     1511   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType);\
     1512   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType);\
     1513 \
     1514 JNI_ENTRY(ResultType, \
     1515           jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
     1516   JNIWrapper("CallStatic" XSTR(Result) "Method"); \
     1517 \
     1518   DTRACE_PROBE3(hotspot_jni, CallStatic##Result##Method__entry, env, cls, methodID);\
     1519   ResultType ret = 0;\
     1520   DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
     1521                      (const ResultType&)ret);\
     1522 \
     1523   va_list args; \
     1524   va_start(args, methodID); \
     1525   JavaValue jvalue(Tag); \
     1526   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \
     1527   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
     1528   va_end(args); \
     1529   ret = jvalue.get_##ResultType(); \
     1530   return ret;\
     1531 JNI_END \
     1532 \
     1533 JNI_ENTRY(ResultType, \
     1534           jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
     1535   JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
     1536   DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodV__entry, env, cls, methodID);\
     1537   ResultType ret = 0;\
     1538   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
     1539                      (const ResultType&)ret);\
     1540 \
     1541   JavaValue jvalue(Tag); \
     1542   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args); \
     1543   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
     1544   ret = jvalue.get_##ResultType(); \
     1545   return ret;\
     1546 JNI_END \
     1547 \
     1548 JNI_ENTRY(ResultType, \
     1549           jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
     1550   JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
     1551   DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodA__entry, env, cls, methodID);\
     1552   ResultType ret = 0;\
     1553   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
     1554                      (const ResultType&)ret);\
     1555 \
     1556   JavaValue jvalue(Tag); \
     1557   JNI_ArgumentPusherArray ap(THREAD, methodID, args); \
     1558   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
     1559   ret = jvalue.get_##ResultType(); \
     1560   return ret;\
     1561 JNI_END
     1562 
     1563 // the runtime type of subword integral basic types is integer
     1564 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN)
     1565 DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE)
     1566 DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR)
     1567 DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT)
     1568 
     1569 DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT)
     1570 DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT)
     1571 DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG)
     1572 DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT)
     1573 DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE)
     1574 
     1575 
     1576 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod);
     1577 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV);
     1578 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA);
     1579 
     1580 JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
     1581   JNIWrapper("CallStaticVoidMethod");
     1582   DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID);
     1583   DT_VOID_RETURN_MARK(CallStaticVoidMethod);
     1584 
     1585   va_list args;
     1586   va_start(args, methodID);
     1587   JavaValue jvalue(T_VOID);
     1588   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1589   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
     1590   va_end(args);
     1591 JNI_END
     1592 
     1593 
     1594 JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
     1595   JNIWrapper("CallStaticVoidMethodV");
     1596   DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID);
     1597   DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
     1598 
     1599   JavaValue jvalue(T_VOID);
     1600   JNI_ArgumentPusherVaArg ap(THREAD, methodID, args);
     1601   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
     1602 JNI_END
     1603 
     1604 
     1605 JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
     1606   JNIWrapper("CallStaticVoidMethodA");
     1607   DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID);
     1608   DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
     1609 
     1610   JavaValue jvalue(T_VOID);
     1611   JNI_ArgumentPusherArray ap(THREAD, methodID, args);
     1612   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
     1613 JNI_END
     1614 
     1615 
     1616 //
     1617 // Accessing Fields
     1618 //
     1619 
     1620 
     1621 DT_RETURN_MARK_DECL(GetFieldID, jfieldID);
     1622 
     1623 JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
     1624           const char *name, const char *sig))
     1625   JNIWrapper("GetFieldID");
     1626   DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig);
     1627   jfieldID ret = 0;
     1628   DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
     1629 
     1630   // The class should have been loaded (we have an instance of the class
     1631   // passed in) so the field and signature should already be in the symbol
     1632   // table.  If they're not there, the field doesn't exist.
     1633   symbolHandle fieldname =
     1634             symbolHandle(THREAD, SymbolTable::probe(name, (int)strlen(name)));
     1635   symbolHandle signame   =
     1636             symbolHandle(THREAD, SymbolTable::probe(sig, (int)strlen(sig)));
     1637   if (fieldname.is_null() || signame.is_null()) {
     1638     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
     1639   }
     1640   KlassHandle k(THREAD,
     1641                 java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
     1642   // Make sure class is initialized before handing id's out to fields
     1643   Klass::cast(k())->initialize(CHECK_NULL);
     1644 
     1645   fieldDescriptor fd;
     1646   if (!Klass::cast(k())->oop_is_instance() ||
     1647       !instanceKlass::cast(k())->find_field(fieldname(), signame(), false, &fd)) {
     1648     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
     1649   }
     1650 
     1651   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
     1652   // It may also have hash bits for k, if VerifyJNIFields is turned on.
     1653   ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());
     1654   return ret;
     1655 JNI_END
     1656 
     1657 
     1658 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
     1659   JNIWrapper("GetObjectField");
     1660   DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
     1661   oop o = JNIHandles::resolve_non_null(obj);
     1662   klassOop k = o->klass();
     1663   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
     1664   // Keep JVMTI addition small and only check enabled flag here.
     1665   // jni_GetField_probe() assumes that is okay to create handles.
     1666   if (JvmtiExport::should_post_field_access()) {
     1667     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
     1668   }
     1669   jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
     1670   DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
     1671   return ret;
     1672 JNI_END
     1673 
     1674 
     1675 #define DEFINE_GETFIELD(Return,Fieldname,Result) \
     1676 \
     1677   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\
     1678 \
     1679 JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
     1680   JNIWrapper("Get" XSTR(Result) "Field"); \
     1681 \
     1682   DTRACE_PROBE3(hotspot_jni, Get##Result##Field__entry, env, obj, fieldID);\
     1683   Return ret = 0;\
     1684   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
     1685 \
     1686   oop o = JNIHandles::resolve_non_null(obj); \
     1687   klassOop k = o->klass(); \
     1688   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
     1689   /* Keep JVMTI addition small and only check enabled flag here.       */ \
     1690   /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
     1691   /* and creates a ResetNoHandleMark.                                   */ \
     1692   if (JvmtiExport::should_post_field_access()) { \
     1693     o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
     1694   } \
     1695   ret = o->Fieldname##_field(offset); \
     1696   return ret; \
     1697 JNI_END
     1698 
     1699 DEFINE_GETFIELD(jboolean, bool,   Boolean)
     1700 DEFINE_GETFIELD(jbyte,    byte,   Byte)
     1701 DEFINE_GETFIELD(jchar,    char,   Char)
     1702 DEFINE_GETFIELD(jshort,   short,  Short)
     1703 DEFINE_GETFIELD(jint,     int,    Int)
     1704 DEFINE_GETFIELD(jlong,    long,   Long)
     1705 DEFINE_GETFIELD(jfloat,   float,  Float)
     1706 DEFINE_GETFIELD(jdouble,  double, Double)
     1707 
     1708 address jni_GetBooleanField_addr() {
     1709   return (address)jni_GetBooleanField;
     1710 }
     1711 address jni_GetByteField_addr() {
     1712   return (address)jni_GetByteField;
     1713 }
     1714 address jni_GetCharField_addr() {
     1715   return (address)jni_GetCharField;
     1716 }
     1717 address jni_GetShortField_addr() {
     1718   return (address)jni_GetShortField;
     1719 }
     1720 address jni_GetIntField_addr() {
     1721   return (address)jni_GetIntField;
     1722 }
     1723 address jni_GetLongField_addr() {
     1724   return (address)jni_GetLongField;
     1725 }
     1726 address jni_GetFloatField_addr() {
     1727   return (address)jni_GetFloatField;
     1728 }
     1729 address jni_GetDoubleField_addr() {
     1730   return (address)jni_GetDoubleField;
     1731 }
     1732 
     1733 JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
     1734   JNIWrapper("SetObjectField");
     1735   DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value);
     1736   oop o = JNIHandles::resolve_non_null(obj);
     1737   klassOop k = o->klass();
     1738   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
     1739   // Keep JVMTI addition small and only check enabled flag here.
     1740   // jni_SetField_probe_nh() assumes that is not okay to create handles
     1741   // and creates a ResetNoHandleMark.
     1742   if (JvmtiExport::should_post_field_modification()) {
     1743     jvalue field_value;
     1744     field_value.l = value;
     1745     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
     1746   }
     1747   o->obj_field_put(offset, JNIHandles::resolve(value));
     1748   DTRACE_PROBE(hotspot_jni, SetObjectField__return);
     1749 JNI_END
     1750 
     1751 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \
     1752 \
     1753 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
     1754   JNIWrapper("Set" XSTR(Result) "Field"); \
     1755 \
     1756   HS_DTRACE_PROBE_CDECL_N(hotspot_jni, Set##Result##Field__entry, \
     1757     ( JNIEnv*, jobject, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \
     1758   HS_DTRACE_PROBE_N(hotspot_jni, Set##Result##Field__entry, \
     1759     ( env, obj, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \
     1760 \
     1761   oop o = JNIHandles::resolve_non_null(obj); \
     1762   klassOop k = o->klass(); \
     1763   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
     1764   /* Keep JVMTI addition small and only check enabled flag here.       */ \
     1765   /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
     1766   /* and creates a ResetNoHandleMark.                                   */ \
     1767   if (JvmtiExport::should_post_field_modification()) { \
     1768     jvalue field_value; \
     1769     field_value.unionType = value; \
     1770     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
     1771   } \
     1772   o->Fieldname##_field_put(offset, value); \
     1773   DTRACE_PROBE(hotspot_jni, Set##Result##Field__return);\
     1774 JNI_END
     1775 
     1776 DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z)
     1777 DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b)
     1778 DEFINE_SETFIELD(jchar,    char,   Char,    'C', c)
     1779 DEFINE_SETFIELD(jshort,   short,  Short,   'S', s)
     1780 DEFINE_SETFIELD(jint,     int,    Int,     'I', i)
     1781 DEFINE_SETFIELD(jlong,    long,   Long,    'J', j)
     1782 DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f)
     1783 DEFINE_SETFIELD(jdouble,  double, Double,  'D', d)
     1784 
     1785 DT_RETURN_MARK_DECL(ToReflectedField, jobject);
     1786 
     1787 JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
     1788   JNIWrapper("ToReflectedField");
     1789   DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry,
     1790                 env, cls, fieldID, isStatic);
     1791   jobject ret = NULL;
     1792   DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
     1793 
     1794   fieldDescriptor fd;
     1795   bool found = false;
     1796   klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
     1797 
     1798   assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");
     1799 
     1800   if (isStatic) {
     1801     // Static field. The fieldID a JNIid specifying the field holder and the offset within the klassOop.
     1802     JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
     1803     assert(id->is_static_field_id(), "invalid static field id");
     1804     found = instanceKlass::cast(id->holder())->find_local_field_from_offset(id->offset(), true, &fd);
     1805   } else {
     1806     // Non-static field. The fieldID is really the offset of the field within the instanceOop.
     1807     int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
     1808     found = instanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);
     1809   }
     1810   assert(found, "bad fieldID passed into jni_ToReflectedField");
     1811   oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);
     1812   ret = JNIHandles::make_local(env, reflected);
     1813   return ret;
     1814 JNI_END
     1815 
     1816 
     1817 //
     1818 // Accessing Static Fields
     1819 //
     1820 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);
     1821 
     1822 JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
     1823           const char *name, const char *sig))
     1824   JNIWrapper("GetStaticFieldID");
     1825   DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig);
     1826   jfieldID ret = NULL;
     1827   DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
     1828 
     1829   // The class should have been loaded (we have an instance of the class
     1830   // passed in) so the field and signature should already be in the symbol
     1831   // table.  If they're not there, the field doesn't exist.
     1832   symbolHandle fieldname =
     1833            symbolHandle(THREAD, SymbolTable::probe(name, (int)strlen(name)));
     1834   symbolHandle signame   =
     1835            symbolHandle(THREAD, SymbolTable::probe(sig, (int)strlen(sig)));
     1836   if (fieldname.is_null() || signame.is_null()) {
     1837     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
     1838   }
     1839   KlassHandle k(THREAD,
     1840                 java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
     1841   // Make sure class is initialized before handing id's out to static fields
     1842   Klass::cast(k())->initialize(CHECK_NULL);
     1843 
     1844   fieldDescriptor fd;
     1845   if (!Klass::cast(k())->oop_is_instance() ||
     1846       !instanceKlass::cast(k())->find_field(fieldname(), signame(), true, &fd)) {
     1847     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
     1848   }
     1849 
     1850   // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the klassOop
     1851   JNIid* id = instanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset());
     1852   debug_only(id->set_is_static_field_id();)
     1853 
     1854   debug_only(int first_offset = instanceKlass::cast(fd.field_holder())->offset_of_static_fields();)
     1855   debug_only(int end_offset = first_offset + (instanceKlass::cast(fd.field_holder())->static_field_size() * wordSize);)
     1856   assert(id->offset() >= first_offset && id->offset() < end_offset, "invalid static field offset");
     1857 
     1858   ret = jfieldIDWorkaround::to_static_jfieldID(id);
     1859   return ret;
     1860 JNI_END
     1861 
     1862 
     1863 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
     1864   JNIWrapper("GetStaticObjectField");
     1865   DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
     1866 #ifndef JNICHECK_KERNEL
     1867   DEBUG_ONLY(klassOop param_k = jniCheck::validate_class(thread, clazz);)
     1868 #endif // JNICHECK_KERNEL
     1869   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
     1870   assert(id->is_static_field_id(), "invalid static field id");
     1871   // Keep JVMTI addition small and only check enabled flag here.
     1872   // jni_GetField_probe() assumes that is okay to create handles.
     1873   if (JvmtiExport::should_post_field_access()) {
     1874     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
     1875   }
     1876   jobject ret = JNIHandles::make_local(id->holder()->obj_field(id->offset()));
     1877   DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
     1878   return ret;
     1879 JNI_END
     1880 
     1881 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
     1882 \
     1883   DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\
     1884 \
     1885 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
     1886   JNIWrapper("GetStatic" XSTR(Result) "Field"); \
     1887   DTRACE_PROBE3(hotspot_jni, GetStatic##Result##Field__entry, env, clazz, fieldID);\
     1888   Return ret = 0;\
     1889   DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
     1890                      (const Return&)ret);\
     1891   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
     1892   assert(id->is_static_field_id(), "invalid static field id"); \
     1893   /* Keep JVMTI addition small and only check enabled flag here. */ \
     1894   /* jni_GetField_probe() assumes that is okay to create handles. */ \
     1895   if (JvmtiExport::should_post_field_access()) { \
     1896     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
     1897   } \
     1898   ret = id->holder()-> Fieldname##_field (id->offset()); \
     1899   return ret;\
     1900 JNI_END
     1901 
     1902 DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean)
     1903 DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte)
     1904 DEFINE_GETSTATICFIELD(jchar,    char,   Char)
     1905 DEFINE_GETSTATICFIELD(jshort,   short,  Short)
     1906 DEFINE_GETSTATICFIELD(jint,     int,    Int)
     1907 DEFINE_GETSTATICFIELD(jlong,    long,   Long)
     1908 DEFINE_GETSTATICFIELD(jfloat,   float,  Float)
     1909 DEFINE_GETSTATICFIELD(jdouble,  double, Double)
     1910 
     1911 
     1912 JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
     1913   JNIWrapper("SetStaticObjectField");
     1914   DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value);
     1915   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
     1916   assert(id->is_static_field_id(), "invalid static field id");
     1917   // Keep JVMTI addition small and only check enabled flag here.
     1918   // jni_SetField_probe() assumes that is okay to create handles.
     1919   if (JvmtiExport::should_post_field_modification()) {
     1920     jvalue field_value;
     1921     field_value.l = value;
     1922     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);
     1923   }
     1924   id->holder()->obj_field_put(id->offset(), JNIHandles::resolve(value));
     1925   DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);
     1926 JNI_END
     1927 
     1928 
     1929 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \
     1930 \
     1931 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
     1932   JNIWrapper("SetStatic" XSTR(Result) "Field"); \
     1933   HS_DTRACE_PROBE_CDECL_N(hotspot_jni, SetStatic##Result##Field__entry,\
     1934     ( JNIEnv*, jclass, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \
     1935   HS_DTRACE_PROBE_N(hotspot_jni, SetStatic##Result##Field__entry, \
     1936     ( env, clazz, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \
     1937 \
     1938   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
     1939   assert(id->is_static_field_id(), "invalid static field id"); \
     1940   /* Keep JVMTI addition small and only check enabled flag here. */ \
     1941   /* jni_SetField_probe() assumes that is okay to create handles. */ \
     1942   if (JvmtiExport::should_post_field_modification()) { \
     1943     jvalue field_value; \
     1944     field_value.unionType = value; \
     1945     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
     1946   } \
     1947   id->holder()-> Fieldname##_field_put (id->offset(), value); \
     1948   DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\
     1949 JNI_END
     1950 
     1951 DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z)
     1952 DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b)
     1953 DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c)
     1954 DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s)
     1955 DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i)
     1956 DEFINE_SETSTATICFIELD(jlong,    long,   Long,    'J', j)
     1957 DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f)
     1958 DEFINE_SETSTATICFIELD(jdouble,  double, Double,  'D', d)
     1959 
     1960 
     1961 //
     1962 // String Operations
     1963 //
     1964 
     1965 // Unicode Interface
     1966 
     1967 DT_RETURN_MARK_DECL(NewString, jstring);
     1968 
     1969 JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
     1970   JNIWrapper("NewString");
     1971   DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len);
     1972   jstring ret = NULL;
     1973   DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
     1974   oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
     1975   ret = (jstring) JNIHandles::make_local(env, string);
     1976   return ret;
     1977 JNI_END
     1978 
     1979 
     1980 JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
     1981   JNIWrapper("GetStringLength");
     1982   DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string);
     1983   jsize ret = java_lang_String::length(JNIHandles::resolve_non_null(string));
     1984   DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
     1985   return ret;
     1986 JNI_END
     1987 
     1988 
     1989 JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
     1990   JNIEnv *env, jstring string, jboolean *isCopy))
     1991   JNIWrapper("GetStringChars");
     1992   DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy);
     1993   //%note jni_5
     1994   if (isCopy != NULL) {
     1995     *isCopy = JNI_TRUE;
     1996   }
     1997   oop s = JNIHandles::resolve_non_null(string);
     1998   int s_len = java_lang_String::length(s);
     1999   typeArrayOop s_value = java_lang_String::value(s);
     2000   int s_offset = java_lang_String::offset(s);
     2001   jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1);  // add one for zero termination
     2002   if (s_len > 0) {
     2003     memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
     2004   }
     2005   buf[s_len] = 0;
     2006   DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
     2007   return buf;
     2008 JNI_END
     2009 
     2010 
     2011 JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
     2012   JNIWrapper("ReleaseStringChars");
     2013   DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars);
     2014   //%note jni_6
     2015   if (chars != NULL) {
     2016     // Since String objects are supposed to be immutable, don't copy any
     2017     // new data back.  A bad user will have to go after the char array.
     2018     FreeHeap((void*) chars);
     2019   }
     2020   DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return);
     2021 JNI_END
     2022 
     2023 
     2024 // UTF Interface
     2025 
     2026 DT_RETURN_MARK_DECL(NewStringUTF, jstring);
     2027 
     2028 JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
     2029   JNIWrapper("NewStringUTF");
     2030   DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes);
     2031   jstring ret;
     2032   DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
     2033 
     2034   oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
     2035   ret = (jstring) JNIHandles::make_local(env, result);
     2036   return ret;
     2037 JNI_END
     2038 
     2039 
     2040 JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
     2041   JNIWrapper("GetStringUTFLength");
     2042   DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string);
     2043   jsize ret = java_lang_String::utf8_length(JNIHandles::resolve_non_null(string));
     2044   DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
     2045   return ret;
     2046 JNI_END
     2047 
     2048 
     2049 JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
     2050   JNIWrapper("GetStringUTFChars");
     2051   DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy);
     2052   ResourceMark rm;
     2053   char* str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(string));
     2054   int length = (int)strlen(str);
     2055   char* result = AllocateHeap(length+1, "GetStringUTFChars");
     2056   strcpy(result, str);
     2057   if (isCopy != NULL) *isCopy = JNI_TRUE;
     2058   DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
     2059   return result;
     2060 JNI_END
     2061 
     2062 
     2063 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
     2064   JNIWrapper("ReleaseStringUTFChars");
     2065   DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars);
     2066   if (chars != NULL) {
     2067     FreeHeap((char*) chars);
     2068   }
     2069   DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return);
     2070 JNI_END
     2071 
     2072 
     2073 JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
     2074   JNIWrapper("GetArrayLength");
     2075   DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array);
     2076   arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
     2077   assert(a->is_array(), "must be array");
     2078   jsize ret = a->length();
     2079   DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret);
     2080   return ret;
     2081 JNI_END
     2082 
     2083 
     2084 //
     2085 // Object Array Operations
     2086 //
     2087 
     2088 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);
     2089 
     2090 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
     2091   JNIWrapper("NewObjectArray");
     2092   DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement);
     2093   jobjectArray ret = NULL;
     2094   DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
     2095   KlassHandle ek(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(elementClass)));
     2096   klassOop ako = Klass::cast(ek())->array_klass(CHECK_NULL);
     2097   KlassHandle ak = KlassHandle(THREAD, ako);
     2098   objArrayKlass::cast(ak())->initialize(CHECK_NULL);
     2099   objArrayOop result = objArrayKlass::cast(ak())->allocate(length, CHECK_NULL);
     2100   oop initial_value = JNIHandles::resolve(initialElement);
     2101   if (initial_value != NULL) {  // array already initialized with NULL
     2102     for (int index = 0; index < length; index++) {
     2103       result->obj_at_put(index, initial_value);
     2104     }
     2105   }
     2106   ret = (jobjectArray) JNIHandles::make_local(env, result);
     2107   return ret;
     2108 JNI_END
     2109 
     2110 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);
     2111 
     2112 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
     2113   JNIWrapper("GetObjectArrayElement");
     2114   DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index);
     2115   jobject ret = NULL;
     2116   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
     2117   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
     2118   if (a->is_within_bounds(index)) {
     2119     jobject ret = JNIHandles::make_local(env, a->obj_at(index));
     2120     return ret;
     2121   } else {
     2122     char buf[jintAsStringSize];
     2123     sprintf(buf, "%d", index);
     2124     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
     2125   }
     2126 JNI_END
     2127 
     2128 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);
     2129 
     2130 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
     2131   JNIWrapper("SetObjectArrayElement");
     2132   DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value);
     2133   DT_VOID_RETURN_MARK(SetObjectArrayElement);
     2134 
     2135   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
     2136   oop v = JNIHandles::resolve(value);
     2137   if (a->is_within_bounds(index)) {
     2138     if (v == NULL || v->is_a(objArrayKlass::cast(a->klass())->element_klass())) {
     2139       a->obj_at_put(index, v);
     2140     } else {
     2141       THROW(vmSymbols::java_lang_ArrayStoreException());
     2142     }
     2143   } else {
     2144     char buf[jintAsStringSize];
     2145     sprintf(buf, "%d", index);
     2146     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
     2147   }
     2148 JNI_END
     2149 
     2150 
     2151 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \
     2152 \
     2153   DT_RETURN_MARK_DECL_FOR(Result, New##Result##Array, Return);\
     2154 \
     2155 JNI_ENTRY(Return, \
     2156           jni_New##Result##Array(JNIEnv *env, jsize len)) \
     2157   JNIWrapper("New" XSTR(Result) "Array"); \
     2158   DTRACE_PROBE2(hotspot_jni, New##Result##Array__entry, env, len);\
     2159   Return ret = NULL;\
     2160   DT_RETURN_MARK_FOR(Result, New##Result##Array, Return, (const Return&)ret);\
     2161 \
     2162   oop obj= oopFactory::Allocator(len, CHECK_0); \
     2163   ret = (Return) JNIHandles::make_local(env, obj); \
     2164   return ret;\
     2165 JNI_END
     2166 
     2167 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean)
     2168 DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte)
     2169 DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short)
     2170 DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char)
     2171 DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int)
     2172 DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long)
     2173 DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float)
     2174 DEFINE_NEWSCALARARRAY(jdoubleArray,  new_doubleArray, Double)
     2175 
     2176 
     2177 // Return an address which will fault if the caller writes to it.
     2178 
     2179 static char* get_bad_address() {
     2180   static char* bad_address = NULL;
     2181   if (bad_address == NULL) {
     2182     size_t size = os::vm_allocation_granularity();
     2183     bad_address = os::reserve_memory(size);
     2184     if (bad_address != NULL) {
     2185       os::protect_memory(bad_address, size, os::MEM_PROT_READ,
     2186                          /*is_committed*/false);
     2187     }
     2188   }
     2189   return bad_address;
     2190 }
     2191 
     2192 
     2193 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag) \
     2194 \
     2195 JNI_QUICK_ENTRY(ElementType*, \
     2196           jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
     2197   JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
     2198   DTRACE_PROBE3(hotspot_jni, Get##Result##ArrayElements__entry, env, array, isCopy);\
     2199   /* allocate an chunk of memory in c land */ \
     2200   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
     2201   ElementType* result; \
     2202   int len = a->length(); \
     2203   if (len == 0) { \
     2204     /* Empty array: legal but useless, can't return NULL. \
     2205      * Return a pointer to something useless. \
     2206      * Avoid asserts in typeArrayOop. */ \
     2207     result = (ElementType*)get_bad_address(); \
     2208   } else { \
     2209     result = NEW_C_HEAP_ARRAY(ElementType, len); \
     2210     /* copy the array to the c chunk */ \
     2211     memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
     2212   } \
     2213   if (isCopy) *isCopy = JNI_TRUE; \
     2214   DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\
     2215   return result; \
     2216 JNI_END
     2217 
     2218 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
     2219 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
     2220 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
     2221 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
     2222 DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
     2223 DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
     2224 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
     2225 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
     2226 
     2227 
     2228 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag) \
     2229 \
     2230 JNI_QUICK_ENTRY(void, \
     2231           jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
     2232                                              ElementType *buf, jint mode)) \
     2233   JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
     2234   DTRACE_PROBE4(hotspot_jni, Release##Result##ArrayElements__entry, env, array, buf, mode);\
     2235   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
     2236   int len = a->length(); \
     2237   if (len != 0) {   /* Empty array:  nothing to free or copy. */  \
     2238     if ((mode == 0) || (mode == JNI_COMMIT)) { \
     2239       memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
     2240     } \
     2241     if ((mode == 0) || (mode == JNI_ABORT)) { \
     2242       FreeHeap(buf); \
     2243     } \
     2244   } \
     2245   DTRACE_PROBE(hotspot_jni, Release##Result##ArrayElements__return);\
     2246 JNI_END
     2247 
     2248 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
     2249 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
     2250 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
     2251 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
     2252 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
     2253 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
     2254 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
     2255 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
     2256 
     2257 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
     2258   DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion);\
     2259 \
     2260 JNI_ENTRY(void, \
     2261 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
     2262              jsize len, ElementType *buf)) \
     2263   JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
     2264   DTRACE_PROBE5(hotspot_jni, Get##Result##ArrayRegion__entry, env, array, start, len, buf);\
     2265   DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
     2266   typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
     2267   if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
     2268     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
     2269   } else { \
     2270     if (len > 0) { \
     2271       int sc = typeArrayKlass::cast(src->klass())->log2_element_size(); \
     2272       memcpy((u_char*) buf, \
     2273              (u_char*) src->Tag##_at_addr(start), \
     2274              len << sc);                          \
     2275     } \
     2276   } \
     2277 JNI_END
     2278 
     2279 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool)
     2280 DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte)
     2281 DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short)
     2282 DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char)
     2283 DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int)
     2284 DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long)
     2285 DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float)
     2286 DEFINE_GETSCALARARRAYREGION(T_DOUBLE,  jdouble, Double,  double)
     2287 
     2288 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
     2289   DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion);\
     2290 \
     2291 JNI_ENTRY(void, \
     2292 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
     2293              jsize len, const ElementType *buf)) \
     2294   JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
     2295   DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\
     2296   DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
     2297   typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
     2298   if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
     2299     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
     2300   } else { \
     2301     if (len > 0) { \
     2302       int sc = typeArrayKlass::cast(dst->klass())->log2_element_size(); \
     2303       memcpy((u_char*) dst->Tag##_at_addr(start), \
     2304              (u_char*) buf, \
     2305              len << sc);    \
     2306     } \
     2307   } \
     2308 JNI_END
     2309 
     2310 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool)
     2311 DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte)
     2312 DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short)
     2313 DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char)
     2314 DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int)
     2315 DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long)
     2316 DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float)
     2317 DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double)
     2318 
     2319 
     2320 //
     2321 // Interception of natives
     2322 //
     2323 
     2324 // The RegisterNatives call being attempted tried to register with a method that
     2325 // is not native.  Ask JVM TI what prefixes have been specified.  Then check
     2326 // to see if the native method is now wrapped with the prefixes.  See the
     2327 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
     2328 static methodOop find_prefixed_native(KlassHandle k,
     2329                                       symbolHandle name, symbolHandle signature, TRAPS) {
     2330   ResourceMark rm(THREAD);
     2331   methodOop method;
     2332   int name_len = name->utf8_length();
     2333   char* name_str = name->as_utf8();
     2334   int prefix_count;
     2335   char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
     2336   for (int i = 0; i < prefix_count; i++) {
     2337     char* prefix = prefixes[i];
     2338     int prefix_len = (int)strlen(prefix);
     2339 
     2340     // try adding this prefix to the method name and see if it matches another method name
     2341     int trial_len = name_len + prefix_len;
     2342     char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
     2343     strcpy(trial_name_str, prefix);
     2344     strcat(trial_name_str, name_str);
     2345     symbolHandle trial_name(THREAD, SymbolTable::probe(trial_name_str, trial_len));
     2346     if (trial_name.is_null()) {
     2347       continue; // no such symbol, so this prefix wasn't used, try the next prefix
     2348     }
     2349     method = Klass::cast(k())->lookup_method(trial_name(), signature());
     2350     if (method == NULL) {
     2351       continue; // signature doesn't match, try the next prefix
     2352     }
     2353     if (method->is_native()) {
     2354       method->set_is_prefixed_native();
     2355       return method; // wahoo, we found a prefixed version of the method, return it
     2356     }
     2357     // found as non-native, so prefix is good, add it, probably just need more prefixes
     2358     name_len = trial_len;
     2359     name_str = trial_name_str;
     2360   }
     2361   return NULL; // not found
     2362 }
     2363 
     2364 static bool register_native(KlassHandle k, symbolHandle name, symbolHandle signature, address entry, TRAPS) {
     2365   methodOop method = Klass::cast(k())->lookup_method(name(), signature());
     2366   if (method == NULL) {
     2367     ResourceMark rm;
     2368     stringStream st;
     2369     st.print("Method %s name or signature does not match",
     2370              methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name(), signature()));
     2371     THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
     2372   }
     2373   if (!method->is_native()) {
     2374     // trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
     2375     method = find_prefixed_native(k, name, signature, THREAD);
     2376     if (method == NULL) {
     2377       ResourceMark rm;
     2378       stringStream st;
     2379       st.print("Method %s is not declared as native",
     2380                methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name(), signature()));
     2381       THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
     2382     }
     2383   }
     2384 
     2385   if (entry != NULL) {
     2386     method->set_native_function(entry,
     2387       methodOopDesc::native_bind_event_is_interesting);
     2388   } else {
     2389     method->clear_native_function();
     2390   }
     2391   if (PrintJNIResolving) {
     2392     ResourceMark rm(THREAD);
     2393     tty->print_cr("[Registering JNI native method %s.%s]",
     2394       Klass::cast(method->method_holder())->external_name(),
     2395       method->name()->as_C_string());
     2396   }
     2397   return true;
     2398 }
     2399 
     2400 DT_RETURN_MARK_DECL(RegisterNatives, jint);
     2401 
     2402 JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
     2403                                     const JNINativeMethod *methods,
     2404                                     jint nMethods))
     2405   JNIWrapper("RegisterNatives");
     2406   DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);
     2407   jint ret = 0;
     2408   DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
     2409 
     2410   KlassHandle h_k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
     2411 
     2412   for (int index = 0; index < nMethods; index++) {
     2413     const char* meth_name = methods[index].name;
     2414     const char* meth_sig = methods[index].signature;
     2415     int meth_name_len = (int)strlen(meth_name);
     2416 
     2417     // The class should have been loaded (we have an instance of the class
     2418     // passed in) so the method and signature should already be in the symbol
     2419     // table.  If they're not there, the method doesn't exist.
     2420     symbolHandle name(THREAD, SymbolTable::probe(meth_name, meth_name_len));
     2421     symbolHandle signature(THREAD, SymbolTable::probe(meth_sig, (int)strlen(meth_sig)));
     2422 
     2423     if (name.is_null() || signature.is_null()) {
     2424       ResourceMark rm;
     2425       stringStream st;
     2426       st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig);
     2427       // Must return negative value on failure
     2428       THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
     2429     }
     2430 
     2431     bool res = register_native(h_k, name, signature,
     2432                                (address) methods[index].fnPtr, THREAD);
     2433     if (!res) {
     2434       ret = -1;
     2435       break;
     2436     }
     2437   }
     2438   return ret;
     2439 JNI_END
     2440 
     2441 
     2442 JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
     2443   JNIWrapper("UnregisterNatives");
     2444   DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz);
     2445   klassOop k   = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz));
     2446   //%note jni_2
     2447   if (Klass::cast(k)->oop_is_instance()) {
     2448     for (int index = 0; index < instanceKlass::cast(k)->methods()->length(); index++) {
     2449       methodOop m = methodOop(instanceKlass::cast(k)->methods()->obj_at(index));
     2450       if (m->is_native()) {
     2451         m->clear_native_function();
     2452         m->set_signature_handler(NULL);
     2453       }
     2454     }
     2455   }
     2456   DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0);
     2457   return 0;
     2458 JNI_END
     2459 
     2460 //
     2461 // Monitor functions
     2462 //
     2463 
     2464 DT_RETURN_MARK_DECL(MonitorEnter, jint);
     2465 
     2466 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
     2467   DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj);
     2468   jint ret = JNI_ERR;
     2469   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
     2470 
     2471   // If the object is null, we can't do anything with it
     2472   if (jobj == NULL) {
     2473     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
     2474   }
     2475 
     2476   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
     2477   ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
     2478   ret = JNI_OK;
     2479   return ret;
     2480 JNI_END
     2481 
     2482 DT_RETURN_MARK_DECL(MonitorExit, jint);
     2483 
     2484 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
     2485   DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj);
     2486   jint ret = JNI_ERR;
     2487   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
     2488 
     2489   // Don't do anything with a null object
     2490   if (jobj == NULL) {
     2491     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
     2492   }
     2493 
     2494   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
     2495   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
     2496 
     2497   ret = JNI_OK;
     2498   return ret;
     2499 JNI_END
     2500 
     2501 //
     2502 // Extensions
     2503 //
     2504 
     2505 DT_VOID_RETURN_MARK_DECL(GetStringRegion);
     2506 
     2507 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
     2508   JNIWrapper("GetStringRegion");
     2509   DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf);
     2510   DT_VOID_RETURN_MARK(GetStringRegion);
     2511   oop s = JNIHandles::resolve_non_null(string);
     2512   int s_len = java_lang_String::length(s);
     2513   if (start < 0 || len < 0 || start + len > s_len) {
     2514     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
     2515   } else {
     2516     if (len > 0) {
     2517       int s_offset = java_lang_String::offset(s);
     2518       typeArrayOop s_value = java_lang_String::value(s);
     2519       memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
     2520     }
     2521   }
     2522 JNI_END
     2523 
     2524 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);
     2525 
     2526 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
     2527   JNIWrapper("GetStringUTFRegion");
     2528   DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf);
     2529   DT_VOID_RETURN_MARK(GetStringUTFRegion);
     2530   oop s = JNIHandles::resolve_non_null(string);
     2531   int s_len = java_lang_String::length(s);
     2532   if (start < 0 || len < 0 || start + len > s_len) {
     2533     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
     2534   } else {
     2535     //%note jni_7
     2536     if (len > 0) {
     2537       ResourceMark rm(THREAD);
     2538       char *utf_region = java_lang_String::as_utf8_string(s, start, len);
     2539       int utf_len = (int)strlen(utf_region);
     2540       memcpy(buf, utf_region, utf_len);
     2541       buf[utf_len] = 0;
     2542     } else {
     2543       // JDK null-terminates the buffer even in len is zero
     2544       if (buf != NULL) {
     2545         buf[0] = 0;
     2546       }
     2547     }
     2548   }
     2549 JNI_END
     2550 
     2551 
     2552 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
     2553   JNIWrapper("GetPrimitiveArrayCritical");
     2554   DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
     2555   GC_locker::lock_critical(thread);
     2556   if (isCopy != NULL) {
     2557     *isCopy = JNI_FALSE;
     2558   }
     2559   oop a = JNIHandles::resolve_non_null(array);
     2560   assert(a->is_array(), "just checking");
     2561   BasicType type;
     2562   if (a->is_objArray()) {
     2563     type = T_OBJECT;
     2564   } else {
     2565     type = typeArrayKlass::cast(a->klass())->element_type();
     2566   }
     2567   void* ret = arrayOop(a)->base(type);
     2568   DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
     2569   return ret;
     2570 JNI_END
     2571 
     2572 
     2573 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
     2574   JNIWrapper("ReleasePrimitiveArrayCritical");
     2575   DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
     2576   // The array, carray and mode arguments are ignored
     2577   GC_locker::unlock_critical(thread);
     2578   DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
     2579 JNI_END
     2580 
     2581 
     2582 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
     2583   JNIWrapper("GetStringCritical");
     2584   DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
     2585   GC_locker::lock_critical(thread);
     2586   if (isCopy != NULL) {
     2587     *isCopy = JNI_FALSE;
     2588   }
     2589   oop s = JNIHandles::resolve_non_null(string);
     2590   int s_len = java_lang_String::length(s);
     2591   typeArrayOop s_value = java_lang_String::value(s);
     2592   int s_offset = java_lang_String::offset(s);
     2593   const jchar* ret;
     2594   if (s_len > 0) {
     2595     ret = s_value->char_at_addr(s_offset);
     2596   } else {
     2597     ret = (jchar*) s_value->base(T_CHAR);
     2598   }
     2599   DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
     2600   return ret;
     2601 JNI_END
     2602 
     2603 
     2604 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
     2605   JNIWrapper("ReleaseStringCritical");
     2606   DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
     2607   // The str and chars arguments are ignored
     2608   GC_locker::unlock_critical(thread);
     2609   DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
     2610 JNI_END
     2611 
     2612 
     2613 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
     2614   JNIWrapper("jni_NewWeakGlobalRef");
     2615   DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
     2616   Handle ref_handle(thread, JNIHandles::resolve(ref));
     2617   jweak ret = JNIHandles::make_weak_global(ref_handle);
     2618   DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret);
     2619   return ret;
     2620 JNI_END
     2621 
     2622 // Must be JNI_ENTRY (with HandleMark)
     2623 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
     2624   JNIWrapper("jni_DeleteWeakGlobalRef");
     2625   DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref);
     2626   JNIHandles::destroy_weak_global(ref);
     2627   DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return);
     2628 JNI_END
     2629 
     2630 
     2631 JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
     2632   JNIWrapper("jni_ExceptionCheck");
     2633   DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env);
     2634   jni_check_async_exceptions(thread);
     2635   jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
     2636   DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret);
     2637   return ret;
     2638 JNI_END
     2639 
     2640 
     2641 // Initialization state for three routines below relating to
     2642 // java.nio.DirectBuffers
     2643 static          jint directBufferSupportInitializeStarted = 0;
     2644 static volatile jint directBufferSupportInitializeEnded   = 0;
     2645 static volatile jint directBufferSupportInitializeFailed  = 0;
     2646 static jclass    bufferClass                 = NULL;
     2647 static jclass    directBufferClass           = NULL;
     2648 static jclass    directByteBufferClass       = NULL;
     2649 static jmethodID directByteBufferConstructor = NULL;
     2650 static jfieldID  directBufferAddressField    = NULL;
     2651 static jfieldID  bufferCapacityField         = NULL;
     2652 
     2653 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
     2654   Handle loader;            // null (bootstrap) loader
     2655   Handle protection_domain; // null protection domain
     2656 
     2657   symbolHandle sym = oopFactory::new_symbol_handle(name, CHECK_NULL);
     2658   jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
     2659 
     2660   if (TraceClassResolution && result != NULL) {
     2661     trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
     2662   }
     2663   return result;
     2664 }
     2665 
     2666 // These lookups are done with the NULL (bootstrap) ClassLoader to
     2667 // circumvent any security checks that would be done by jni_FindClass.
     2668 JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env))
     2669 {
     2670   if ((bufferClass           = lookupOne(env, "java/nio/Buffer", thread))           == NULL) { return false; }
     2671   if ((directBufferClass     = lookupOne(env, "sun/nio/ch/DirectBuffer", thread))   == NULL) { return false; }
     2672   if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; }
     2673   return true;
     2674 }
     2675 JNI_END
     2676 
     2677 
     2678 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {
     2679   if (directBufferSupportInitializeFailed) {
     2680     return false;
     2681   }
     2682 
     2683   if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) {
     2684     if (!lookupDirectBufferClasses(env)) {
     2685       directBufferSupportInitializeFailed = 1;
     2686       return false;
     2687     }
     2688 
     2689     // Make global references for these
     2690     bufferClass           = (jclass) env->NewGlobalRef(bufferClass);
     2691     directBufferClass     = (jclass) env->NewGlobalRef(directBufferClass);
     2692     directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);
     2693 
     2694     // Get needed field and method IDs
     2695     directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");
     2696     directBufferAddressField    = env->GetFieldID(bufferClass, "address", "J");
     2697     bufferCapacityField         = env->GetFieldID(bufferClass, "capacity", "I");
     2698 
     2699     if ((directByteBufferConstructor == NULL) ||
     2700         (directBufferAddressField    == NULL) ||
     2701         (bufferCapacityField         == NULL)) {
     2702       directBufferSupportInitializeFailed = 1;
     2703       return false;
     2704     }
     2705 
     2706     directBufferSupportInitializeEnded = 1;
     2707   } else {
     2708     while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {
     2709       // Set state as yield_all can call os:sleep. On Solaris, yield_all calls
     2710       // os::sleep which requires the VM state transition. On other platforms, it
     2711       // is not necessary. The following call to change the VM state is purposely
     2712       // put inside the loop to avoid potential deadlock when multiple threads
     2713       // try to call this method. See 6791815 for more details.
     2714       ThreadInVMfromNative tivn(thread);
     2715       os::yield_all();
     2716     }
     2717   }
     2718 
     2719   return !directBufferSupportInitializeFailed;
     2720 }
     2721 
     2722 extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)
     2723 {
     2724   // thread_from_jni_environment() will block if VM is gone.
     2725   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
     2726 
     2727   JNIWrapper("jni_NewDirectByteBuffer");
     2728   DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity);
     2729 
     2730   if (!directBufferSupportInitializeEnded) {
     2731     if (!initializeDirectBufferSupport(env, thread)) {
     2732       DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, NULL);
     2733       return NULL;
     2734     }
     2735   }
     2736 
     2737   // Being paranoid about accidental sign extension on address
     2738   jlong addr = (jlong) ((uintptr_t) address);
     2739   // NOTE that package-private DirectByteBuffer constructor currently
     2740   // takes int capacity
     2741   jint  cap  = (jint)  capacity;
     2742   jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
     2743   DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret);
     2744   return ret;
     2745 }
     2746 
     2747 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);
     2748 
     2749 extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
     2750 {
     2751   // thread_from_jni_environment() will block if VM is gone.
     2752   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
     2753 
     2754   JNIWrapper("jni_GetDirectBufferAddress");
     2755   DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf);
     2756   void* ret = NULL;
     2757   DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
     2758 
     2759   if (!directBufferSupportInitializeEnded) {
     2760     if (!initializeDirectBufferSupport(env, thread)) {
     2761       return 0;
     2762     }
     2763   }
     2764 
     2765   if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {
     2766     return 0;
     2767   }
     2768 
     2769   ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);
     2770   return ret;
     2771 }
     2772 
     2773 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);
     2774 
     2775 extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
     2776 {
     2777   // thread_from_jni_environment() will block if VM is gone.
     2778   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
     2779 
     2780   JNIWrapper("jni_GetDirectBufferCapacity");
     2781   DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf);
     2782   jlong ret = -1;
     2783   DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
     2784 
     2785   if (!directBufferSupportInitializeEnded) {
     2786     if (!initializeDirectBufferSupport(env, thread)) {
     2787       ret = 0;
     2788       return ret;
     2789     }
     2790   }
     2791 
     2792   if (buf == NULL) {
     2793     return -1;
     2794   }
     2795 
     2796   if (!env->IsInstanceOf(buf, directBufferClass)) {
     2797     return -1;
     2798   }
     2799 
     2800   // NOTE that capacity is currently an int in the implementation
     2801   ret = env->GetIntField(buf, bufferCapacityField);
     2802   return ret;
     2803 }
     2804 
     2805 
     2806 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
     2807   JNIWrapper("GetVersion");
     2808   DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env);
     2809   DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion);
     2810   return CurrentVersion;
     2811 JNI_END
     2812 
     2813 extern struct JavaVM_ main_vm;
     2814 
     2815 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
     2816   JNIWrapper("jni_GetJavaVM");
     2817   DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm);
     2818   *vm  = (JavaVM *)(&main_vm);
     2819   DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK);
     2820   return JNI_OK;
     2821 JNI_END
     2822 
     2823 // Structure containing all jni functions
     2824 struct JNINativeInterface_ jni_NativeInterface = {
     2825     NULL,
     2826     NULL,
     2827     NULL,
     2828 
     2829     NULL,
     2830 
     2831     jni_GetVersion,
     2832 
     2833     jni_DefineClass,
     2834     jni_FindClass,
     2835 
     2836     jni_FromReflectedMethod,
     2837     jni_FromReflectedField,
     2838 
     2839     jni_ToReflectedMethod,
     2840 
     2841     jni_GetSuperclass,
     2842     jni_IsAssignableFrom,
     2843 
     2844     jni_ToReflectedField,
     2845 
     2846     jni_Throw,
     2847     jni_ThrowNew,
     2848     jni_ExceptionOccurred,
     2849     jni_ExceptionDescribe,
     2850     jni_ExceptionClear,
     2851     jni_FatalError,
     2852 
     2853     jni_PushLocalFrame,
     2854     jni_PopLocalFrame,
     2855 
     2856     jni_NewGlobalRef,
     2857     jni_DeleteGlobalRef,
     2858     jni_DeleteLocalRef,
     2859     jni_IsSameObject,
     2860 
     2861     jni_NewLocalRef,
     2862     jni_EnsureLocalCapacity,
     2863 
     2864     jni_AllocObject,
     2865     jni_NewObject,
     2866     jni_NewObjectV,
     2867     jni_NewObjectA,
     2868 
     2869     jni_GetObjectClass,
     2870     jni_IsInstanceOf,
     2871 
     2872     jni_GetMethodID,
     2873 
     2874     jni_CallObjectMethod,
     2875     jni_CallObjectMethodV,
     2876     jni_CallObjectMethodA,
     2877     jni_CallBooleanMethod,
     2878     jni_CallBooleanMethodV,
     2879     jni_CallBooleanMethodA,
     2880     jni_CallByteMethod,
     2881     jni_CallByteMethodV,
     2882     jni_CallByteMethodA,
     2883     jni_CallCharMethod,
     2884     jni_CallCharMethodV,
     2885     jni_CallCharMethodA,
     2886     jni_CallShortMethod,
     2887     jni_CallShortMethodV,
     2888     jni_CallShortMethodA,
     2889     jni_CallIntMethod,
     2890     jni_CallIntMethodV,
     2891     jni_CallIntMethodA,
     2892     jni_CallLongMethod,
     2893     jni_CallLongMethodV,
     2894     jni_CallLongMethodA,
     2895     jni_CallFloatMethod,
     2896     jni_CallFloatMethodV,
     2897     jni_CallFloatMethodA,
     2898     jni_CallDoubleMethod,
     2899     jni_CallDoubleMethodV,
     2900     jni_CallDoubleMethodA,
     2901     jni_CallVoidMethod,
     2902     jni_CallVoidMethodV,
     2903     jni_CallVoidMethodA,
     2904 
     2905     jni_CallNonvirtualObjectMethod,
     2906     jni_CallNonvirtualObjectMethodV,
     2907     jni_CallNonvirtualObjectMethodA,
     2908     jni_CallNonvirtualBooleanMethod,
     2909     jni_CallNonvirtualBooleanMethodV,
     2910     jni_CallNonvirtualBooleanMethodA,
     2911     jni_CallNonvirtualByteMethod,
     2912     jni_CallNonvirtualByteMethodV,
     2913     jni_CallNonvirtualByteMethodA,
     2914     jni_CallNonvirtualCharMethod,
     2915     jni_CallNonvirtualCharMethodV,
     2916     jni_CallNonvirtualCharMethodA,
     2917     jni_CallNonvirtualShortMethod,
     2918     jni_CallNonvirtualShortMethodV,
     2919     jni_CallNonvirtualShortMethodA,
     2920     jni_CallNonvirtualIntMethod,
     2921     jni_CallNonvirtualIntMethodV,
     2922     jni_CallNonvirtualIntMethodA,
     2923     jni_CallNonvirtualLongMethod,
     2924     jni_CallNonvirtualLongMethodV,
     2925     jni_CallNonvirtualLongMethodA,
     2926     jni_CallNonvirtualFloatMethod,
     2927     jni_CallNonvirtualFloatMethodV,
     2928     jni_CallNonvirtualFloatMethodA,
     2929     jni_CallNonvirtualDoubleMethod,
     2930     jni_CallNonvirtualDoubleMethodV,
     2931     jni_CallNonvirtualDoubleMethodA,
     2932     jni_CallNonvirtualVoidMethod,
     2933     jni_CallNonvirtualVoidMethodV,
     2934     jni_CallNonvirtualVoidMethodA,
     2935 
     2936     jni_GetFieldID,
     2937 
     2938     jni_GetObjectField,
     2939     jni_GetBooleanField,
     2940     jni_GetByteField,
     2941     jni_GetCharField,
     2942     jni_GetShortField,
     2943     jni_GetIntField,
     2944     jni_GetLongField,
     2945     jni_GetFloatField,
     2946     jni_GetDoubleField,
     2947 
     2948     jni_SetObjectField,
     2949     jni_SetBooleanField,
     2950     jni_SetByteField,
     2951     jni_SetCharField,
     2952     jni_SetShortField,
     2953     jni_SetIntField,
     2954     jni_SetLongField,
     2955     jni_SetFloatField,
     2956     jni_SetDoubleField,
     2957 
     2958     jni_GetStaticMethodID,
     2959 
     2960     jni_CallStaticObjectMethod,
     2961     jni_CallStaticObjectMethodV,
     2962     jni_CallStaticObjectMethodA,
     2963     jni_CallStaticBooleanMethod,
     2964     jni_CallStaticBooleanMethodV,
     2965     jni_CallStaticBooleanMethodA,
     2966     jni_CallStaticByteMethod,
     2967     jni_CallStaticByteMethodV,
     2968     jni_CallStaticByteMethodA,
     2969     jni_CallStaticCharMethod,
     2970     jni_CallStaticCharMethodV,
     2971     jni_CallStaticCharMethodA,
     2972     jni_CallStaticShortMethod,
     2973     jni_CallStaticShortMethodV,
     2974     jni_CallStaticShortMethodA,
     2975     jni_CallStaticIntMethod,
     2976     jni_CallStaticIntMethodV,
     2977     jni_CallStaticIntMethodA,
     2978     jni_CallStaticLongMethod,
     2979     jni_CallStaticLongMethodV,
     2980     jni_CallStaticLongMethodA,
     2981     jni_CallStaticFloatMethod,
     2982     jni_CallStaticFloatMethodV,
     2983     jni_CallStaticFloatMethodA,
     2984     jni_CallStaticDoubleMethod,
     2985     jni_CallStaticDoubleMethodV,
     2986     jni_CallStaticDoubleMethodA,
     2987     jni_CallStaticVoidMethod,
     2988     jni_CallStaticVoidMethodV,
     2989     jni_CallStaticVoidMethodA,
     2990 
     2991     jni_GetStaticFieldID,
     2992 
     2993     jni_GetStaticObjectField,
     2994     jni_GetStaticBooleanField,
     2995     jni_GetStaticByteField,
     2996     jni_GetStaticCharField,
     2997     jni_GetStaticShortField,
     2998     jni_GetStaticIntField,
     2999     jni_GetStaticLongField,
     3000     jni_GetStaticFloatField,
     3001     jni_GetStaticDoubleField,
     3002 
     3003     jni_SetStaticObjectField,
     3004     jni_SetStaticBooleanField,
     3005     jni_SetStaticByteField,
     3006     jni_SetStaticCharField,
     3007     jni_SetStaticShortField,
     3008     jni_SetStaticIntField,
     3009     jni_SetStaticLongField,
     3010     jni_SetStaticFloatField,
     3011     jni_SetStaticDoubleField,
     3012 
     3013     jni_NewString,
     3014     jni_GetStringLength,
     3015     jni_GetStringChars,
     3016     jni_ReleaseStringChars,
     3017 
     3018     jni_NewStringUTF,
     3019     jni_GetStringUTFLength,
     3020     jni_GetStringUTFChars,
     3021     jni_ReleaseStringUTFChars,
     3022 
     3023     jni_GetArrayLength,
     3024 
     3025     jni_NewObjectArray,
     3026     jni_GetObjectArrayElement,
     3027     jni_SetObjectArrayElement,
     3028 
     3029     jni_NewBooleanArray,
     3030     jni_NewByteArray,
     3031     jni_NewCharArray,
     3032     jni_NewShortArray,
     3033     jni_NewIntArray,
     3034     jni_NewLongArray,
     3035     jni_NewFloatArray,
     3036     jni_NewDoubleArray,
     3037 
     3038     jni_GetBooleanArrayElements,
     3039     jni_GetByteArrayElements,
     3040     jni_GetCharArrayElements,
     3041     jni_GetShortArrayElements,
     3042     jni_GetIntArrayElements,
     3043     jni_GetLongArrayElements,
     3044     jni_GetFloatArrayElements,
     3045     jni_GetDoubleArrayElements,
     3046 
     3047     jni_ReleaseBooleanArrayElements,
     3048     jni_ReleaseByteArrayElements,
     3049     jni_ReleaseCharArrayElements,
     3050     jni_ReleaseShortArrayElements,
     3051     jni_ReleaseIntArrayElements,
     3052     jni_ReleaseLongArrayElements,
     3053     jni_ReleaseFloatArrayElements,
     3054     jni_ReleaseDoubleArrayElements,
     3055 
     3056     jni_GetBooleanArrayRegion,
     3057     jni_GetByteArrayRegion,
     3058     jni_GetCharArrayRegion,
     3059     jni_GetShortArrayRegion,
     3060     jni_GetIntArrayRegion,
     3061     jni_GetLongArrayRegion,
     3062     jni_GetFloatArrayRegion,
     3063     jni_GetDoubleArrayRegion,
     3064 
<