src/share/vm/prims/jni.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/prims/jni.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,5638 @@
     1.4 +/*
     1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2012 Red Hat, Inc.
     1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8 + *
     1.9 + * This code is free software; you can redistribute it and/or modify it
    1.10 + * under the terms of the GNU General Public License version 2 only, as
    1.11 + * published by the Free Software Foundation.
    1.12 + *
    1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.16 + * version 2 for more details (a copy is included in the LICENSE file that
    1.17 + * accompanied this code).
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License version
    1.20 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.22 + *
    1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.24 + * or visit www.oracle.com if you need additional information or have any
    1.25 + * questions.
    1.26 + *
    1.27 + */
    1.28 +
    1.29 +#include "precompiled.hpp"
    1.30 +#include "ci/ciReplay.hpp"
    1.31 +#include "classfile/altHashing.hpp"
    1.32 +#include "classfile/classLoader.hpp"
    1.33 +#include "classfile/javaClasses.hpp"
    1.34 +#include "classfile/symbolTable.hpp"
    1.35 +#include "classfile/systemDictionary.hpp"
    1.36 +#include "classfile/vmSymbols.hpp"
    1.37 +#include "interpreter/linkResolver.hpp"
    1.38 +#include "utilities/macros.hpp"
    1.39 +#if INCLUDE_ALL_GCS
    1.40 +#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
    1.41 +#endif // INCLUDE_ALL_GCS
    1.42 +#include "memory/allocation.hpp"
    1.43 +#include "memory/allocation.inline.hpp"
    1.44 +#include "memory/gcLocker.inline.hpp"
    1.45 +#include "memory/oopFactory.hpp"
    1.46 +#include "memory/universe.inline.hpp"
    1.47 +#include "oops/instanceKlass.hpp"
    1.48 +#include "oops/instanceOop.hpp"
    1.49 +#include "oops/markOop.hpp"
    1.50 +#include "oops/method.hpp"
    1.51 +#include "oops/objArrayKlass.hpp"
    1.52 +#include "oops/objArrayOop.hpp"
    1.53 +#include "oops/oop.inline.hpp"
    1.54 +#include "oops/symbol.hpp"
    1.55 +#include "oops/typeArrayKlass.hpp"
    1.56 +#include "oops/typeArrayOop.hpp"
    1.57 +#include "prims/jni.h"
    1.58 +#include "prims/jniCheck.hpp"
    1.59 +#include "prims/jniExport.hpp"
    1.60 +#include "prims/jniFastGetField.hpp"
    1.61 +#include "prims/jvm.h"
    1.62 +#include "prims/jvm_misc.hpp"
    1.63 +#include "prims/jvmtiExport.hpp"
    1.64 +#include "prims/jvmtiThreadState.hpp"
    1.65 +#include "runtime/compilationPolicy.hpp"
    1.66 +#include "runtime/fieldDescriptor.hpp"
    1.67 +#include "runtime/fprofiler.hpp"
    1.68 +#include "runtime/handles.inline.hpp"
    1.69 +#include "runtime/interfaceSupport.hpp"
    1.70 +#include "runtime/java.hpp"
    1.71 +#include "runtime/javaCalls.hpp"
    1.72 +#include "runtime/jfieldIDWorkaround.hpp"
    1.73 +#include "runtime/reflection.hpp"
    1.74 +#include "runtime/sharedRuntime.hpp"
    1.75 +#include "runtime/signature.hpp"
    1.76 +#include "runtime/thread.inline.hpp"
    1.77 +#include "runtime/vm_operations.hpp"
    1.78 +#include "services/runtimeService.hpp"
    1.79 +#include "trace/tracing.hpp"
    1.80 +#include "utilities/defaultStream.hpp"
    1.81 +#include "utilities/dtrace.hpp"
    1.82 +#include "utilities/events.hpp"
    1.83 +#include "utilities/histogram.hpp"
    1.84 +#ifdef TARGET_OS_FAMILY_linux
    1.85 +# include "os_linux.inline.hpp"
    1.86 +#endif
    1.87 +#ifdef TARGET_OS_FAMILY_solaris
    1.88 +# include "os_solaris.inline.hpp"
    1.89 +#endif
    1.90 +#ifdef TARGET_OS_FAMILY_windows
    1.91 +# include "os_windows.inline.hpp"
    1.92 +#endif
    1.93 +#ifdef TARGET_OS_FAMILY_bsd
    1.94 +# include "os_bsd.inline.hpp"
    1.95 +#endif
    1.96 +
    1.97 +static jint CurrentVersion = JNI_VERSION_1_8;
    1.98 +
    1.99 +
   1.100 +// The DT_RETURN_MARK macros create a scoped object to fire the dtrace
   1.101 +// '-return' probe regardless of the return path is taken out of the function.
   1.102 +// Methods that have multiple return paths use this to avoid having to
   1.103 +// instrument each return path.  Methods that use CHECK or THROW must use this
   1.104 +// since those macros can cause an immedate uninstrumented return.
   1.105 +//
   1.106 +// In order to get the return value, a reference to the variable containing
   1.107 +// the return value must be passed to the contructor of the object, and
   1.108 +// the return value must be set before return (since the mark object has
   1.109 +// a reference to it).
   1.110 +//
   1.111 +// Example:
   1.112 +// DT_RETURN_MARK_DECL(SomeFunc, int);
   1.113 +// JNI_ENTRY(int, SomeFunc, ...)
   1.114 +//   int return_value = 0;
   1.115 +//   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
   1.116 +//   foo(CHECK_0)
   1.117 +//   return_value = 5;
   1.118 +//   return return_value;
   1.119 +// JNI_END
   1.120 +#ifndef USDT2
   1.121 +#define DT_RETURN_MARK_DECL(name, type)                                    \
   1.122 +  HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type);                \
   1.123 +  DTRACE_ONLY(                                                             \
   1.124 +    class DTraceReturnProbeMark_##name {                                   \
   1.125 +     public:                                                               \
   1.126 +      const type& _ret_ref;                                                \
   1.127 +      DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
   1.128 +      ~DTraceReturnProbeMark_##name() {                                    \
   1.129 +        HS_DTRACE_PROBE1(hotspot_jni, name##__return, _ret_ref);           \
   1.130 +      }                                                                    \
   1.131 +    }                                                                      \
   1.132 +  )
   1.133 +// Void functions are simpler since there's no return value
   1.134 +#define DT_VOID_RETURN_MARK_DECL(name)                                     \
   1.135 +  HS_DTRACE_PROBE_DECL0(hotspot_jni, name##__return);                      \
   1.136 +  DTRACE_ONLY(                                                             \
   1.137 +    class DTraceReturnProbeMark_##name {                                   \
   1.138 +     public:                                                               \
   1.139 +      ~DTraceReturnProbeMark_##name() {                                    \
   1.140 +        HS_DTRACE_PROBE0(hotspot_jni, name##__return);                     \
   1.141 +      }                                                                    \
   1.142 +    }                                                                      \
   1.143 +  )
   1.144 +
   1.145 +#else /* USDT2 */
   1.146 +
   1.147 +#define DT_RETURN_MARK_DECL(name, type, probe)                             \
   1.148 +  DTRACE_ONLY(                                                             \
   1.149 +    class DTraceReturnProbeMark_##name {                                   \
   1.150 +     public:                                                               \
   1.151 +      const type& _ret_ref;                                                \
   1.152 +      DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
   1.153 +      ~DTraceReturnProbeMark_##name() {                                    \
   1.154 +        probe;                                                             \
   1.155 +      }                                                                    \
   1.156 +    }                                                                      \
   1.157 +  )
   1.158 +// Void functions are simpler since there's no return value
   1.159 +#define DT_VOID_RETURN_MARK_DECL(name, probe)                              \
   1.160 +  DTRACE_ONLY(                                                             \
   1.161 +    class DTraceReturnProbeMark_##name {                                   \
   1.162 +     public:                                                               \
   1.163 +      ~DTraceReturnProbeMark_##name() {                                    \
   1.164 +        probe;                                                             \
   1.165 +      }                                                                    \
   1.166 +    }                                                                      \
   1.167 +  )
   1.168 +#endif /* USDT2 */
   1.169 +
   1.170 +// Place these macros in the function to mark the return.  Non-void
   1.171 +// functions need the type and address of the return value.
   1.172 +#define DT_RETURN_MARK(name, type, ref) \
   1.173 +  DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )
   1.174 +#define DT_VOID_RETURN_MARK(name) \
   1.175 +  DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )
   1.176 +
   1.177 +
   1.178 +// Use these to select distinct code for floating-point vs. non-floating point
   1.179 +// situations.  Used from within common macros where we need slightly
   1.180 +// different behavior for Float/Double
   1.181 +#define FP_SELECT_Boolean(intcode, fpcode) intcode
   1.182 +#define FP_SELECT_Byte(intcode, fpcode)    intcode
   1.183 +#define FP_SELECT_Char(intcode, fpcode)    intcode
   1.184 +#define FP_SELECT_Short(intcode, fpcode)   intcode
   1.185 +#define FP_SELECT_Object(intcode, fpcode)  intcode
   1.186 +#define FP_SELECT_Int(intcode, fpcode)     intcode
   1.187 +#define FP_SELECT_Long(intcode, fpcode)    intcode
   1.188 +#define FP_SELECT_Float(intcode, fpcode)   fpcode
   1.189 +#define FP_SELECT_Double(intcode, fpcode)  fpcode
   1.190 +#define FP_SELECT(TypeName, intcode, fpcode) \
   1.191 +  FP_SELECT_##TypeName(intcode, fpcode)
   1.192 +
   1.193 +#define COMMA ,
   1.194 +
   1.195 +// Choose DT_RETURN_MARK macros  based on the type: float/double -> void
   1.196 +// (dtrace doesn't do FP yet)
   1.197 +#ifndef USDT2
   1.198 +#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \
   1.199 +  FP_SELECT(TypeName, \
   1.200 +    DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) )
   1.201 +#else /* USDT2 */
   1.202 +#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe)    \
   1.203 +  FP_SELECT(TypeName, \
   1.204 +    DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
   1.205 +#endif /* USDT2 */
   1.206 +#define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
   1.207 +  FP_SELECT(TypeName, \
   1.208 +    DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
   1.209 +
   1.210 +
   1.211 +// out-of-line helpers for class jfieldIDWorkaround:
   1.212 +
   1.213 +bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {
   1.214 +  if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
   1.215 +    uintptr_t as_uint = (uintptr_t) id;
   1.216 +    intptr_t offset = raw_instance_offset(id);
   1.217 +    if (is_checked_jfieldID(id)) {
   1.218 +      if (!klass_hash_ok(k, id)) {
   1.219 +        return false;
   1.220 +      }
   1.221 +    }
   1.222 +    return InstanceKlass::cast(k)->contains_field_offset(offset);
   1.223 +  } else {
   1.224 +    JNIid* result = (JNIid*) id;
   1.225 +#ifdef ASSERT
   1.226 +    return result != NULL && result->is_static_field_id();
   1.227 +#else
   1.228 +    return result != NULL;
   1.229 +#endif
   1.230 +  }
   1.231 +}
   1.232 +
   1.233 +
   1.234 +intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {
   1.235 +  if (offset <= small_offset_mask) {
   1.236 +    Klass* field_klass = k;
   1.237 +    Klass* super_klass = field_klass->super();
   1.238 +    // With compressed oops the most super class with nonstatic fields would
   1.239 +    // be the owner of fields embedded in the header.
   1.240 +    while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&
   1.241 +           InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {
   1.242 +      field_klass = super_klass;   // super contains the field also
   1.243 +      super_klass = field_klass->super();
   1.244 +    }
   1.245 +    debug_only(No_Safepoint_Verifier nosafepoint;)
   1.246 +    uintptr_t klass_hash = field_klass->identity_hash();
   1.247 +    return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
   1.248 +  } else {
   1.249 +#if 0
   1.250 +    #ifndef PRODUCT
   1.251 +    {
   1.252 +      ResourceMark rm;
   1.253 +      warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());
   1.254 +    }
   1.255 +    #endif
   1.256 +#endif
   1.257 +    return 0;
   1.258 +  }
   1.259 +}
   1.260 +
   1.261 +bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {
   1.262 +  uintptr_t as_uint = (uintptr_t) id;
   1.263 +  intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
   1.264 +  do {
   1.265 +    debug_only(No_Safepoint_Verifier nosafepoint;)
   1.266 +    // Could use a non-blocking query for identity_hash here...
   1.267 +    if ((k->identity_hash() & klass_mask) == klass_hash)
   1.268 +      return true;
   1.269 +    k = k->super();
   1.270 +  } while (k != NULL);
   1.271 +  return false;
   1.272 +}
   1.273 +
   1.274 +void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {
   1.275 +  guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
   1.276 +  uintptr_t as_uint = (uintptr_t) id;
   1.277 +  intptr_t offset = raw_instance_offset(id);
   1.278 +  if (VerifyJNIFields) {
   1.279 +    if (is_checked_jfieldID(id)) {
   1.280 +      guarantee(klass_hash_ok(k, id),
   1.281 +    "Bug in native code: jfieldID class must match object");
   1.282 +    } else {
   1.283 +#if 0
   1.284 +      #ifndef PRODUCT
   1.285 +      if (Verbose) {
   1.286 +  ResourceMark rm;
   1.287 +  warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());
   1.288 +      }
   1.289 +      #endif
   1.290 +#endif
   1.291 +    }
   1.292 +  }
   1.293 +  guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),
   1.294 +      "Bug in native code: jfieldID offset must address interior of object");
   1.295 +}
   1.296 +
   1.297 +// Pick a reasonable higher bound for local capacity requested
   1.298 +// for EnsureLocalCapacity and PushLocalFrame.  We don't want it too
   1.299 +// high because a test (or very unusual application) may try to allocate
   1.300 +// that many handles and run out of swap space.  An implementation is
   1.301 +// permitted to allocate more handles than the ensured capacity, so this
   1.302 +// value is set high enough to prevent compatibility problems.
   1.303 +const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K;
   1.304 +
   1.305 +
   1.306 +// Wrapper to trace JNI functions
   1.307 +
   1.308 +#ifdef ASSERT
   1.309 +  Histogram* JNIHistogram;
   1.310 +  static volatile jint JNIHistogram_lock = 0;
   1.311 +
   1.312 +  class JNITraceWrapper : public StackObj {
   1.313 +   public:
   1.314 +    JNITraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {
   1.315 +      if (TraceJNICalls) {
   1.316 +        va_list ap;
   1.317 +        va_start(ap, format);
   1.318 +        tty->print("JNI ");
   1.319 +        tty->vprint_cr(format, ap);
   1.320 +        va_end(ap);
   1.321 +      }
   1.322 +    }
   1.323 +  };
   1.324 +
   1.325 +  class JNIHistogramElement : public HistogramElement {
   1.326 +    public:
   1.327 +     JNIHistogramElement(const char* name);
   1.328 +  };
   1.329 +
   1.330 +  JNIHistogramElement::JNIHistogramElement(const char* elementName) {
   1.331 +    _name = elementName;
   1.332 +    uintx count = 0;
   1.333 +
   1.334 +    while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) {
   1.335 +      while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) {
   1.336 +        count +=1;
   1.337 +        if ( (WarnOnStalledSpinLock > 0)
   1.338 +          && (count % WarnOnStalledSpinLock == 0)) {
   1.339 +          warning("JNIHistogram_lock seems to be stalled");
   1.340 +        }
   1.341 +      }
   1.342 +     }
   1.343 +
   1.344 +
   1.345 +    if(JNIHistogram == NULL)
   1.346 +      JNIHistogram = new Histogram("JNI Call Counts",100);
   1.347 +
   1.348 +    JNIHistogram->add_element(this);
   1.349 +    Atomic::dec(&JNIHistogram_lock);
   1.350 +  }
   1.351 +
   1.352 +  #define JNICountWrapper(arg)                                     \
   1.353 +     static JNIHistogramElement* e = new JNIHistogramElement(arg); \
   1.354 +      /* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \
   1.355 +     if (e != NULL) e->increment_count()
   1.356 +  #define JNIWrapper(arg) JNICountWrapper(arg); JNITraceWrapper(arg)
   1.357 +#else
   1.358 +  #define JNIWrapper(arg)
   1.359 +#endif
   1.360 +
   1.361 +
   1.362 +// Implementation of JNI entries
   1.363 +
   1.364 +#ifndef USDT2
   1.365 +DT_RETURN_MARK_DECL(DefineClass, jclass);
   1.366 +#else /* USDT2 */
   1.367 +DT_RETURN_MARK_DECL(DefineClass, jclass
   1.368 +                    , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));
   1.369 +#endif /* USDT2 */
   1.370 +
   1.371 +JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,
   1.372 +                                  const jbyte *buf, jsize bufLen))
   1.373 +  JNIWrapper("DefineClass");
   1.374 +
   1.375 +#ifndef USDT2
   1.376 +  DTRACE_PROBE5(hotspot_jni, DefineClass__entry,
   1.377 +    env, name, loaderRef, buf, bufLen);
   1.378 +#else /* USDT2 */
   1.379 +  HOTSPOT_JNI_DEFINECLASS_ENTRY(
   1.380 +    env, (char*) name, loaderRef, (char*) buf, bufLen);
   1.381 +#endif /* USDT2 */
   1.382 +  jclass cls = NULL;
   1.383 +  DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
   1.384 +
   1.385 +  TempNewSymbol class_name = NULL;
   1.386 +  // Since exceptions can be thrown, class initialization can take place
   1.387 +  // if name is NULL no check for class name in .class stream has to be made.
   1.388 +  if (name != NULL) {
   1.389 +    const int str_len = (int)strlen(name);
   1.390 +    if (str_len > Symbol::max_length()) {
   1.391 +      // It's impossible to create this class;  the name cannot fit
   1.392 +      // into the constant pool.
   1.393 +      THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
   1.394 +    }
   1.395 +    class_name = SymbolTable::new_symbol(name, CHECK_NULL);
   1.396 +  }
   1.397 +  ResourceMark rm(THREAD);
   1.398 +  ClassFileStream st((u1*) buf, bufLen, NULL);
   1.399 +  Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
   1.400 +
   1.401 +  if (UsePerfData && !class_loader.is_null()) {
   1.402 +    // check whether the current caller thread holds the lock or not.
   1.403 +    // If not, increment the corresponding counter
   1.404 +    if (ObjectSynchronizer::
   1.405 +        query_lock_ownership((JavaThread*)THREAD, class_loader) !=
   1.406 +        ObjectSynchronizer::owner_self) {
   1.407 +      ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
   1.408 +    }
   1.409 +  }
   1.410 +  Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,
   1.411 +                                                     Handle(), &st, true,
   1.412 +                                                     CHECK_NULL);
   1.413 +
   1.414 +  if (TraceClassResolution && k != NULL) {
   1.415 +    trace_class_resolution(k);
   1.416 +  }
   1.417 +
   1.418 +  cls = (jclass)JNIHandles::make_local(
   1.419 +    env, k->java_mirror());
   1.420 +  return cls;
   1.421 +JNI_END
   1.422 +
   1.423 +
   1.424 +
   1.425 +static bool first_time_FindClass = true;
   1.426 +
   1.427 +#ifndef USDT2
   1.428 +DT_RETURN_MARK_DECL(FindClass, jclass);
   1.429 +#else /* USDT2 */
   1.430 +DT_RETURN_MARK_DECL(FindClass, jclass
   1.431 +                    , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
   1.432 +#endif /* USDT2 */
   1.433 +
   1.434 +JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
   1.435 +  JNIWrapper("FindClass");
   1.436 +#ifndef USDT2
   1.437 +  DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);
   1.438 +#else /* USDT2 */
   1.439 +  HOTSPOT_JNI_FINDCLASS_ENTRY(
   1.440 +                              env, (char *)name);
   1.441 +#endif /* USDT2 */
   1.442 +
   1.443 +  jclass result = NULL;
   1.444 +  DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
   1.445 +
   1.446 +  // Remember if we are the first invocation of jni_FindClass
   1.447 +  bool first_time = first_time_FindClass;
   1.448 +  first_time_FindClass = false;
   1.449 +
   1.450 +  // Sanity check the name:  it cannot be null or larger than the maximum size
   1.451 +  // name we can fit in the constant pool.
   1.452 +  if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
   1.453 +    THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
   1.454 +  }
   1.455 +
   1.456 +  //%note jni_3
   1.457 +  Handle loader;
   1.458 +  Handle protection_domain;
   1.459 +  // Find calling class
   1.460 +  instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));
   1.461 +  if (k.not_null()) {
   1.462 +    loader = Handle(THREAD, k->class_loader());
   1.463 +    // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
   1.464 +    // in the correct class context.
   1.465 +    if (loader.is_null() &&
   1.466 +        k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
   1.467 +      JavaValue result(T_OBJECT);
   1.468 +      JavaCalls::call_static(&result, k,
   1.469 +                                      vmSymbols::getFromClass_name(),
   1.470 +                                      vmSymbols::void_class_signature(),
   1.471 +                                      thread);
   1.472 +      if (HAS_PENDING_EXCEPTION) {
   1.473 +        Handle ex(thread, thread->pending_exception());
   1.474 +        CLEAR_PENDING_EXCEPTION;
   1.475 +        THROW_HANDLE_0(ex);
   1.476 +      }
   1.477 +      oop mirror = (oop) result.get_jobject();
   1.478 +      loader = Handle(THREAD,
   1.479 +        InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->class_loader());
   1.480 +      protection_domain = Handle(THREAD,
   1.481 +        InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->protection_domain());
   1.482 +    }
   1.483 +  } else {
   1.484 +    // We call ClassLoader.getSystemClassLoader to obtain the system class loader.
   1.485 +    loader = Handle(THREAD, SystemDictionary::java_system_loader());
   1.486 +  }
   1.487 +
   1.488 +  TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
   1.489 +  result = find_class_from_class_loader(env, sym, true, loader,
   1.490 +                                        protection_domain, true, thread);
   1.491 +
   1.492 +  if (TraceClassResolution && result != NULL) {
   1.493 +    trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
   1.494 +  }
   1.495 +
   1.496 +  // If we were the first invocation of jni_FindClass, we enable compilation again
   1.497 +  // rather than just allowing invocation counter to overflow and decay.
   1.498 +  // Controlled by flag DelayCompilationDuringStartup.
   1.499 +  if (first_time && !CompileTheWorld)
   1.500 +    CompilationPolicy::completed_vm_startup();
   1.501 +
   1.502 +  return result;
   1.503 +JNI_END
   1.504 +
   1.505 +#ifndef USDT2
   1.506 +DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);
   1.507 +#else /* USDT2 */
   1.508 +DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
   1.509 +                    , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
   1.510 +#endif /* USDT2 */
   1.511 +
   1.512 +JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
   1.513 +  JNIWrapper("FromReflectedMethod");
   1.514 +#ifndef USDT2
   1.515 +  DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method);
   1.516 +#else /* USDT2 */
   1.517 +  HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(
   1.518 +                                        env, method);
   1.519 +#endif /* USDT2 */
   1.520 +  jmethodID ret = NULL;
   1.521 +  DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
   1.522 +
   1.523 +  // method is a handle to a java.lang.reflect.Method object
   1.524 +  oop reflected  = JNIHandles::resolve_non_null(method);
   1.525 +  oop mirror     = NULL;
   1.526 +  int slot       = 0;
   1.527 +
   1.528 +  if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {
   1.529 +    mirror = java_lang_reflect_Constructor::clazz(reflected);
   1.530 +    slot   = java_lang_reflect_Constructor::slot(reflected);
   1.531 +  } else {
   1.532 +    assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
   1.533 +    mirror = java_lang_reflect_Method::clazz(reflected);
   1.534 +    slot   = java_lang_reflect_Method::slot(reflected);
   1.535 +  }
   1.536 +  Klass* k     = java_lang_Class::as_Klass(mirror);
   1.537 +
   1.538 +  KlassHandle k1(THREAD, k);
   1.539 +  // Make sure class is initialized before handing id's out to methods
   1.540 +  k1()->initialize(CHECK_NULL);
   1.541 +  Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot);
   1.542 +  ret = m==NULL? NULL : m->jmethod_id();  // return NULL if reflected method deleted
   1.543 +  return ret;
   1.544 +JNI_END
   1.545 +
   1.546 +#ifndef USDT2
   1.547 +DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);
   1.548 +#else /* USDT2 */
   1.549 +DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
   1.550 +                    , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
   1.551 +#endif /* USDT2 */
   1.552 +
   1.553 +JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
   1.554 +  JNIWrapper("FromReflectedField");
   1.555 +#ifndef USDT2
   1.556 +  DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field);
   1.557 +#else /* USDT2 */
   1.558 +  HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(
   1.559 +                                       env, field);
   1.560 +#endif /* USDT2 */
   1.561 +  jfieldID ret = NULL;
   1.562 +  DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
   1.563 +
   1.564 +  // field is a handle to a java.lang.reflect.Field object
   1.565 +  oop reflected   = JNIHandles::resolve_non_null(field);
   1.566 +  oop mirror      = java_lang_reflect_Field::clazz(reflected);
   1.567 +  Klass* k      = java_lang_Class::as_Klass(mirror);
   1.568 +  int slot        = java_lang_reflect_Field::slot(reflected);
   1.569 +  int modifiers   = java_lang_reflect_Field::modifiers(reflected);
   1.570 +
   1.571 +  KlassHandle k1(THREAD, k);
   1.572 +  // Make sure class is initialized before handing id's out to fields
   1.573 +  k1()->initialize(CHECK_NULL);
   1.574 +
   1.575 +  // First check if this is a static field
   1.576 +  if (modifiers & JVM_ACC_STATIC) {
   1.577 +    intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
   1.578 +    JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset);
   1.579 +    assert(id != NULL, "corrupt Field object");
   1.580 +    debug_only(id->set_is_static_field_id();)
   1.581 +    // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
   1.582 +    ret = jfieldIDWorkaround::to_static_jfieldID(id);
   1.583 +    return ret;
   1.584 +  }
   1.585 +
   1.586 +  // The slot is the index of the field description in the field-array
   1.587 +  // The jfieldID is the offset of the field within the object
   1.588 +  // It may also have hash bits for k, if VerifyJNIFields is turned on.
   1.589 +  intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );
   1.590 +  assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
   1.591 +  ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);
   1.592 +  return ret;
   1.593 +JNI_END
   1.594 +
   1.595 +#ifndef USDT2
   1.596 +DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);
   1.597 +#else /* USDT2 */
   1.598 +DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
   1.599 +                    , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
   1.600 +#endif /* USDT2 */
   1.601 +
   1.602 +JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
   1.603 +  JNIWrapper("ToReflectedMethod");
   1.604 +#ifndef USDT2
   1.605 +  DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic);
   1.606 +#else /* USDT2 */
   1.607 +  HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(
   1.608 +                                      env, cls, (uintptr_t) method_id, isStatic);
   1.609 +#endif /* USDT2 */
   1.610 +  jobject ret = NULL;
   1.611 +  DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
   1.612 +
   1.613 +  methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));
   1.614 +  assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
   1.615 +  oop reflection_method;
   1.616 +  if (m->is_initializer()) {
   1.617 +    reflection_method = Reflection::new_constructor(m, CHECK_NULL);
   1.618 +  } else {
   1.619 +    reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL);
   1.620 +  }
   1.621 +  ret = JNIHandles::make_local(env, reflection_method);
   1.622 +  return ret;
   1.623 +JNI_END
   1.624 +
   1.625 +#ifndef USDT2
   1.626 +DT_RETURN_MARK_DECL(GetSuperclass, jclass);
   1.627 +#else /* USDT2 */
   1.628 +DT_RETURN_MARK_DECL(GetSuperclass, jclass
   1.629 +                    , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
   1.630 +#endif /* USDT2 */
   1.631 +
   1.632 +JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
   1.633 +  JNIWrapper("GetSuperclass");
   1.634 +#ifndef USDT2
   1.635 +  DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub);
   1.636 +#else /* USDT2 */
   1.637 +  HOTSPOT_JNI_GETSUPERCLASS_ENTRY(
   1.638 +                                  env, sub);
   1.639 +#endif /* USDT2 */
   1.640 +  jclass obj = NULL;
   1.641 +  DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
   1.642 +
   1.643 +  oop mirror = JNIHandles::resolve_non_null(sub);
   1.644 +  // primitive classes return NULL
   1.645 +  if (java_lang_Class::is_primitive(mirror)) return NULL;
   1.646 +
   1.647 +  // Rules of Class.getSuperClass as implemented by KLass::java_super:
   1.648 +  // arrays return Object
   1.649 +  // interfaces return NULL
   1.650 +  // proper classes return Klass::super()
   1.651 +  Klass* k = java_lang_Class::as_Klass(mirror);
   1.652 +  if (k->is_interface()) return NULL;
   1.653 +
   1.654 +  // return mirror for superclass
   1.655 +  Klass* super = k->java_super();
   1.656 +  // super2 is the value computed by the compiler's getSuperClass intrinsic:
   1.657 +  debug_only(Klass* super2 = ( k->oop_is_array()
   1.658 +                                 ? SystemDictionary::Object_klass()
   1.659 +                                 : k->super() ) );
   1.660 +  assert(super == super2,
   1.661 +         "java_super computation depends on interface, array, other super");
   1.662 +  obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());
   1.663 +  return obj;
   1.664 +JNI_END
   1.665 +
   1.666 +JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
   1.667 +  JNIWrapper("IsSubclassOf");
   1.668 +#ifndef USDT2
   1.669 +  DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super);
   1.670 +#else /* USDT2 */
   1.671 +  HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(
   1.672 +                                     env, sub, super);
   1.673 +#endif /* USDT2 */
   1.674 +  oop sub_mirror   = JNIHandles::resolve_non_null(sub);
   1.675 +  oop super_mirror = JNIHandles::resolve_non_null(super);
   1.676 +  if (java_lang_Class::is_primitive(sub_mirror) ||
   1.677 +      java_lang_Class::is_primitive(super_mirror)) {
   1.678 +    jboolean ret = (sub_mirror == super_mirror);
   1.679 +#ifndef USDT2
   1.680 +    DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
   1.681 +#else /* USDT2 */
   1.682 +    HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(
   1.683 +                                        ret);
   1.684 +#endif /* USDT2 */
   1.685 +    return ret;
   1.686 +  }
   1.687 +  Klass* sub_klass   = java_lang_Class::as_Klass(sub_mirror);
   1.688 +  Klass* super_klass = java_lang_Class::as_Klass(super_mirror);
   1.689 +  assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
   1.690 +  jboolean ret = sub_klass->is_subtype_of(super_klass) ?
   1.691 +                   JNI_TRUE : JNI_FALSE;
   1.692 +#ifndef USDT2
   1.693 +  DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
   1.694 +#else /* USDT2 */
   1.695 +  HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(
   1.696 +                                      ret);
   1.697 +#endif /* USDT2 */
   1.698 +  return ret;
   1.699 +JNI_END
   1.700 +
   1.701 +#ifndef USDT2
   1.702 +DT_RETURN_MARK_DECL(Throw, jint);
   1.703 +#else /* USDT2 */
   1.704 +DT_RETURN_MARK_DECL(Throw, jint
   1.705 +                    , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
   1.706 +#endif /* USDT2 */
   1.707 +
   1.708 +JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
   1.709 +  JNIWrapper("Throw");
   1.710 +#ifndef USDT2
   1.711 +  DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj);
   1.712 +#else /* USDT2 */
   1.713 +  HOTSPOT_JNI_THROW_ENTRY(
   1.714 + env, obj);
   1.715 +#endif /* USDT2 */
   1.716 +  jint ret = JNI_OK;
   1.717 +  DT_RETURN_MARK(Throw, jint, (const jint&)ret);
   1.718 +
   1.719 +  THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
   1.720 +  ShouldNotReachHere();
   1.721 +JNI_END
   1.722 +
   1.723 +#ifndef USDT2
   1.724 +DT_RETURN_MARK_DECL(ThrowNew, jint);
   1.725 +#else /* USDT2 */
   1.726 +DT_RETURN_MARK_DECL(ThrowNew, jint
   1.727 +                    , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
   1.728 +#endif /* USDT2 */
   1.729 +
   1.730 +JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
   1.731 +  JNIWrapper("ThrowNew");
   1.732 +#ifndef USDT2
   1.733 +  DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message);
   1.734 +#else /* USDT2 */
   1.735 +  HOTSPOT_JNI_THROWNEW_ENTRY(
   1.736 +                             env, clazz, (char *) message);
   1.737 +#endif /* USDT2 */
   1.738 +  jint ret = JNI_OK;
   1.739 +  DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
   1.740 +
   1.741 +  InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
   1.742 +  Symbol*  name = k->name();
   1.743 +  Handle class_loader (THREAD,  k->class_loader());
   1.744 +  Handle protection_domain (THREAD, k->protection_domain());
   1.745 +  THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);
   1.746 +  ShouldNotReachHere();
   1.747 +JNI_END
   1.748 +
   1.749 +
   1.750 +// JNI functions only transform a pending async exception to a synchronous
   1.751 +// exception in ExceptionOccurred and ExceptionCheck calls, since
   1.752 +// delivering an async exception in other places won't change the native
   1.753 +// code's control flow and would be harmful when native code further calls
   1.754 +// JNI functions with a pending exception. Async exception is also checked
   1.755 +// during the call, so ExceptionOccurred/ExceptionCheck won't return
   1.756 +// false but deliver the async exception at the very end during
   1.757 +// state transition.
   1.758 +
   1.759 +static void jni_check_async_exceptions(JavaThread *thread) {
   1.760 +  assert(thread == Thread::current(), "must be itself");
   1.761 +  thread->check_and_handle_async_exceptions();
   1.762 +}
   1.763 +
   1.764 +JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
   1.765 +  JNIWrapper("ExceptionOccurred");
   1.766 +#ifndef USDT2
   1.767 +  DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env);
   1.768 +#else /* USDT2 */
   1.769 +  HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(
   1.770 +                                      env);
   1.771 +#endif /* USDT2 */
   1.772 +  jni_check_async_exceptions(thread);
   1.773 +  oop exception = thread->pending_exception();
   1.774 +  jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
   1.775 +#ifndef USDT2
   1.776 +  DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret);
   1.777 +#else /* USDT2 */
   1.778 +  HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(
   1.779 +                                       ret);
   1.780 +#endif /* USDT2 */
   1.781 +  return ret;
   1.782 +JNI_END
   1.783 +
   1.784 +
   1.785 +JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
   1.786 +  JNIWrapper("ExceptionDescribe");
   1.787 +#ifndef USDT2
   1.788 +  DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env);
   1.789 +#else /* USDT2 */
   1.790 +  HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(
   1.791 +                                      env);
   1.792 +#endif /* USDT2 */
   1.793 +  if (thread->has_pending_exception()) {
   1.794 +    Handle ex(thread, thread->pending_exception());
   1.795 +    thread->clear_pending_exception();
   1.796 +    if (ex->is_a(SystemDictionary::ThreadDeath_klass())) {
   1.797 +      // Don't print anything if we are being killed.
   1.798 +    } else {
   1.799 +      jio_fprintf(defaultStream::error_stream(), "Exception ");
   1.800 +      if (thread != NULL && thread->threadObj() != NULL) {
   1.801 +        ResourceMark rm(THREAD);
   1.802 +        jio_fprintf(defaultStream::error_stream(),
   1.803 +        "in thread \"%s\" ", thread->get_thread_name());
   1.804 +      }
   1.805 +      if (ex->is_a(SystemDictionary::Throwable_klass())) {
   1.806 +        JavaValue result(T_VOID);
   1.807 +        JavaCalls::call_virtual(&result,
   1.808 +                                ex,
   1.809 +                                KlassHandle(THREAD,
   1.810 +                                  SystemDictionary::Throwable_klass()),
   1.811 +                                vmSymbols::printStackTrace_name(),
   1.812 +                                vmSymbols::void_method_signature(),
   1.813 +                                THREAD);
   1.814 +        // If an exception is thrown in the call it gets thrown away. Not much
   1.815 +        // we can do with it. The native code that calls this, does not check
   1.816 +        // for the exception - hence, it might still be in the thread when DestroyVM gets
   1.817 +        // called, potentially causing a few asserts to trigger - since no pending exception
   1.818 +        // is expected.
   1.819 +        CLEAR_PENDING_EXCEPTION;
   1.820 +      } else {
   1.821 +        ResourceMark rm(THREAD);
   1.822 +        jio_fprintf(defaultStream::error_stream(),
   1.823 +        ". Uncaught exception of type %s.",
   1.824 +        ex->klass()->external_name());
   1.825 +      }
   1.826 +    }
   1.827 +  }
   1.828 +#ifndef USDT2
   1.829 +  DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return);
   1.830 +#else /* USDT2 */
   1.831 +  HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN(
   1.832 +                                       );
   1.833 +#endif /* USDT2 */
   1.834 +JNI_END
   1.835 +
   1.836 +
   1.837 +JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env))
   1.838 +  JNIWrapper("ExceptionClear");
   1.839 +#ifndef USDT2
   1.840 +  DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env);
   1.841 +#else /* USDT2 */
   1.842 +  HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(
   1.843 +                                   env);
   1.844 +#endif /* USDT2 */
   1.845 +
   1.846 +  // The jni code might be using this API to clear java thrown exception.
   1.847 +  // So just mark jvmti thread exception state as exception caught.
   1.848 +  JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();
   1.849 +  if (state != NULL && state->is_exception_detected()) {
   1.850 +    state->set_exception_caught();
   1.851 +  }
   1.852 +  thread->clear_pending_exception();
   1.853 +#ifndef USDT2
   1.854 +  DTRACE_PROBE(hotspot_jni, ExceptionClear__return);
   1.855 +#else /* USDT2 */
   1.856 +  HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN(
   1.857 +                                    );
   1.858 +#endif /* USDT2 */
   1.859 +JNI_END
   1.860 +
   1.861 +
   1.862 +JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
   1.863 +  JNIWrapper("FatalError");
   1.864 +#ifndef USDT2
   1.865 +  DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);
   1.866 +#else /* USDT2 */
   1.867 +  HOTSPOT_JNI_FATALERROR_ENTRY(
   1.868 +                               env, (char *) msg);
   1.869 +#endif /* USDT2 */
   1.870 +  tty->print_cr("FATAL ERROR in native method: %s", msg);
   1.871 +  thread->print_stack();
   1.872 +  os::abort(); // Dump core and abort
   1.873 +JNI_END
   1.874 +
   1.875 +
   1.876 +JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
   1.877 +  JNIWrapper("PushLocalFrame");
   1.878 +#ifndef USDT2
   1.879 +  DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity);
   1.880 +#else /* USDT2 */
   1.881 +  HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(
   1.882 +                                   env, capacity);
   1.883 +#endif /* USDT2 */
   1.884 +  //%note jni_11
   1.885 +  if (capacity < 0 || capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
   1.886 +#ifndef USDT2
   1.887 +    DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
   1.888 +#else /* USDT2 */
   1.889 +    HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(
   1.890 +                                      (uint32_t)JNI_ERR);
   1.891 +#endif /* USDT2 */
   1.892 +    return JNI_ERR;
   1.893 +  }
   1.894 +  JNIHandleBlock* old_handles = thread->active_handles();
   1.895 +  JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
   1.896 +  assert(new_handles != NULL, "should not be NULL");
   1.897 +  new_handles->set_pop_frame_link(old_handles);
   1.898 +  thread->set_active_handles(new_handles);
   1.899 +  jint ret = JNI_OK;
   1.900 +#ifndef USDT2
   1.901 +  DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret);
   1.902 +#else /* USDT2 */
   1.903 +  HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(
   1.904 +                                    ret);
   1.905 +#endif /* USDT2 */
   1.906 +  return ret;
   1.907 +JNI_END
   1.908 +
   1.909 +
   1.910 +JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
   1.911 +  JNIWrapper("PopLocalFrame");
   1.912 +#ifndef USDT2
   1.913 +  DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result);
   1.914 +#else /* USDT2 */
   1.915 +  HOTSPOT_JNI_POPLOCALFRAME_ENTRY(
   1.916 +                                  env, result);
   1.917 +#endif /* USDT2 */
   1.918 +  //%note jni_11
   1.919 +  Handle result_handle(thread, JNIHandles::resolve(result));
   1.920 +  JNIHandleBlock* old_handles = thread->active_handles();
   1.921 +  JNIHandleBlock* new_handles = old_handles->pop_frame_link();
   1.922 +  if (new_handles != NULL) {
   1.923 +    // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.
   1.924 +    // This way code will still work if PopLocalFrame is called without a corresponding
   1.925 +    // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise
   1.926 +    // the release_block call will release the blocks.
   1.927 +    thread->set_active_handles(new_handles);
   1.928 +    old_handles->set_pop_frame_link(NULL);              // clear link we won't release new_handles below
   1.929 +    JNIHandleBlock::release_block(old_handles, thread); // may block
   1.930 +    result = JNIHandles::make_local(thread, result_handle());
   1.931 +  }
   1.932 +#ifndef USDT2
   1.933 +  DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result);
   1.934 +#else /* USDT2 */
   1.935 +  HOTSPOT_JNI_POPLOCALFRAME_RETURN(
   1.936 +                                   result);
   1.937 +#endif /* USDT2 */
   1.938 +  return result;
   1.939 +JNI_END
   1.940 +
   1.941 +
   1.942 +JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
   1.943 +  JNIWrapper("NewGlobalRef");
   1.944 +#ifndef USDT2
   1.945 +  DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref);
   1.946 +#else /* USDT2 */
   1.947 +  HOTSPOT_JNI_NEWGLOBALREF_ENTRY(
   1.948 +                                 env, ref);
   1.949 +#endif /* USDT2 */
   1.950 +  Handle ref_handle(thread, JNIHandles::resolve(ref));
   1.951 +  jobject ret = JNIHandles::make_global(ref_handle);
   1.952 +#ifndef USDT2
   1.953 +  DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret);
   1.954 +#else /* USDT2 */
   1.955 +  HOTSPOT_JNI_NEWGLOBALREF_RETURN(
   1.956 +                                  ret);
   1.957 +#endif /* USDT2 */
   1.958 +  return ret;
   1.959 +JNI_END
   1.960 +
   1.961 +// Must be JNI_ENTRY (with HandleMark)
   1.962 +JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
   1.963 +  JNIWrapper("DeleteGlobalRef");
   1.964 +#ifndef USDT2
   1.965 +  DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref);
   1.966 +#else /* USDT2 */
   1.967 +  HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(
   1.968 +                                    env, ref);
   1.969 +#endif /* USDT2 */
   1.970 +  JNIHandles::destroy_global(ref);
   1.971 +#ifndef USDT2
   1.972 +  DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return);
   1.973 +#else /* USDT2 */
   1.974 +  HOTSPOT_JNI_DELETEGLOBALREF_RETURN(
   1.975 +                                     );
   1.976 +#endif /* USDT2 */
   1.977 +JNI_END
   1.978 +
   1.979 +JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
   1.980 +  JNIWrapper("DeleteLocalRef");
   1.981 +#ifndef USDT2
   1.982 +  DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj);
   1.983 +#else /* USDT2 */
   1.984 +  HOTSPOT_JNI_DELETELOCALREF_ENTRY(
   1.985 +                                   env, obj);
   1.986 +#endif /* USDT2 */
   1.987 +  JNIHandles::destroy_local(obj);
   1.988 +#ifndef USDT2
   1.989 +  DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return);
   1.990 +#else /* USDT2 */
   1.991 +  HOTSPOT_JNI_DELETELOCALREF_RETURN(
   1.992 +                                    );
   1.993 +#endif /* USDT2 */
   1.994 +JNI_END
   1.995 +
   1.996 +JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
   1.997 +  JNIWrapper("IsSameObject");
   1.998 +#ifndef USDT2
   1.999 +  DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2);
  1.1000 +#else /* USDT2 */
  1.1001 +  HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(
  1.1002 +                                 env, r1, r2);
  1.1003 +#endif /* USDT2 */
  1.1004 +  oop a = JNIHandles::resolve(r1);
  1.1005 +  oop b = JNIHandles::resolve(r2);
  1.1006 +  jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
  1.1007 +#ifndef USDT2
  1.1008 +  DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret);
  1.1009 +#else /* USDT2 */
  1.1010 +  HOTSPOT_JNI_ISSAMEOBJECT_RETURN(
  1.1011 +                                  ret);
  1.1012 +#endif /* USDT2 */
  1.1013 +  return ret;
  1.1014 +JNI_END
  1.1015 +
  1.1016 +
  1.1017 +JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
  1.1018 +  JNIWrapper("NewLocalRef");
  1.1019 +#ifndef USDT2
  1.1020 +  DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref);
  1.1021 +#else /* USDT2 */
  1.1022 +  HOTSPOT_JNI_NEWLOCALREF_ENTRY(
  1.1023 +                                env, ref);
  1.1024 +#endif /* USDT2 */
  1.1025 +  jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
  1.1026 +#ifndef USDT2
  1.1027 +  DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret);
  1.1028 +#else /* USDT2 */
  1.1029 +  HOTSPOT_JNI_NEWLOCALREF_RETURN(
  1.1030 +                                 ret);
  1.1031 +#endif /* USDT2 */
  1.1032 +  return ret;
  1.1033 +JNI_END
  1.1034 +
  1.1035 +JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
  1.1036 +  JNIWrapper("EnsureLocalCapacity");
  1.1037 +#ifndef USDT2
  1.1038 +  DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity);
  1.1039 +#else /* USDT2 */
  1.1040 +  HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(
  1.1041 +                                        env, capacity);
  1.1042 +#endif /* USDT2 */
  1.1043 +  jint ret;
  1.1044 +  if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
  1.1045 +    ret = JNI_OK;
  1.1046 +  } else {
  1.1047 +    ret = JNI_ERR;
  1.1048 +  }
  1.1049 +#ifndef USDT2
  1.1050 +  DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret);
  1.1051 +#else /* USDT2 */
  1.1052 +  HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(
  1.1053 +                                         ret);
  1.1054 +#endif /* USDT2 */
  1.1055 +  return ret;
  1.1056 +JNI_END
  1.1057 +
  1.1058 +// Return the Handle Type
  1.1059 +JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
  1.1060 +  JNIWrapper("GetObjectRefType");
  1.1061 +#ifndef USDT2
  1.1062 +  DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj);
  1.1063 +#else /* USDT2 */
  1.1064 +  HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(
  1.1065 +                                     env, obj);
  1.1066 +#endif /* USDT2 */
  1.1067 +  jobjectRefType ret;
  1.1068 +  if (JNIHandles::is_local_handle(thread, obj) ||
  1.1069 +      JNIHandles::is_frame_handle(thread, obj))
  1.1070 +    ret = JNILocalRefType;
  1.1071 +  else if (JNIHandles::is_global_handle(obj))
  1.1072 +    ret = JNIGlobalRefType;
  1.1073 +  else if (JNIHandles::is_weak_global_handle(obj))
  1.1074 +    ret = JNIWeakGlobalRefType;
  1.1075 +  else
  1.1076 +    ret = JNIInvalidRefType;
  1.1077 +#ifndef USDT2
  1.1078 +  DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret);
  1.1079 +#else /* USDT2 */
  1.1080 +  HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN(
  1.1081 +                                      (void *) ret);
  1.1082 +#endif /* USDT2 */
  1.1083 +  return ret;
  1.1084 +JNI_END
  1.1085 +
  1.1086 +
  1.1087 +class JNI_ArgumentPusher : public SignatureIterator {
  1.1088 + protected:
  1.1089 +  JavaCallArguments*  _arguments;
  1.1090 +
  1.1091 +  virtual void get_bool   () = 0;
  1.1092 +  virtual void get_char   () = 0;
  1.1093 +  virtual void get_short  () = 0;
  1.1094 +  virtual void get_byte   () = 0;
  1.1095 +  virtual void get_int    () = 0;
  1.1096 +  virtual void get_long   () = 0;
  1.1097 +  virtual void get_float  () = 0;
  1.1098 +  virtual void get_double () = 0;
  1.1099 +  virtual void get_object () = 0;
  1.1100 +
  1.1101 +  JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {
  1.1102 +    this->_return_type = T_ILLEGAL;
  1.1103 +    _arguments = NULL;
  1.1104 +  }
  1.1105 +
  1.1106 + public:
  1.1107 +  virtual void iterate( uint64_t fingerprint ) = 0;
  1.1108 +
  1.1109 +  void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }
  1.1110 +
  1.1111 +  inline void do_bool()                     { if (!is_return_type()) get_bool();   }
  1.1112 +  inline void do_char()                     { if (!is_return_type()) get_char();   }
  1.1113 +  inline void do_short()                    { if (!is_return_type()) get_short();  }
  1.1114 +  inline void do_byte()                     { if (!is_return_type()) get_byte();   }
  1.1115 +  inline void do_int()                      { if (!is_return_type()) get_int();    }
  1.1116 +  inline void do_long()                     { if (!is_return_type()) get_long();   }
  1.1117 +  inline void do_float()                    { if (!is_return_type()) get_float();  }
  1.1118 +  inline void do_double()                   { if (!is_return_type()) get_double(); }
  1.1119 +  inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }
  1.1120 +  inline void do_array(int begin, int end)  { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array
  1.1121 +  inline void do_void()                     { }
  1.1122 +
  1.1123 +  JavaCallArguments* arguments()     { return _arguments; }
  1.1124 +  void push_receiver(Handle h)       { _arguments->push_oop(h); }
  1.1125 +};
  1.1126 +
  1.1127 +
  1.1128 +class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
  1.1129 + protected:
  1.1130 +  va_list _ap;
  1.1131 +
  1.1132 +  inline void get_bool()   { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg
  1.1133 +  inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
  1.1134 +  inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
  1.1135 +  inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
  1.1136 +  inline void get_int()    { _arguments->push_int(va_arg(_ap, jint)); }
  1.1137 +
  1.1138 +  // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
  1.1139 +
  1.1140 +  inline void get_long()   { _arguments->push_long(va_arg(_ap, jlong)); }
  1.1141 +  inline void get_float()  { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
  1.1142 +  inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
  1.1143 +  inline void get_object() { jobject l = va_arg(_ap, jobject);
  1.1144 +                             _arguments->push_oop(Handle((oop *)l, false)); }
  1.1145 +
  1.1146 +  inline void set_ap(va_list rap) {
  1.1147 +#ifdef va_copy
  1.1148 +    va_copy(_ap, rap);
  1.1149 +#elif defined (__va_copy)
  1.1150 +    __va_copy(_ap, rap);
  1.1151 +#else
  1.1152 +    _ap = rap;
  1.1153 +#endif
  1.1154 +  }
  1.1155 +
  1.1156 + public:
  1.1157 +  JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap)
  1.1158 +       : JNI_ArgumentPusher(signature) {
  1.1159 +    set_ap(rap);
  1.1160 +  }
  1.1161 +  JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
  1.1162 +      : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
  1.1163 +    set_ap(rap);
  1.1164 +  }
  1.1165 +
  1.1166 +  // Optimized path if we have the bitvector form of signature
  1.1167 +  void iterate( uint64_t fingerprint ) {
  1.1168 +    if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments
  1.1169 +    else {
  1.1170 +      _return_type = (BasicType)((fingerprint >> static_feature_size) &
  1.1171 +                                  result_feature_mask);
  1.1172 +
  1.1173 +      assert(fingerprint, "Fingerprint should not be 0");
  1.1174 +      fingerprint = fingerprint >> (static_feature_size + result_feature_size);
  1.1175 +      while ( 1 ) {
  1.1176 +        switch ( fingerprint & parameter_feature_mask ) {
  1.1177 +          case bool_parm:
  1.1178 +          case char_parm:
  1.1179 +          case short_parm:
  1.1180 +          case byte_parm:
  1.1181 +          case int_parm:
  1.1182 +            get_int();
  1.1183 +            break;
  1.1184 +          case obj_parm:
  1.1185 +            get_object();
  1.1186 +            break;
  1.1187 +          case long_parm:
  1.1188 +            get_long();
  1.1189 +            break;
  1.1190 +          case float_parm:
  1.1191 +            get_float();
  1.1192 +            break;
  1.1193 +          case double_parm:
  1.1194 +            get_double();
  1.1195 +            break;
  1.1196 +          case done_parm:
  1.1197 +            return;
  1.1198 +            break;
  1.1199 +          default:
  1.1200 +            ShouldNotReachHere();
  1.1201 +            break;
  1.1202 +        }
  1.1203 +        fingerprint >>= parameter_feature_size;
  1.1204 +      }
  1.1205 +    }
  1.1206 +  }
  1.1207 +};
  1.1208 +
  1.1209 +
  1.1210 +class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
  1.1211 + protected:
  1.1212 +  const jvalue *_ap;
  1.1213 +
  1.1214 +  inline void get_bool()   { _arguments->push_int((jint)(_ap++)->z); }
  1.1215 +  inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
  1.1216 +  inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
  1.1217 +  inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
  1.1218 +  inline void get_int()    { _arguments->push_int((jint)(_ap++)->i); }
  1.1219 +
  1.1220 +  inline void get_long()   { _arguments->push_long((_ap++)->j);  }
  1.1221 +  inline void get_float()  { _arguments->push_float((_ap++)->f); }
  1.1222 +  inline void get_double() { _arguments->push_double((_ap++)->d);}
  1.1223 +  inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); }
  1.1224 +
  1.1225 +  inline void set_ap(const jvalue *rap) { _ap = rap; }
  1.1226 +
  1.1227 + public:
  1.1228 +  JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap)
  1.1229 +       : JNI_ArgumentPusher(signature) {
  1.1230 +    set_ap(rap);
  1.1231 +  }
  1.1232 +  JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
  1.1233 +      : JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {
  1.1234 +    set_ap(rap);
  1.1235 +  }
  1.1236 +
  1.1237 +  // Optimized path if we have the bitvector form of signature
  1.1238 +  void iterate( uint64_t fingerprint ) {
  1.1239 +    if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments
  1.1240 +    else {
  1.1241 +      _return_type = (BasicType)((fingerprint >> static_feature_size) &
  1.1242 +                                  result_feature_mask);
  1.1243 +      assert(fingerprint, "Fingerprint should not be 0");
  1.1244 +      fingerprint = fingerprint >> (static_feature_size + result_feature_size);
  1.1245 +      while ( 1 ) {
  1.1246 +        switch ( fingerprint & parameter_feature_mask ) {
  1.1247 +          case bool_parm:
  1.1248 +            get_bool();
  1.1249 +            break;
  1.1250 +          case char_parm:
  1.1251 +            get_char();
  1.1252 +            break;
  1.1253 +          case short_parm:
  1.1254 +            get_short();
  1.1255 +            break;
  1.1256 +          case byte_parm:
  1.1257 +            get_byte();
  1.1258 +            break;
  1.1259 +          case int_parm:
  1.1260 +            get_int();
  1.1261 +            break;
  1.1262 +          case obj_parm:
  1.1263 +            get_object();
  1.1264 +            break;
  1.1265 +          case long_parm:
  1.1266 +            get_long();
  1.1267 +            break;
  1.1268 +          case float_parm:
  1.1269 +            get_float();
  1.1270 +            break;
  1.1271 +          case double_parm:
  1.1272 +            get_double();
  1.1273 +            break;
  1.1274 +          case done_parm:
  1.1275 +            return;
  1.1276 +            break;
  1.1277 +          default:
  1.1278 +            ShouldNotReachHere();
  1.1279 +            break;
  1.1280 +        }
  1.1281 +        fingerprint >>= parameter_feature_size;
  1.1282 +      }
  1.1283 +    }
  1.1284 +  }
  1.1285 +};
  1.1286 +
  1.1287 +
  1.1288 +enum JNICallType {
  1.1289 +  JNI_STATIC,
  1.1290 +  JNI_VIRTUAL,
  1.1291 +  JNI_NONVIRTUAL
  1.1292 +};
  1.1293 +
  1.1294 +
  1.1295 +
  1.1296 +static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
  1.1297 +  methodHandle method(THREAD, Method::resolve_jmethod_id(method_id));
  1.1298 +
  1.1299 +  // Create object to hold arguments for the JavaCall, and associate it with
  1.1300 +  // the jni parser
  1.1301 +  ResourceMark rm(THREAD);
  1.1302 +  int number_of_parameters = method->size_of_parameters();
  1.1303 +  JavaCallArguments java_args(number_of_parameters);
  1.1304 +  args->set_java_argument_object(&java_args);
  1.1305 +
  1.1306 +  assert(method->is_static(), "method should be static");
  1.1307 +
  1.1308 +  // Fill out JavaCallArguments object
  1.1309 +  args->iterate( Fingerprinter(method).fingerprint() );
  1.1310 +  // Initialize result type
  1.1311 +  result->set_type(args->get_ret_type());
  1.1312 +
  1.1313 +  // Invoke the method. Result is returned as oop.
  1.1314 +  JavaCalls::call(result, method, &java_args, CHECK);
  1.1315 +
  1.1316 +  // Convert result
  1.1317 +  if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
  1.1318 +    result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
  1.1319 +  }
  1.1320 +}
  1.1321 +
  1.1322 +
  1.1323 +static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
  1.1324 +  oop recv = JNIHandles::resolve(receiver);
  1.1325 +  if (recv == NULL) {
  1.1326 +    THROW(vmSymbols::java_lang_NullPointerException());
  1.1327 +  }
  1.1328 +  Handle h_recv(THREAD, recv);
  1.1329 +
  1.1330 +  int number_of_parameters;
  1.1331 +  Method* selected_method;
  1.1332 +  {
  1.1333 +    Method* m = Method::resolve_jmethod_id(method_id);
  1.1334 +    number_of_parameters = m->size_of_parameters();
  1.1335 +    Klass* holder = m->method_holder();
  1.1336 +    if (!(holder)->is_interface()) {
  1.1337 +      // non-interface call -- for that little speed boost, don't handlize
  1.1338 +      debug_only(No_Safepoint_Verifier nosafepoint;)
  1.1339 +      if (call_type == JNI_VIRTUAL) {
  1.1340 +        // jni_GetMethodID makes sure class is linked and initialized
  1.1341 +        // so m should have a valid vtable index.
  1.1342 +        assert(!m->has_itable_index(), "");
  1.1343 +        int vtbl_index = m->vtable_index();
  1.1344 +        if (vtbl_index != Method::nonvirtual_vtable_index) {
  1.1345 +          Klass* k = h_recv->klass();
  1.1346 +          // k might be an arrayKlassOop but all vtables start at
  1.1347 +          // the same place. The cast is to avoid virtual call and assertion.
  1.1348 +          InstanceKlass *ik = (InstanceKlass*)k;
  1.1349 +          selected_method = ik->method_at_vtable(vtbl_index);
  1.1350 +        } else {
  1.1351 +          // final method
  1.1352 +          selected_method = m;
  1.1353 +        }
  1.1354 +      } else {
  1.1355 +        // JNI_NONVIRTUAL call
  1.1356 +        selected_method = m;
  1.1357 +      }
  1.1358 +    } else {
  1.1359 +      // interface call
  1.1360 +      KlassHandle h_holder(THREAD, holder);
  1.1361 +
  1.1362 +      if (call_type == JNI_VIRTUAL) {
  1.1363 +        int itbl_index = m->itable_index();
  1.1364 +        Klass* k = h_recv->klass();
  1.1365 +        selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
  1.1366 +      } else {
  1.1367 +        selected_method = m;
  1.1368 +      }
  1.1369 +    }
  1.1370 +  }
  1.1371 +
  1.1372 +  methodHandle method(THREAD, selected_method);
  1.1373 +
  1.1374 +  // Create object to hold arguments for the JavaCall, and associate it with
  1.1375 +  // the jni parser
  1.1376 +  ResourceMark rm(THREAD);
  1.1377 +  JavaCallArguments java_args(number_of_parameters);
  1.1378 +  args->set_java_argument_object(&java_args);
  1.1379 +
  1.1380 +  // handle arguments
  1.1381 +  assert(!method->is_static(), "method should not be static");
  1.1382 +  args->push_receiver(h_recv); // Push jobject handle
  1.1383 +
  1.1384 +  // Fill out JavaCallArguments object
  1.1385 +  args->iterate( Fingerprinter(method).fingerprint() );
  1.1386 +  // Initialize result type
  1.1387 +  result->set_type(args->get_ret_type());
  1.1388 +
  1.1389 +  // Invoke the method. Result is returned as oop.
  1.1390 +  JavaCalls::call(result, method, &java_args, CHECK);
  1.1391 +
  1.1392 +  // Convert result
  1.1393 +  if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
  1.1394 +    result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
  1.1395 +  }
  1.1396 +}
  1.1397 +
  1.1398 +
  1.1399 +static instanceOop alloc_object(jclass clazz, TRAPS) {
  1.1400 +  KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
  1.1401 +  k()->check_valid_for_instantiation(false, CHECK_NULL);
  1.1402 +  InstanceKlass::cast(k())->initialize(CHECK_NULL);
  1.1403 +  instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD);
  1.1404 +  return ih;
  1.1405 +}
  1.1406 +
  1.1407 +#ifndef USDT2
  1.1408 +DT_RETURN_MARK_DECL(AllocObject, jobject);
  1.1409 +#else /* USDT2 */
  1.1410 +DT_RETURN_MARK_DECL(AllocObject, jobject
  1.1411 +                    , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
  1.1412 +#endif /* USDT2 */
  1.1413 +
  1.1414 +JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
  1.1415 +  JNIWrapper("AllocObject");
  1.1416 +
  1.1417 +#ifndef USDT2
  1.1418 +  DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz);
  1.1419 +#else /* USDT2 */
  1.1420 +  HOTSPOT_JNI_ALLOCOBJECT_ENTRY(
  1.1421 +                                env, clazz);
  1.1422 +#endif /* USDT2 */
  1.1423 +  jobject ret = NULL;
  1.1424 +  DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
  1.1425 +
  1.1426 +  instanceOop i = alloc_object(clazz, CHECK_NULL);
  1.1427 +  ret = JNIHandles::make_local(env, i);
  1.1428 +  return ret;
  1.1429 +JNI_END
  1.1430 +
  1.1431 +#ifndef USDT2
  1.1432 +DT_RETURN_MARK_DECL(NewObjectA, jobject);
  1.1433 +#else /* USDT2 */
  1.1434 +DT_RETURN_MARK_DECL(NewObjectA, jobject
  1.1435 +                    , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
  1.1436 +#endif /* USDT2 */
  1.1437 +
  1.1438 +JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
  1.1439 +  JNIWrapper("NewObjectA");
  1.1440 +#ifndef USDT2
  1.1441 +  DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID);
  1.1442 +#else /* USDT2 */
  1.1443 +  HOTSPOT_JNI_NEWOBJECTA_ENTRY(
  1.1444 +                               env, clazz, (uintptr_t) methodID);
  1.1445 +#endif /* USDT2 */
  1.1446 +  jobject obj = NULL;
  1.1447 +  DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
  1.1448 +
  1.1449 +  instanceOop i = alloc_object(clazz, CHECK_NULL);
  1.1450 +  obj = JNIHandles::make_local(env, i);
  1.1451 +  JavaValue jvalue(T_VOID);
  1.1452 +  JNI_ArgumentPusherArray ap(methodID, args);
  1.1453 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
  1.1454 +  return obj;
  1.1455 +JNI_END
  1.1456 +
  1.1457 +#ifndef USDT2
  1.1458 +DT_RETURN_MARK_DECL(NewObjectV, jobject);
  1.1459 +#else /* USDT2 */
  1.1460 +DT_RETURN_MARK_DECL(NewObjectV, jobject
  1.1461 +                    , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
  1.1462 +#endif /* USDT2 */
  1.1463 +
  1.1464 +JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
  1.1465 +  JNIWrapper("NewObjectV");
  1.1466 +#ifndef USDT2
  1.1467 +  DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID);
  1.1468 +#else /* USDT2 */
  1.1469 +  HOTSPOT_JNI_NEWOBJECTV_ENTRY(
  1.1470 +                               env, clazz, (uintptr_t) methodID);
  1.1471 +#endif /* USDT2 */
  1.1472 +  jobject obj = NULL;
  1.1473 +  DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
  1.1474 +
  1.1475 +  instanceOop i = alloc_object(clazz, CHECK_NULL);
  1.1476 +  obj = JNIHandles::make_local(env, i);
  1.1477 +  JavaValue jvalue(T_VOID);
  1.1478 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.1479 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
  1.1480 +  return obj;
  1.1481 +JNI_END
  1.1482 +
  1.1483 +#ifndef USDT2
  1.1484 +DT_RETURN_MARK_DECL(NewObject, jobject);
  1.1485 +#else /* USDT2 */
  1.1486 +DT_RETURN_MARK_DECL(NewObject, jobject
  1.1487 +                    , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
  1.1488 +#endif /* USDT2 */
  1.1489 +
  1.1490 +JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
  1.1491 +  JNIWrapper("NewObject");
  1.1492 +#ifndef USDT2
  1.1493 +  DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID);
  1.1494 +#else /* USDT2 */
  1.1495 +  HOTSPOT_JNI_NEWOBJECT_ENTRY(
  1.1496 +                              env, clazz, (uintptr_t) methodID);
  1.1497 +#endif /* USDT2 */
  1.1498 +  jobject obj = NULL;
  1.1499 +  DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
  1.1500 +
  1.1501 +  instanceOop i = alloc_object(clazz, CHECK_NULL);
  1.1502 +  obj = JNIHandles::make_local(env, i);
  1.1503 +  va_list args;
  1.1504 +  va_start(args, methodID);
  1.1505 +  JavaValue jvalue(T_VOID);
  1.1506 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.1507 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
  1.1508 +  va_end(args);
  1.1509 +  return obj;
  1.1510 +JNI_END
  1.1511 +
  1.1512 +
  1.1513 +JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
  1.1514 +  JNIWrapper("GetObjectClass");
  1.1515 +#ifndef USDT2
  1.1516 +  DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj);
  1.1517 +#else /* USDT2 */
  1.1518 +  HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(
  1.1519 +                                   env, obj);
  1.1520 +#endif /* USDT2 */
  1.1521 +  Klass* k = JNIHandles::resolve_non_null(obj)->klass();
  1.1522 +  jclass ret =
  1.1523 +    (jclass) JNIHandles::make_local(env, k->java_mirror());
  1.1524 +#ifndef USDT2
  1.1525 +  DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);
  1.1526 +#else /* USDT2 */
  1.1527 +  HOTSPOT_JNI_GETOBJECTCLASS_RETURN(
  1.1528 +                                    ret);
  1.1529 +#endif /* USDT2 */
  1.1530 +  return ret;
  1.1531 +JNI_END
  1.1532 +
  1.1533 +JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
  1.1534 +  JNIWrapper("IsInstanceOf");
  1.1535 +#ifndef USDT2
  1.1536 +  DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz);
  1.1537 +#else /* USDT2 */
  1.1538 +  HOTSPOT_JNI_ISINSTANCEOF_ENTRY(
  1.1539 +                                 env, obj, clazz);
  1.1540 +#endif /* USDT2 */
  1.1541 +  jboolean ret = JNI_TRUE;
  1.1542 +  if (obj != NULL) {
  1.1543 +    ret = JNI_FALSE;
  1.1544 +    Klass* k = java_lang_Class::as_Klass(
  1.1545 +      JNIHandles::resolve_non_null(clazz));
  1.1546 +    if (k != NULL) {
  1.1547 +      ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
  1.1548 +    }
  1.1549 +  }
  1.1550 +#ifndef USDT2
  1.1551 +  DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret);
  1.1552 +#else /* USDT2 */
  1.1553 +  HOTSPOT_JNI_ISINSTANCEOF_RETURN(
  1.1554 +                                  ret);
  1.1555 +#endif /* USDT2 */
  1.1556 +  return ret;
  1.1557 +JNI_END
  1.1558 +
  1.1559 +
  1.1560 +static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
  1.1561 +                               const char *sig, bool is_static, TRAPS) {
  1.1562 +  // %%%% This code should probably just call into a method in the LinkResolver
  1.1563 +  //
  1.1564 +  // The class should have been loaded (we have an instance of the class
  1.1565 +  // passed in) so the method and signature should already be in the symbol
  1.1566 +  // table.  If they're not there, the method doesn't exist.
  1.1567 +  const char *name_to_probe = (name_str == NULL)
  1.1568 +                        ? vmSymbols::object_initializer_name()->as_C_string()
  1.1569 +                        : name_str;
  1.1570 +  TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe));
  1.1571 +  TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig));
  1.1572 +
  1.1573 +  if (name == NULL || signature == NULL) {
  1.1574 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
  1.1575 +  }
  1.1576 +
  1.1577 +  // Throw a NoSuchMethodError exception if we have an instance of a
  1.1578 +  // primitive java.lang.Class
  1.1579 +  if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
  1.1580 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
  1.1581 +  }
  1.1582 +
  1.1583 +  KlassHandle klass(THREAD,
  1.1584 +               java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
  1.1585 +
  1.1586 +  // Make sure class is linked and initialized before handing id's out to
  1.1587 +  // Method*s.
  1.1588 +  klass()->initialize(CHECK_NULL);
  1.1589 +
  1.1590 +  Method* m;
  1.1591 +  if (name == vmSymbols::object_initializer_name() ||
  1.1592 +      name == vmSymbols::class_initializer_name()) {
  1.1593 +    // Never search superclasses for constructors
  1.1594 +    if (klass->oop_is_instance()) {
  1.1595 +      m = InstanceKlass::cast(klass())->find_method(name, signature);
  1.1596 +    } else {
  1.1597 +      m = NULL;
  1.1598 +    }
  1.1599 +  } else {
  1.1600 +    m = klass->lookup_method(name, signature);
  1.1601 +    if (m == NULL &&  klass->oop_is_instance()) {
  1.1602 +      m = InstanceKlass::cast(klass())->lookup_method_in_ordered_interfaces(name, signature);
  1.1603 +    }
  1.1604 +  }
  1.1605 +  if (m == NULL || (m->is_static() != is_static)) {
  1.1606 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
  1.1607 +  }
  1.1608 +  return m->jmethod_id();
  1.1609 +}
  1.1610 +
  1.1611 +
  1.1612 +JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
  1.1613 +          const char *name, const char *sig))
  1.1614 +  JNIWrapper("GetMethodID");
  1.1615 +#ifndef USDT2
  1.1616 +  DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig);
  1.1617 +#else /* USDT2 */
  1.1618 +  HOTSPOT_JNI_GETMETHODID_ENTRY(
  1.1619 +                                env, clazz, (char *) name, (char *) sig);
  1.1620 +#endif /* USDT2 */
  1.1621 +  jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
  1.1622 +#ifndef USDT2
  1.1623 +  DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret);
  1.1624 +#else /* USDT2 */
  1.1625 +  HOTSPOT_JNI_GETMETHODID_RETURN(
  1.1626 +                                 (uintptr_t) ret);
  1.1627 +#endif /* USDT2 */
  1.1628 +  return ret;
  1.1629 +JNI_END
  1.1630 +
  1.1631 +
  1.1632 +JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
  1.1633 +          const char *name, const char *sig))
  1.1634 +  JNIWrapper("GetStaticMethodID");
  1.1635 +#ifndef USDT2
  1.1636 +  DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig);
  1.1637 +#else /* USDT2 */
  1.1638 +  HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(
  1.1639 +                                      env, (char *) clazz, (char *) name, (char *)sig);
  1.1640 +#endif /* USDT2 */
  1.1641 +  jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
  1.1642 +#ifndef USDT2
  1.1643 +  DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret);
  1.1644 +#else /* USDT2 */
  1.1645 +  HOTSPOT_JNI_GETSTATICMETHODID_RETURN(
  1.1646 +                                       (uintptr_t) ret);
  1.1647 +#endif /* USDT2 */
  1.1648 +  return ret;
  1.1649 +JNI_END
  1.1650 +
  1.1651 +
  1.1652 +
  1.1653 +//
  1.1654 +// Calling Methods
  1.1655 +//
  1.1656 +
  1.1657 +#ifndef USDT2
  1.1658 +#define DEFINE_CALLMETHOD(ResultType, Result, Tag) \
  1.1659 +\
  1.1660 +  DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\
  1.1661 +  DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType);\
  1.1662 +  DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType);\
  1.1663 +\
  1.1664 +JNI_ENTRY(ResultType, \
  1.1665 +          jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
  1.1666 +  JNIWrapper("Call" XSTR(Result) "Method"); \
  1.1667 +\
  1.1668 +  DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID); \
  1.1669 +  ResultType ret = 0;\
  1.1670 +  DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
  1.1671 +                     (const ResultType&)ret);\
  1.1672 +\
  1.1673 +  va_list args; \
  1.1674 +  va_start(args, methodID); \
  1.1675 +  JavaValue jvalue(Tag); \
  1.1676 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.1677 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
  1.1678 +  va_end(args); \
  1.1679 +  ret = jvalue.get_##ResultType(); \
  1.1680 +  return ret;\
  1.1681 +JNI_END \
  1.1682 +\
  1.1683 +\
  1.1684 +JNI_ENTRY(ResultType, \
  1.1685 +          jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
  1.1686 +  JNIWrapper("Call" XSTR(Result) "MethodV"); \
  1.1687 +\
  1.1688 +  DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID); \
  1.1689 +  ResultType ret = 0;\
  1.1690 +  DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
  1.1691 +                     (const ResultType&)ret);\
  1.1692 +\
  1.1693 +  JavaValue jvalue(Tag); \
  1.1694 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.1695 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
  1.1696 +  ret = jvalue.get_##ResultType(); \
  1.1697 +  return ret;\
  1.1698 +JNI_END \
  1.1699 +\
  1.1700 +\
  1.1701 +JNI_ENTRY(ResultType, \
  1.1702 +          jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
  1.1703 +  JNIWrapper("Call" XSTR(Result) "MethodA"); \
  1.1704 +  DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID); \
  1.1705 +  ResultType ret = 0;\
  1.1706 +  DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
  1.1707 +                     (const ResultType&)ret);\
  1.1708 +\
  1.1709 +  JavaValue jvalue(Tag); \
  1.1710 +  JNI_ArgumentPusherArray ap(methodID, args); \
  1.1711 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
  1.1712 +  ret = jvalue.get_##ResultType(); \
  1.1713 +  return ret;\
  1.1714 +JNI_END
  1.1715 +
  1.1716 +// the runtime type of subword integral basic types is integer
  1.1717 +DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN)
  1.1718 +DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE)
  1.1719 +DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR)
  1.1720 +DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT)
  1.1721 +
  1.1722 +DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT)
  1.1723 +DEFINE_CALLMETHOD(jint,     Int,     T_INT)
  1.1724 +DEFINE_CALLMETHOD(jlong,    Long,    T_LONG)
  1.1725 +DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT)
  1.1726 +DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE)
  1.1727 +
  1.1728 +DT_VOID_RETURN_MARK_DECL(CallVoidMethod);
  1.1729 +DT_VOID_RETURN_MARK_DECL(CallVoidMethodV);
  1.1730 +DT_VOID_RETURN_MARK_DECL(CallVoidMethodA);
  1.1731 +
  1.1732 +#else /* USDT2 */
  1.1733 +
  1.1734 +#define DEFINE_CALLMETHOD(ResultType, Result, Tag \
  1.1735 +                          , EntryProbe, ReturnProbe)    \
  1.1736 +\
  1.1737 +  DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \
  1.1738 +                          , ReturnProbe);                          \
  1.1739 +\
  1.1740 +JNI_ENTRY(ResultType, \
  1.1741 +          jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
  1.1742 +  JNIWrapper("Call" XSTR(Result) "Method"); \
  1.1743 +\
  1.1744 +  EntryProbe; \
  1.1745 +  ResultType ret = 0;\
  1.1746 +  DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
  1.1747 +                     (const ResultType&)ret);\
  1.1748 +\
  1.1749 +  va_list args; \
  1.1750 +  va_start(args, methodID); \
  1.1751 +  JavaValue jvalue(Tag); \
  1.1752 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.1753 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
  1.1754 +  va_end(args); \
  1.1755 +  ret = jvalue.get_##ResultType(); \
  1.1756 +  return ret;\
  1.1757 +JNI_END
  1.1758 +
  1.1759 +// the runtime type of subword integral basic types is integer
  1.1760 +DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN
  1.1761 +                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1762 +                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
  1.1763 +DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE
  1.1764 +                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1765 +                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
  1.1766 +DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR
  1.1767 +                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1768 +                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
  1.1769 +DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT
  1.1770 +                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1771 +                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
  1.1772 +
  1.1773 +DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT
  1.1774 +                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1775 +                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
  1.1776 +DEFINE_CALLMETHOD(jint,     Int,     T_INT,
  1.1777 +                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1778 +                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
  1.1779 +DEFINE_CALLMETHOD(jlong,    Long,    T_LONG
  1.1780 +                  , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1781 +                  HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
  1.1782 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.1783 +DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT
  1.1784 +                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1785 +                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
  1.1786 +DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE
  1.1787 +                  , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1788 +                  HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
  1.1789 +
  1.1790 +#define DEFINE_CALLMETHODV(ResultType, Result, Tag \
  1.1791 +                          , EntryProbe, ReturnProbe)    \
  1.1792 +\
  1.1793 +  DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \
  1.1794 +                          , ReturnProbe);                          \
  1.1795 +\
  1.1796 +JNI_ENTRY(ResultType, \
  1.1797 +          jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
  1.1798 +  JNIWrapper("Call" XSTR(Result) "MethodV"); \
  1.1799 +\
  1.1800 +  EntryProbe;\
  1.1801 +  ResultType ret = 0;\
  1.1802 +  DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
  1.1803 +                     (const ResultType&)ret);\
  1.1804 +\
  1.1805 +  JavaValue jvalue(Tag); \
  1.1806 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.1807 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
  1.1808 +  ret = jvalue.get_##ResultType(); \
  1.1809 +  return ret;\
  1.1810 +JNI_END
  1.1811 +
  1.1812 +// the runtime type of subword integral basic types is integer
  1.1813 +DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
  1.1814 +                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1815 +                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
  1.1816 +DEFINE_CALLMETHODV(jbyte,    Byte,    T_BYTE
  1.1817 +                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1818 +                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
  1.1819 +DEFINE_CALLMETHODV(jchar,    Char,    T_CHAR
  1.1820 +                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1821 +                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
  1.1822 +DEFINE_CALLMETHODV(jshort,   Short,   T_SHORT
  1.1823 +                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1824 +                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
  1.1825 +
  1.1826 +DEFINE_CALLMETHODV(jobject,  Object,  T_OBJECT
  1.1827 +                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1828 +                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
  1.1829 +DEFINE_CALLMETHODV(jint,     Int,     T_INT,
  1.1830 +                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1831 +                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
  1.1832 +DEFINE_CALLMETHODV(jlong,    Long,    T_LONG
  1.1833 +                  , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1834 +                  HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
  1.1835 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.1836 +DEFINE_CALLMETHODV(jfloat,   Float,   T_FLOAT
  1.1837 +                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1838 +                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
  1.1839 +DEFINE_CALLMETHODV(jdouble,  Double,  T_DOUBLE
  1.1840 +                  , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1841 +                  HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
  1.1842 +
  1.1843 +#define DEFINE_CALLMETHODA(ResultType, Result, Tag \
  1.1844 +                          , EntryProbe, ReturnProbe)    \
  1.1845 +\
  1.1846 +  DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \
  1.1847 +                          , ReturnProbe);                          \
  1.1848 +\
  1.1849 +JNI_ENTRY(ResultType, \
  1.1850 +          jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
  1.1851 +  JNIWrapper("Call" XSTR(Result) "MethodA"); \
  1.1852 +  EntryProbe; \
  1.1853 +  ResultType ret = 0;\
  1.1854 +  DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
  1.1855 +                     (const ResultType&)ret);\
  1.1856 +\
  1.1857 +  JavaValue jvalue(Tag); \
  1.1858 +  JNI_ArgumentPusherArray ap(methodID, args); \
  1.1859 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
  1.1860 +  ret = jvalue.get_##ResultType(); \
  1.1861 +  return ret;\
  1.1862 +JNI_END
  1.1863 +
  1.1864 +// the runtime type of subword integral basic types is integer
  1.1865 +DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
  1.1866 +                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1867 +                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
  1.1868 +DEFINE_CALLMETHODA(jbyte,    Byte,    T_BYTE
  1.1869 +                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1870 +                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
  1.1871 +DEFINE_CALLMETHODA(jchar,    Char,    T_CHAR
  1.1872 +                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1873 +                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
  1.1874 +DEFINE_CALLMETHODA(jshort,   Short,   T_SHORT
  1.1875 +                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1876 +                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
  1.1877 +
  1.1878 +DEFINE_CALLMETHODA(jobject,  Object,  T_OBJECT
  1.1879 +                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1880 +                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
  1.1881 +DEFINE_CALLMETHODA(jint,     Int,     T_INT,
  1.1882 +                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1883 +                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
  1.1884 +DEFINE_CALLMETHODA(jlong,    Long,    T_LONG
  1.1885 +                  , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1886 +                  HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
  1.1887 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.1888 +DEFINE_CALLMETHODA(jfloat,   Float,   T_FLOAT
  1.1889 +                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1890 +                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
  1.1891 +DEFINE_CALLMETHODA(jdouble,  Double,  T_DOUBLE
  1.1892 +                  , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
  1.1893 +                  HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
  1.1894 +
  1.1895 +DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
  1.1896 +DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
  1.1897 +DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
  1.1898 +
  1.1899 +#endif /* USDT2 */
  1.1900 +
  1.1901 +JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
  1.1902 +  JNIWrapper("CallVoidMethod");
  1.1903 +#ifndef USDT2
  1.1904 +  DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID);
  1.1905 +#else /* USDT2 */
  1.1906 +  HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(
  1.1907 +                                   env, obj, (uintptr_t) methodID);
  1.1908 +#endif /* USDT2 */
  1.1909 +  DT_VOID_RETURN_MARK(CallVoidMethod);
  1.1910 +
  1.1911 +  va_list args;
  1.1912 +  va_start(args, methodID);
  1.1913 +  JavaValue jvalue(T_VOID);
  1.1914 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.1915 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
  1.1916 +  va_end(args);
  1.1917 +JNI_END
  1.1918 +
  1.1919 +
  1.1920 +JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
  1.1921 +  JNIWrapper("CallVoidMethodV");
  1.1922 +#ifndef USDT2
  1.1923 +  DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID);
  1.1924 +#else /* USDT2 */
  1.1925 +  HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(
  1.1926 +                                    env, obj, (uintptr_t) methodID);
  1.1927 +#endif /* USDT2 */
  1.1928 +  DT_VOID_RETURN_MARK(CallVoidMethodV);
  1.1929 +
  1.1930 +  JavaValue jvalue(T_VOID);
  1.1931 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.1932 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
  1.1933 +JNI_END
  1.1934 +
  1.1935 +
  1.1936 +JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
  1.1937 +  JNIWrapper("CallVoidMethodA");
  1.1938 +#ifndef USDT2
  1.1939 +  DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID);
  1.1940 +#else /* USDT2 */
  1.1941 +  HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(
  1.1942 +                                    env, obj, (uintptr_t) methodID);
  1.1943 +#endif /* USDT2 */
  1.1944 +  DT_VOID_RETURN_MARK(CallVoidMethodA);
  1.1945 +
  1.1946 +  JavaValue jvalue(T_VOID);
  1.1947 +  JNI_ArgumentPusherArray ap(methodID, args);
  1.1948 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
  1.1949 +JNI_END
  1.1950 +
  1.1951 +
  1.1952 +#ifndef USDT2
  1.1953 +#define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \
  1.1954 +\
  1.1955 +  DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\
  1.1956 +  DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType);\
  1.1957 +  DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType);\
  1.1958 +\
  1.1959 +JNI_ENTRY(ResultType, \
  1.1960 +          jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
  1.1961 +  JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
  1.1962 +\
  1.1963 +  DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##Method__entry, env, obj, cls, methodID);\
  1.1964 +  ResultType ret;\
  1.1965 +  DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
  1.1966 +                     (const ResultType&)ret);\
  1.1967 +\
  1.1968 +  va_list args; \
  1.1969 +  va_start(args, methodID); \
  1.1970 +  JavaValue jvalue(Tag); \
  1.1971 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.1972 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
  1.1973 +  va_end(args); \
  1.1974 +  ret = jvalue.get_##ResultType(); \
  1.1975 +  return ret;\
  1.1976 +JNI_END \
  1.1977 +\
  1.1978 +JNI_ENTRY(ResultType, \
  1.1979 +          jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
  1.1980 +  JNIWrapper("CallNonvitual" XSTR(Result) "#MethodV"); \
  1.1981 +  DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodV__entry, env, obj, cls, methodID);\
  1.1982 +  ResultType ret;\
  1.1983 +  DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
  1.1984 +                     (const ResultType&)ret);\
  1.1985 +\
  1.1986 +  JavaValue jvalue(Tag); \
  1.1987 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.1988 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
  1.1989 +  ret = jvalue.get_##ResultType(); \
  1.1990 +  return ret;\
  1.1991 +JNI_END \
  1.1992 +\
  1.1993 +JNI_ENTRY(ResultType, \
  1.1994 +          jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
  1.1995 +  JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
  1.1996 +  DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodA__entry, env, obj, cls, methodID);\
  1.1997 +  ResultType ret;\
  1.1998 +  DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
  1.1999 +                     (const ResultType&)ret);\
  1.2000 +\
  1.2001 +  JavaValue jvalue(Tag); \
  1.2002 +  JNI_ArgumentPusherArray ap(methodID, args); \
  1.2003 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
  1.2004 +  ret = jvalue.get_##ResultType(); \
  1.2005 +  return ret;\
  1.2006 +JNI_END
  1.2007 +
  1.2008 +// the runtime type of subword integral basic types is integer
  1.2009 +DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN)
  1.2010 +DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE)
  1.2011 +DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR)
  1.2012 +DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT)
  1.2013 +
  1.2014 +DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT)
  1.2015 +DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT)
  1.2016 +DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG)
  1.2017 +DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT)
  1.2018 +DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE)
  1.2019 +
  1.2020 +
  1.2021 +DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod);
  1.2022 +DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV);
  1.2023 +DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA);
  1.2024 +
  1.2025 +#else /* USDT2 */
  1.2026 +
  1.2027 +#define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \
  1.2028 +                                    , EntryProbe, ReturnProbe)      \
  1.2029 +\
  1.2030 +  DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \
  1.2031 +                          , ReturnProbe);\
  1.2032 +\
  1.2033 +JNI_ENTRY(ResultType, \
  1.2034 +          jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
  1.2035 +  JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
  1.2036 +\
  1.2037 +  EntryProbe;\
  1.2038 +  ResultType ret;\
  1.2039 +  DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
  1.2040 +                     (const ResultType&)ret);\
  1.2041 +\
  1.2042 +  va_list args; \
  1.2043 +  va_start(args, methodID); \
  1.2044 +  JavaValue jvalue(Tag); \
  1.2045 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.2046 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
  1.2047 +  va_end(args); \
  1.2048 +  ret = jvalue.get_##ResultType(); \
  1.2049 +  return ret;\
  1.2050 +JNI_END
  1.2051 +
  1.2052 +// the runtime type of subword integral basic types is integer
  1.2053 +DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN
  1.2054 +                            , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2055 +                            HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))
  1.2056 +DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE
  1.2057 +                            , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2058 +                            HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))
  1.2059 +DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR
  1.2060 +                            , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2061 +                            HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))
  1.2062 +DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT
  1.2063 +                            , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2064 +                            HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))
  1.2065 +
  1.2066 +DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT
  1.2067 +                            , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2068 +                            HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))
  1.2069 +DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT
  1.2070 +                            , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2071 +                            HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))
  1.2072 +DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG
  1.2073 +                            , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2074 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2075 +                            HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref))
  1.2076 +DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT
  1.2077 +                            , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2078 +                            HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())
  1.2079 +DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE
  1.2080 +                            , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2081 +                            HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN())
  1.2082 +
  1.2083 +#define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \
  1.2084 +                                    , EntryProbe, ReturnProbe)      \
  1.2085 +\
  1.2086 +  DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \
  1.2087 +                          , ReturnProbe);\
  1.2088 +\
  1.2089 +JNI_ENTRY(ResultType, \
  1.2090 +          jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
  1.2091 +  JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \
  1.2092 +\
  1.2093 +  EntryProbe;\
  1.2094 +  ResultType ret;\
  1.2095 +  DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
  1.2096 +                     (const ResultType&)ret);\
  1.2097 +\
  1.2098 +  JavaValue jvalue(Tag); \
  1.2099 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.2100 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
  1.2101 +  ret = jvalue.get_##ResultType(); \
  1.2102 +  return ret;\
  1.2103 +JNI_END
  1.2104 +
  1.2105 +// the runtime type of subword integral basic types is integer
  1.2106 +DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN
  1.2107 +                            , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2108 +                            HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))
  1.2109 +DEFINE_CALLNONVIRTUALMETHODV(jbyte,    Byte,    T_BYTE
  1.2110 +                            , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2111 +                            HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))
  1.2112 +DEFINE_CALLNONVIRTUALMETHODV(jchar,    Char,    T_CHAR
  1.2113 +                            , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2114 +                            HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))
  1.2115 +DEFINE_CALLNONVIRTUALMETHODV(jshort,   Short,   T_SHORT
  1.2116 +                            , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2117 +                            HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))
  1.2118 +
  1.2119 +DEFINE_CALLNONVIRTUALMETHODV(jobject,  Object,  T_OBJECT
  1.2120 +                            , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2121 +                            HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))
  1.2122 +DEFINE_CALLNONVIRTUALMETHODV(jint,     Int,     T_INT
  1.2123 +                            , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2124 +                            HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))
  1.2125 +DEFINE_CALLNONVIRTUALMETHODV(jlong,    Long,    T_LONG
  1.2126 +                            , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2127 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2128 +                            HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref))
  1.2129 +DEFINE_CALLNONVIRTUALMETHODV(jfloat,   Float,   T_FLOAT
  1.2130 +                            , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2131 +                            HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())
  1.2132 +DEFINE_CALLNONVIRTUALMETHODV(jdouble,  Double,  T_DOUBLE
  1.2133 +                            , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2134 +                            HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN())
  1.2135 +
  1.2136 +#define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \
  1.2137 +                                    , EntryProbe, ReturnProbe)      \
  1.2138 +\
  1.2139 +  DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \
  1.2140 +                          , ReturnProbe);\
  1.2141 +\
  1.2142 +JNI_ENTRY(ResultType, \
  1.2143 +          jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
  1.2144 +  JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
  1.2145 +\
  1.2146 +  EntryProbe;\
  1.2147 +  ResultType ret;\
  1.2148 +  DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
  1.2149 +                     (const ResultType&)ret);\
  1.2150 +\
  1.2151 +  JavaValue jvalue(Tag); \
  1.2152 +  JNI_ArgumentPusherArray ap(methodID, args); \
  1.2153 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
  1.2154 +  ret = jvalue.get_##ResultType(); \
  1.2155 +  return ret;\
  1.2156 +JNI_END
  1.2157 +
  1.2158 +// the runtime type of subword integral basic types is integer
  1.2159 +DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN
  1.2160 +                            , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2161 +                            HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))
  1.2162 +DEFINE_CALLNONVIRTUALMETHODA(jbyte,    Byte,    T_BYTE
  1.2163 +                            , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2164 +                            HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))
  1.2165 +DEFINE_CALLNONVIRTUALMETHODA(jchar,    Char,    T_CHAR
  1.2166 +                            , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2167 +                            HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))
  1.2168 +DEFINE_CALLNONVIRTUALMETHODA(jshort,   Short,   T_SHORT
  1.2169 +                            , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2170 +                            HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))
  1.2171 +
  1.2172 +DEFINE_CALLNONVIRTUALMETHODA(jobject,  Object,  T_OBJECT
  1.2173 +                            , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2174 +                            HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))
  1.2175 +DEFINE_CALLNONVIRTUALMETHODA(jint,     Int,     T_INT
  1.2176 +                            , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2177 +                            HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))
  1.2178 +DEFINE_CALLNONVIRTUALMETHODA(jlong,    Long,    T_LONG
  1.2179 +                            , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2180 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2181 +                            HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref))
  1.2182 +DEFINE_CALLNONVIRTUALMETHODA(jfloat,   Float,   T_FLOAT
  1.2183 +                            , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2184 +                            HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
  1.2185 +DEFINE_CALLNONVIRTUALMETHODA(jdouble,  Double,  T_DOUBLE
  1.2186 +                            , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
  1.2187 +                            HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
  1.2188 +
  1.2189 +DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
  1.2190 +                         , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
  1.2191 +DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
  1.2192 +                         , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
  1.2193 +DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
  1.2194 +                         , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
  1.2195 +#endif /* USDT2 */
  1.2196 +
  1.2197 +JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
  1.2198 +  JNIWrapper("CallNonvirtualVoidMethod");
  1.2199 +
  1.2200 +#ifndef USDT2
  1.2201 +  DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry,
  1.2202 +               env, obj, cls, methodID);
  1.2203 +#else /* USDT2 */
  1.2204 +  HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(
  1.2205 +               env, obj, cls, (uintptr_t) methodID);
  1.2206 +#endif /* USDT2 */
  1.2207 +  DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
  1.2208 +
  1.2209 +  va_list args;
  1.2210 +  va_start(args, methodID);
  1.2211 +  JavaValue jvalue(T_VOID);
  1.2212 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.2213 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
  1.2214 +  va_end(args);
  1.2215 +JNI_END
  1.2216 +
  1.2217 +
  1.2218 +JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
  1.2219 +  JNIWrapper("CallNonvirtualVoidMethodV");
  1.2220 +
  1.2221 +#ifndef USDT2
  1.2222 +  DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry,
  1.2223 +               env, obj, cls, methodID);
  1.2224 +#else /* USDT2 */
  1.2225 +  HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(
  1.2226 +               env, obj, cls, (uintptr_t) methodID);
  1.2227 +#endif /* USDT2 */
  1.2228 +  DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);
  1.2229 +
  1.2230 +  JavaValue jvalue(T_VOID);
  1.2231 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.2232 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
  1.2233 +JNI_END
  1.2234 +
  1.2235 +
  1.2236 +JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))
  1.2237 +  JNIWrapper("CallNonvirtualVoidMethodA");
  1.2238 +#ifndef USDT2
  1.2239 +  DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodA__entry,
  1.2240 +                env, obj, cls, methodID);
  1.2241 +#else /* USDT2 */
  1.2242 +  HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(
  1.2243 +                env, obj, cls, (uintptr_t) methodID);
  1.2244 +#endif /* USDT2 */
  1.2245 +  DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);
  1.2246 +  JavaValue jvalue(T_VOID);
  1.2247 +  JNI_ArgumentPusherArray ap(methodID, args);
  1.2248 +  jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
  1.2249 +JNI_END
  1.2250 +
  1.2251 +
  1.2252 +#ifndef USDT2
  1.2253 +#define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag) \
  1.2254 +\
  1.2255 +  DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType);\
  1.2256 +  DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType);\
  1.2257 +  DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType);\
  1.2258 +\
  1.2259 +JNI_ENTRY(ResultType, \
  1.2260 +          jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
  1.2261 +  JNIWrapper("CallStatic" XSTR(Result) "Method"); \
  1.2262 +\
  1.2263 +  DTRACE_PROBE3(hotspot_jni, CallStatic##Result##Method__entry, env, cls, methodID);\
  1.2264 +  ResultType ret = 0;\
  1.2265 +  DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
  1.2266 +                     (const ResultType&)ret);\
  1.2267 +\
  1.2268 +  va_list args; \
  1.2269 +  va_start(args, methodID); \
  1.2270 +  JavaValue jvalue(Tag); \
  1.2271 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.2272 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
  1.2273 +  va_end(args); \
  1.2274 +  ret = jvalue.get_##ResultType(); \
  1.2275 +  return ret;\
  1.2276 +JNI_END \
  1.2277 +\
  1.2278 +JNI_ENTRY(ResultType, \
  1.2279 +          jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
  1.2280 +  JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
  1.2281 +  DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodV__entry, env, cls, methodID);\
  1.2282 +  ResultType ret = 0;\
  1.2283 +  DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
  1.2284 +                     (const ResultType&)ret);\
  1.2285 +\
  1.2286 +  JavaValue jvalue(Tag); \
  1.2287 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.2288 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
  1.2289 +  ret = jvalue.get_##ResultType(); \
  1.2290 +  return ret;\
  1.2291 +JNI_END \
  1.2292 +\
  1.2293 +JNI_ENTRY(ResultType, \
  1.2294 +          jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
  1.2295 +  JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
  1.2296 +  DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodA__entry, env, cls, methodID);\
  1.2297 +  ResultType ret = 0;\
  1.2298 +  DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
  1.2299 +                     (const ResultType&)ret);\
  1.2300 +\
  1.2301 +  JavaValue jvalue(Tag); \
  1.2302 +  JNI_ArgumentPusherArray ap(methodID, args); \
  1.2303 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
  1.2304 +  ret = jvalue.get_##ResultType(); \
  1.2305 +  return ret;\
  1.2306 +JNI_END
  1.2307 +
  1.2308 +// the runtime type of subword integral basic types is integer
  1.2309 +DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN)
  1.2310 +DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE)
  1.2311 +DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR)
  1.2312 +DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT)
  1.2313 +
  1.2314 +DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT)
  1.2315 +DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT)
  1.2316 +DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG)
  1.2317 +DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT)
  1.2318 +DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE)
  1.2319 +
  1.2320 +
  1.2321 +DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod);
  1.2322 +DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV);
  1.2323 +DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA);
  1.2324 +
  1.2325 +#else /* USDT2 */
  1.2326 +
  1.2327 +#define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \
  1.2328 +                                , EntryProbe, ResultProbe) \
  1.2329 +\
  1.2330 +  DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \
  1.2331 +                          , ResultProbe);                               \
  1.2332 +\
  1.2333 +JNI_ENTRY(ResultType, \
  1.2334 +          jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
  1.2335 +  JNIWrapper("CallStatic" XSTR(Result) "Method"); \
  1.2336 +\
  1.2337 +  EntryProbe; \
  1.2338 +  ResultType ret = 0;\
  1.2339 +  DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
  1.2340 +                     (const ResultType&)ret);\
  1.2341 +\
  1.2342 +  va_list args; \
  1.2343 +  va_start(args, methodID); \
  1.2344 +  JavaValue jvalue(Tag); \
  1.2345 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.2346 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
  1.2347 +  va_end(args); \
  1.2348 +  ret = jvalue.get_##ResultType(); \
  1.2349 +  return ret;\
  1.2350 +JNI_END
  1.2351 +
  1.2352 +// the runtime type of subword integral basic types is integer
  1.2353 +DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN
  1.2354 +                        , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2355 +                        HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));
  1.2356 +DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE
  1.2357 +                        , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2358 +                        HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));
  1.2359 +DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR
  1.2360 +                        , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2361 +                        HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));
  1.2362 +DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT
  1.2363 +                        , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2364 +                        HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));
  1.2365 +
  1.2366 +DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT
  1.2367 +                        , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2368 +                        HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));
  1.2369 +DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT
  1.2370 +                        , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2371 +                        HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));
  1.2372 +DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG
  1.2373 +                        , HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2374 +                        HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref));
  1.2375 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2376 +DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT
  1.2377 +                        , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2378 +                        HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());
  1.2379 +DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE
  1.2380 +                        , HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
  1.2381 +                        HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN());
  1.2382 +
  1.2383 +#define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \
  1.2384 +                                , EntryProbe, ResultProbe) \
  1.2385 +\
  1.2386 +  DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \
  1.2387 +                          , ResultProbe);                               \
  1.2388 +\
  1.2389 +JNI_ENTRY(ResultType, \
  1.2390 +          jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
  1.2391 +  JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
  1.2392 +\
  1.2393 +  EntryProbe; \
  1.2394 +  ResultType ret = 0;\
  1.2395 +  DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
  1.2396 +                     (const ResultType&)ret);\
  1.2397 +\
  1.2398 +  JavaValue jvalue(Tag); \
  1.2399 +  JNI_ArgumentPusherVaArg ap(methodID, args); \
  1.2400 +  /* Make sure class is initialized before trying to invoke its method */ \
  1.2401 +  KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls))); \
  1.2402 +  k()->initialize(CHECK_0); \
  1.2403 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
  1.2404 +  va_end(args); \
  1.2405 +  ret = jvalue.get_##ResultType(); \
  1.2406 +  return ret;\
  1.2407 +JNI_END
  1.2408 +
  1.2409 +// the runtime type of subword integral basic types is integer
  1.2410 +DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN
  1.2411 +                        , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2412 +                        HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));
  1.2413 +DEFINE_CALLSTATICMETHODV(jbyte,    Byte,    T_BYTE
  1.2414 +                        , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2415 +                        HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));
  1.2416 +DEFINE_CALLSTATICMETHODV(jchar,    Char,    T_CHAR
  1.2417 +                        , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2418 +                        HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));
  1.2419 +DEFINE_CALLSTATICMETHODV(jshort,   Short,   T_SHORT
  1.2420 +                        , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2421 +                        HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));
  1.2422 +
  1.2423 +DEFINE_CALLSTATICMETHODV(jobject,  Object,  T_OBJECT
  1.2424 +                        , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2425 +                        HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));
  1.2426 +DEFINE_CALLSTATICMETHODV(jint,     Int,     T_INT
  1.2427 +                        , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2428 +                        HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));
  1.2429 +DEFINE_CALLSTATICMETHODV(jlong,    Long,    T_LONG
  1.2430 +                        , HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2431 +                        HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref));
  1.2432 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2433 +DEFINE_CALLSTATICMETHODV(jfloat,   Float,   T_FLOAT
  1.2434 +                        , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2435 +                        HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());
  1.2436 +DEFINE_CALLSTATICMETHODV(jdouble,  Double,  T_DOUBLE
  1.2437 +                        , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
  1.2438 +                        HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN());
  1.2439 +
  1.2440 +#define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \
  1.2441 +                                , EntryProbe, ResultProbe) \
  1.2442 +\
  1.2443 +  DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \
  1.2444 +                          , ResultProbe);                               \
  1.2445 +\
  1.2446 +JNI_ENTRY(ResultType, \
  1.2447 +          jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
  1.2448 +  JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
  1.2449 +\
  1.2450 +  EntryProbe; \
  1.2451 +  ResultType ret = 0;\
  1.2452 +  DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
  1.2453 +                     (const ResultType&)ret);\
  1.2454 +\
  1.2455 +  JavaValue jvalue(Tag); \
  1.2456 +  JNI_ArgumentPusherArray ap(methodID, args); \
  1.2457 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
  1.2458 +  ret = jvalue.get_##ResultType(); \
  1.2459 +  return ret;\
  1.2460 +JNI_END
  1.2461 +
  1.2462 +// the runtime type of subword integral basic types is integer
  1.2463 +DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN
  1.2464 +                        , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2465 +                        HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));
  1.2466 +DEFINE_CALLSTATICMETHODA(jbyte,    Byte,    T_BYTE
  1.2467 +                        , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2468 +                        HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));
  1.2469 +DEFINE_CALLSTATICMETHODA(jchar,    Char,    T_CHAR
  1.2470 +                        , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2471 +                        HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));
  1.2472 +DEFINE_CALLSTATICMETHODA(jshort,   Short,   T_SHORT
  1.2473 +                        , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2474 +                        HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));
  1.2475 +
  1.2476 +DEFINE_CALLSTATICMETHODA(jobject,  Object,  T_OBJECT
  1.2477 +                        , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2478 +                        HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));
  1.2479 +DEFINE_CALLSTATICMETHODA(jint,     Int,     T_INT
  1.2480 +                        , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2481 +                        HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));
  1.2482 +DEFINE_CALLSTATICMETHODA(jlong,    Long,    T_LONG
  1.2483 +                        , HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2484 +                        HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref));
  1.2485 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2486 +DEFINE_CALLSTATICMETHODA(jfloat,   Float,   T_FLOAT
  1.2487 +                        , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2488 +                        HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
  1.2489 +DEFINE_CALLSTATICMETHODA(jdouble,  Double,  T_DOUBLE
  1.2490 +                        , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
  1.2491 +                        HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
  1.2492 +
  1.2493 +DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
  1.2494 +                         , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
  1.2495 +DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
  1.2496 +                         , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
  1.2497 +DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
  1.2498 +                         , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
  1.2499 +#endif /* USDT2 */
  1.2500 +
  1.2501 +JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
  1.2502 +  JNIWrapper("CallStaticVoidMethod");
  1.2503 +#ifndef USDT2
  1.2504 +  DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID);
  1.2505 +#else /* USDT2 */
  1.2506 +  HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(
  1.2507 +                                         env, cls, (uintptr_t) methodID);
  1.2508 +#endif /* USDT2 */
  1.2509 +  DT_VOID_RETURN_MARK(CallStaticVoidMethod);
  1.2510 +
  1.2511 +  va_list args;
  1.2512 +  va_start(args, methodID);
  1.2513 +  JavaValue jvalue(T_VOID);
  1.2514 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.2515 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
  1.2516 +  va_end(args);
  1.2517 +JNI_END
  1.2518 +
  1.2519 +
  1.2520 +JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
  1.2521 +  JNIWrapper("CallStaticVoidMethodV");
  1.2522 +#ifndef USDT2
  1.2523 +  DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID);
  1.2524 +#else /* USDT2 */
  1.2525 +  HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(
  1.2526 +                                          env, cls, (uintptr_t) methodID);
  1.2527 +#endif /* USDT2 */
  1.2528 +  DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
  1.2529 +
  1.2530 +  JavaValue jvalue(T_VOID);
  1.2531 +  JNI_ArgumentPusherVaArg ap(methodID, args);
  1.2532 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
  1.2533 +JNI_END
  1.2534 +
  1.2535 +
  1.2536 +JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
  1.2537 +  JNIWrapper("CallStaticVoidMethodA");
  1.2538 +#ifndef USDT2
  1.2539 +  DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID);
  1.2540 +#else /* USDT2 */
  1.2541 +  HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(
  1.2542 +                                          env, cls, (uintptr_t) methodID);
  1.2543 +#endif /* USDT2 */
  1.2544 +  DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
  1.2545 +
  1.2546 +  JavaValue jvalue(T_VOID);
  1.2547 +  JNI_ArgumentPusherArray ap(methodID, args);
  1.2548 +  jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
  1.2549 +JNI_END
  1.2550 +
  1.2551 +
  1.2552 +//
  1.2553 +// Accessing Fields
  1.2554 +//
  1.2555 +
  1.2556 +
  1.2557 +#ifndef USDT2
  1.2558 +DT_RETURN_MARK_DECL(GetFieldID, jfieldID);
  1.2559 +#else /* USDT2 */
  1.2560 +DT_RETURN_MARK_DECL(GetFieldID, jfieldID
  1.2561 +                    , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
  1.2562 +#endif /* USDT2 */
  1.2563 +
  1.2564 +JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
  1.2565 +          const char *name, const char *sig))
  1.2566 +  JNIWrapper("GetFieldID");
  1.2567 +#ifndef USDT2
  1.2568 +  DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig);
  1.2569 +#else /* USDT2 */
  1.2570 +  HOTSPOT_JNI_GETFIELDID_ENTRY(
  1.2571 +                               env, clazz, (char *) name, (char *) sig);
  1.2572 +#endif /* USDT2 */
  1.2573 +  jfieldID ret = 0;
  1.2574 +  DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
  1.2575 +
  1.2576 +  // The class should have been loaded (we have an instance of the class
  1.2577 +  // passed in) so the field and signature should already be in the symbol
  1.2578 +  // table.  If they're not there, the field doesn't exist.
  1.2579 +  TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
  1.2580 +  TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
  1.2581 +  if (fieldname == NULL || signame == NULL) {
  1.2582 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
  1.2583 +  }
  1.2584 +  KlassHandle k(THREAD,
  1.2585 +                java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
  1.2586 +  // Make sure class is initialized before handing id's out to fields
  1.2587 +  k()->initialize(CHECK_NULL);
  1.2588 +
  1.2589 +  fieldDescriptor fd;
  1.2590 +  if (!k()->oop_is_instance() ||
  1.2591 +      !InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
  1.2592 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
  1.2593 +  }
  1.2594 +
  1.2595 +  // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
  1.2596 +  // It may also have hash bits for k, if VerifyJNIFields is turned on.
  1.2597 +  ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());
  1.2598 +  return ret;
  1.2599 +JNI_END
  1.2600 +
  1.2601 +
  1.2602 +JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
  1.2603 +  JNIWrapper("GetObjectField");
  1.2604 +#ifndef USDT2
  1.2605 +  DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
  1.2606 +#else /* USDT2 */
  1.2607 +  HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(
  1.2608 +                                   env, obj, (uintptr_t) fieldID);
  1.2609 +#endif /* USDT2 */
  1.2610 +  oop o = JNIHandles::resolve_non_null(obj);
  1.2611 +  Klass* k = o->klass();
  1.2612 +  int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
  1.2613 +  // Keep JVMTI addition small and only check enabled flag here.
  1.2614 +  // jni_GetField_probe() assumes that is okay to create handles.
  1.2615 +  if (JvmtiExport::should_post_field_access()) {
  1.2616 +    o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
  1.2617 +  }
  1.2618 +  jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
  1.2619 +#if INCLUDE_ALL_GCS
  1.2620 +  // If G1 is enabled and we are accessing the value of the referent
  1.2621 +  // field in a reference object then we need to register a non-null
  1.2622 +  // referent with the SATB barrier.
  1.2623 +  if (UseG1GC) {
  1.2624 +    bool needs_barrier = false;
  1.2625 +
  1.2626 +    if (ret != NULL &&
  1.2627 +        offset == java_lang_ref_Reference::referent_offset &&
  1.2628 +        InstanceKlass::cast(k)->reference_type() != REF_NONE) {
  1.2629 +      assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
  1.2630 +      needs_barrier = true;
  1.2631 +    }
  1.2632 +
  1.2633 +    if (needs_barrier) {
  1.2634 +      oop referent = JNIHandles::resolve(ret);
  1.2635 +      G1SATBCardTableModRefBS::enqueue(referent);
  1.2636 +    }
  1.2637 +  }
  1.2638 +#endif // INCLUDE_ALL_GCS
  1.2639 +#ifndef USDT2
  1.2640 +  DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
  1.2641 +#else /* USDT2 */
  1.2642 +HOTSPOT_JNI_GETOBJECTFIELD_RETURN(
  1.2643 +                                  ret);
  1.2644 +#endif /* USDT2 */
  1.2645 +  return ret;
  1.2646 +JNI_END
  1.2647 +
  1.2648 +
  1.2649 +#ifndef USDT2
  1.2650 +#define DEFINE_GETFIELD(Return,Fieldname,Result) \
  1.2651 +\
  1.2652 +  DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\
  1.2653 +\
  1.2654 +JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
  1.2655 +  JNIWrapper("Get" XSTR(Result) "Field"); \
  1.2656 +\
  1.2657 +  DTRACE_PROBE3(hotspot_jni, Get##Result##Field__entry, env, obj, fieldID);\
  1.2658 +  Return ret = 0;\
  1.2659 +  DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
  1.2660 +\
  1.2661 +  oop o = JNIHandles::resolve_non_null(obj); \
  1.2662 +  Klass* k = o->klass(); \
  1.2663 +  int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
  1.2664 +  /* Keep JVMTI addition small and only check enabled flag here.       */ \
  1.2665 +  /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
  1.2666 +  /* and creates a ResetNoHandleMark.                                   */ \
  1.2667 +  if (JvmtiExport::should_post_field_access()) { \
  1.2668 +    o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
  1.2669 +  } \
  1.2670 +  ret = o->Fieldname##_field(offset); \
  1.2671 +  return ret; \
  1.2672 +JNI_END
  1.2673 +
  1.2674 +DEFINE_GETFIELD(jboolean, bool,   Boolean)
  1.2675 +DEFINE_GETFIELD(jbyte,    byte,   Byte)
  1.2676 +DEFINE_GETFIELD(jchar,    char,   Char)
  1.2677 +DEFINE_GETFIELD(jshort,   short,  Short)
  1.2678 +DEFINE_GETFIELD(jint,     int,    Int)
  1.2679 +DEFINE_GETFIELD(jlong,    long,   Long)
  1.2680 +DEFINE_GETFIELD(jfloat,   float,  Float)
  1.2681 +DEFINE_GETFIELD(jdouble,  double, Double)
  1.2682 +
  1.2683 +#else /* USDT2 */
  1.2684 +
  1.2685 +#define DEFINE_GETFIELD(Return,Fieldname,Result \
  1.2686 +  , EntryProbe, ReturnProbe) \
  1.2687 +\
  1.2688 +  DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
  1.2689 +  , ReturnProbe); \
  1.2690 +\
  1.2691 +JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
  1.2692 +  JNIWrapper("Get" XSTR(Result) "Field"); \
  1.2693 +\
  1.2694 +  EntryProbe; \
  1.2695 +  Return ret = 0;\
  1.2696 +  DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
  1.2697 +\
  1.2698 +  oop o = JNIHandles::resolve_non_null(obj); \
  1.2699 +  Klass* k = o->klass(); \
  1.2700 +  int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
  1.2701 +  /* Keep JVMTI addition small and only check enabled flag here.       */ \
  1.2702 +  /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
  1.2703 +  /* and creates a ResetNoHandleMark.                                   */ \
  1.2704 +  if (JvmtiExport::should_post_field_access()) { \
  1.2705 +    o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
  1.2706 +  } \
  1.2707 +  ret = o->Fieldname##_field(offset); \
  1.2708 +  return ret; \
  1.2709 +JNI_END
  1.2710 +
  1.2711 +DEFINE_GETFIELD(jboolean, bool,   Boolean
  1.2712 +                , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2713 +                HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))
  1.2714 +DEFINE_GETFIELD(jbyte,    byte,   Byte
  1.2715 +                , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2716 +                HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))
  1.2717 +DEFINE_GETFIELD(jchar,    char,   Char
  1.2718 +                , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2719 +                HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))
  1.2720 +DEFINE_GETFIELD(jshort,   short,  Short
  1.2721 +                , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2722 +                HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))
  1.2723 +DEFINE_GETFIELD(jint,     int,    Int
  1.2724 +                , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2725 +                HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))
  1.2726 +DEFINE_GETFIELD(jlong,    long,   Long
  1.2727 +                , HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2728 +                HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref))
  1.2729 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2730 +DEFINE_GETFIELD(jfloat,   float,  Float
  1.2731 +                , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2732 +                HOTSPOT_JNI_GETFLOATFIELD_RETURN())
  1.2733 +DEFINE_GETFIELD(jdouble,  double, Double
  1.2734 +                , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2735 +                HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())
  1.2736 +#endif /* USDT2 */
  1.2737 +
  1.2738 +address jni_GetBooleanField_addr() {
  1.2739 +  return (address)jni_GetBooleanField;
  1.2740 +}
  1.2741 +address jni_GetByteField_addr() {
  1.2742 +  return (address)jni_GetByteField;
  1.2743 +}
  1.2744 +address jni_GetCharField_addr() {
  1.2745 +  return (address)jni_GetCharField;
  1.2746 +}
  1.2747 +address jni_GetShortField_addr() {
  1.2748 +  return (address)jni_GetShortField;
  1.2749 +}
  1.2750 +address jni_GetIntField_addr() {
  1.2751 +  return (address)jni_GetIntField;
  1.2752 +}
  1.2753 +address jni_GetLongField_addr() {
  1.2754 +  return (address)jni_GetLongField;
  1.2755 +}
  1.2756 +address jni_GetFloatField_addr() {
  1.2757 +  return (address)jni_GetFloatField;
  1.2758 +}
  1.2759 +address jni_GetDoubleField_addr() {
  1.2760 +  return (address)jni_GetDoubleField;
  1.2761 +}
  1.2762 +
  1.2763 +JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
  1.2764 +  JNIWrapper("SetObjectField");
  1.2765 +#ifndef USDT2
  1.2766 +  DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value);
  1.2767 +#else /* USDT2 */
  1.2768 +  HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(
  1.2769 +                                   env, obj, (uintptr_t) fieldID, value);
  1.2770 +#endif /* USDT2 */
  1.2771 +  oop o = JNIHandles::resolve_non_null(obj);
  1.2772 +  Klass* k = o->klass();
  1.2773 +  int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
  1.2774 +  // Keep JVMTI addition small and only check enabled flag here.
  1.2775 +  // jni_SetField_probe_nh() assumes that is not okay to create handles
  1.2776 +  // and creates a ResetNoHandleMark.
  1.2777 +  if (JvmtiExport::should_post_field_modification()) {
  1.2778 +    jvalue field_value;
  1.2779 +    field_value.l = value;
  1.2780 +    o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
  1.2781 +  }
  1.2782 +  o->obj_field_put(offset, JNIHandles::resolve(value));
  1.2783 +#ifndef USDT2
  1.2784 +  DTRACE_PROBE(hotspot_jni, SetObjectField__return);
  1.2785 +#else /* USDT2 */
  1.2786 +  HOTSPOT_JNI_SETOBJECTFIELD_RETURN(
  1.2787 +);
  1.2788 +#endif /* USDT2 */
  1.2789 +JNI_END
  1.2790 +
  1.2791 +#ifndef USDT2
  1.2792 +#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \
  1.2793 +\
  1.2794 +JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
  1.2795 +  JNIWrapper("Set" XSTR(Result) "Field"); \
  1.2796 +\
  1.2797 +  FP_SELECT_##Result( \
  1.2798 +    DTRACE_PROBE4(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID, value), \
  1.2799 +    DTRACE_PROBE3(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID)); \
  1.2800 +\
  1.2801 +  oop o = JNIHandles::resolve_non_null(obj); \
  1.2802 +  Klass* k = o->klass(); \
  1.2803 +  int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
  1.2804 +  /* Keep JVMTI addition small and only check enabled flag here.       */ \
  1.2805 +  /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
  1.2806 +  /* and creates a ResetNoHandleMark.                                   */ \
  1.2807 +  if (JvmtiExport::should_post_field_modification()) { \
  1.2808 +    jvalue field_value; \
  1.2809 +    field_value.unionType = value; \
  1.2810 +    o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
  1.2811 +  } \
  1.2812 +  o->Fieldname##_field_put(offset, value); \
  1.2813 +  DTRACE_PROBE(hotspot_jni, Set##Result##Field__return);\
  1.2814 +JNI_END
  1.2815 +
  1.2816 +DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z)
  1.2817 +DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b)
  1.2818 +DEFINE_SETFIELD(jchar,    char,   Char,    'C', c)
  1.2819 +DEFINE_SETFIELD(jshort,   short,  Short,   'S', s)
  1.2820 +DEFINE_SETFIELD(jint,     int,    Int,     'I', i)
  1.2821 +DEFINE_SETFIELD(jlong,    long,   Long,    'J', j)
  1.2822 +DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f)
  1.2823 +DEFINE_SETFIELD(jdouble,  double, Double,  'D', d)
  1.2824 +
  1.2825 +#else /* USDT2 */
  1.2826 +
  1.2827 +#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
  1.2828 +                        , EntryProbe, ReturnProbe) \
  1.2829 +\
  1.2830 +JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
  1.2831 +  JNIWrapper("Set" XSTR(Result) "Field"); \
  1.2832 +\
  1.2833 +  EntryProbe; \
  1.2834 +\
  1.2835 +  oop o = JNIHandles::resolve_non_null(obj); \
  1.2836 +  Klass* k = o->klass(); \
  1.2837 +  int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
  1.2838 +  /* Keep JVMTI addition small and only check enabled flag here.       */ \
  1.2839 +  /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
  1.2840 +  /* and creates a ResetNoHandleMark.                                   */ \
  1.2841 +  if (JvmtiExport::should_post_field_modification()) { \
  1.2842 +    jvalue field_value; \
  1.2843 +    field_value.unionType = value; \
  1.2844 +    o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
  1.2845 +  } \
  1.2846 +  o->Fieldname##_field_put(offset, value); \
  1.2847 +  ReturnProbe; \
  1.2848 +JNI_END
  1.2849 +
  1.2850 +DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z
  1.2851 +                , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
  1.2852 +                HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
  1.2853 +DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b
  1.2854 +                , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
  1.2855 +                HOTSPOT_JNI_SETBYTEFIELD_RETURN())
  1.2856 +DEFINE_SETFIELD(jchar,    char,   Char,    'C', c
  1.2857 +                , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
  1.2858 +                HOTSPOT_JNI_SETCHARFIELD_RETURN())
  1.2859 +DEFINE_SETFIELD(jshort,   short,  Short,   'S', s
  1.2860 +                , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
  1.2861 +                HOTSPOT_JNI_SETSHORTFIELD_RETURN())
  1.2862 +DEFINE_SETFIELD(jint,     int,    Int,     'I', i
  1.2863 +                , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
  1.2864 +                HOTSPOT_JNI_SETINTFIELD_RETURN())
  1.2865 +DEFINE_SETFIELD(jlong,    long,   Long,    'J', j
  1.2866 +                , HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
  1.2867 +                HOTSPOT_JNI_SETLONGFIELD_RETURN())
  1.2868 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.2869 +DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f
  1.2870 +                , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2871 +                HOTSPOT_JNI_SETFLOATFIELD_RETURN())
  1.2872 +DEFINE_SETFIELD(jdouble,  double, Double,  'D', d
  1.2873 +                , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
  1.2874 +                HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())
  1.2875 +#endif /* USDT2 */
  1.2876 +
  1.2877 +#ifndef USDT2
  1.2878 +DT_RETURN_MARK_DECL(ToReflectedField, jobject);
  1.2879 +#else /* USDT2 */
  1.2880 +DT_RETURN_MARK_DECL(ToReflectedField, jobject
  1.2881 +                    , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
  1.2882 +#endif /* USDT2 */
  1.2883 +
  1.2884 +JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
  1.2885 +  JNIWrapper("ToReflectedField");
  1.2886 +#ifndef USDT2
  1.2887 +  DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry,
  1.2888 +                env, cls, fieldID, isStatic);
  1.2889 +#else /* USDT2 */
  1.2890 +  HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(
  1.2891 +                env, cls, (uintptr_t) fieldID, isStatic);
  1.2892 +#endif /* USDT2 */
  1.2893 +  jobject ret = NULL;
  1.2894 +  DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
  1.2895 +
  1.2896 +  fieldDescriptor fd;
  1.2897 +  bool found = false;
  1.2898 +  Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
  1.2899 +
  1.2900 +  assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");
  1.2901 +
  1.2902 +  if (isStatic) {
  1.2903 +    // Static field. The fieldID a JNIid specifying the field holder and the offset within the Klass*.
  1.2904 +    JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
  1.2905 +    assert(id->is_static_field_id(), "invalid static field id");
  1.2906 +    found = id->find_local_field(&fd);
  1.2907 +  } else {
  1.2908 +    // Non-static field. The fieldID is really the offset of the field within the instanceOop.
  1.2909 +    int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
  1.2910 +    found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);
  1.2911 +  }
  1.2912 +  assert(found, "bad fieldID passed into jni_ToReflectedField");
  1.2913 +  oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);
  1.2914 +  ret = JNIHandles::make_local(env, reflected);
  1.2915 +  return ret;
  1.2916 +JNI_END
  1.2917 +
  1.2918 +
  1.2919 +//
  1.2920 +// Accessing Static Fields
  1.2921 +//
  1.2922 +#ifndef USDT2
  1.2923 +DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);
  1.2924 +#else /* USDT2 */
  1.2925 +DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
  1.2926 +                    , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
  1.2927 +#endif /* USDT2 */
  1.2928 +
  1.2929 +JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
  1.2930 +          const char *name, const char *sig))
  1.2931 +  JNIWrapper("GetStaticFieldID");
  1.2932 +#ifndef USDT2
  1.2933 +  DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig);
  1.2934 +#else /* USDT2 */
  1.2935 +  HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(
  1.2936 +                                     env, clazz, (char *) name, (char *) sig);
  1.2937 +#endif /* USDT2 */
  1.2938 +  jfieldID ret = NULL;
  1.2939 +  DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
  1.2940 +
  1.2941 +  // The class should have been loaded (we have an instance of the class
  1.2942 +  // passed in) so the field and signature should already be in the symbol
  1.2943 +  // table.  If they're not there, the field doesn't exist.
  1.2944 +  TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
  1.2945 +  TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
  1.2946 +  if (fieldname == NULL || signame == NULL) {
  1.2947 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
  1.2948 +  }
  1.2949 +  KlassHandle k(THREAD,
  1.2950 +                java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
  1.2951 +  // Make sure class is initialized before handing id's out to static fields
  1.2952 +  k()->initialize(CHECK_NULL);
  1.2953 +
  1.2954 +  fieldDescriptor fd;
  1.2955 +  if (!k()->oop_is_instance() ||
  1.2956 +      !InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {
  1.2957 +    THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
  1.2958 +  }
  1.2959 +
  1.2960 +  // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
  1.2961 +  JNIid* id = fd.field_holder()->jni_id_for(fd.offset());
  1.2962 +  debug_only(id->set_is_static_field_id();)
  1.2963 +
  1.2964 +  debug_only(id->verify(fd.field_holder()));
  1.2965 +
  1.2966 +  ret = jfieldIDWorkaround::to_static_jfieldID(id);
  1.2967 +  return ret;
  1.2968 +JNI_END
  1.2969 +
  1.2970 +
  1.2971 +JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
  1.2972 +  JNIWrapper("GetStaticObjectField");
  1.2973 +#ifndef USDT2
  1.2974 +  DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
  1.2975 +#else /* USDT2 */
  1.2976 +  HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(
  1.2977 +                                         env, clazz, (uintptr_t) fieldID);
  1.2978 +#endif /* USDT2 */
  1.2979 +#if INCLUDE_JNI_CHECK
  1.2980 +  DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)
  1.2981 +#endif // INCLUDE_JNI_CHECK
  1.2982 +  JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
  1.2983 +  assert(id->is_static_field_id(), "invalid static field id");
  1.2984 +  // Keep JVMTI addition small and only check enabled flag here.
  1.2985 +  // jni_GetField_probe() assumes that is okay to create handles.
  1.2986 +  if (JvmtiExport::should_post_field_access()) {
  1.2987 +    JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
  1.2988 +  }
  1.2989 +  jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
  1.2990 +#ifndef USDT2
  1.2991 +  DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
  1.2992 +#else /* USDT2 */
  1.2993 +  HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(
  1.2994 +                                          ret);
  1.2995 +#endif /* USDT2 */
  1.2996 +  return ret;
  1.2997 +JNI_END
  1.2998 +
  1.2999 +#ifndef USDT2
  1.3000 +#define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
  1.3001 +\
  1.3002 +  DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\
  1.3003 +\
  1.3004 +JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
  1.3005 +  JNIWrapper("GetStatic" XSTR(Result) "Field"); \
  1.3006 +  DTRACE_PROBE3(hotspot_jni, GetStatic##Result##Field__entry, env, clazz, fieldID);\
  1.3007 +  Return ret = 0;\
  1.3008 +  DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
  1.3009 +                     (const Return&)ret);\
  1.3010 +  JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
  1.3011 +  assert(id->is_static_field_id(), "invalid static field id"); \
  1.3012 +  /* Keep JVMTI addition small and only check enabled flag here. */ \
  1.3013 +  /* jni_GetField_probe() assumes that is okay to create handles. */ \
  1.3014 +  if (JvmtiExport::should_post_field_access()) { \
  1.3015 +    JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
  1.3016 +  } \
  1.3017 +  ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
  1.3018 +  return ret;\
  1.3019 +JNI_END
  1.3020 +
  1.3021 +DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean)
  1.3022 +DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte)
  1.3023 +DEFINE_GETSTATICFIELD(jchar,    char,   Char)
  1.3024 +DEFINE_GETSTATICFIELD(jshort,   short,  Short)
  1.3025 +DEFINE_GETSTATICFIELD(jint,     int,    Int)
  1.3026 +DEFINE_GETSTATICFIELD(jlong,    long,   Long)
  1.3027 +DEFINE_GETSTATICFIELD(jfloat,   float,  Float)
  1.3028 +DEFINE_GETSTATICFIELD(jdouble,  double, Double)
  1.3029 +
  1.3030 +#else /* USDT2 */
  1.3031 +
  1.3032 +#define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \
  1.3033 +                              , EntryProbe, ReturnProbe) \
  1.3034 +\
  1.3035 +  DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \
  1.3036 +                          , ReturnProbe);                                          \
  1.3037 +\
  1.3038 +JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
  1.3039 +  JNIWrapper("GetStatic" XSTR(Result) "Field"); \
  1.3040 +  EntryProbe; \
  1.3041 +  Return ret = 0;\
  1.3042 +  DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
  1.3043 +                     (const Return&)ret);\
  1.3044 +  JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
  1.3045 +  assert(id->is_static_field_id(), "invalid static field id"); \
  1.3046 +  /* Keep JVMTI addition small and only check enabled flag here. */ \
  1.3047 +  /* jni_GetField_probe() assumes that is okay to create handles. */ \
  1.3048 +  if (JvmtiExport::should_post_field_access()) { \
  1.3049 +    JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
  1.3050 +  } \
  1.3051 +  ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
  1.3052 +  return ret;\
  1.3053 +JNI_END
  1.3054 +
  1.3055 +DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean
  1.3056 +                      , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))
  1.3057 +DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte
  1.3058 +                      , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref)   )
  1.3059 +DEFINE_GETSTATICFIELD(jchar,    char,   Char
  1.3060 +                      , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref)   )
  1.3061 +DEFINE_GETSTATICFIELD(jshort,   short,  Short
  1.3062 +                      , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref)  )
  1.3063 +DEFINE_GETSTATICFIELD(jint,     int,    Int
  1.3064 +                      , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),     HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref)    )
  1.3065 +DEFINE_GETSTATICFIELD(jlong,    long,   Long
  1.3066 +                      , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref)   )
  1.3067 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.3068 +DEFINE_GETSTATICFIELD(jfloat,   float,  Float
  1.3069 +                      , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN()          )
  1.3070 +DEFINE_GETSTATICFIELD(jdouble,  double, Double
  1.3071 +                      , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),  HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN()         )
  1.3072 +#endif /* USDT2 */
  1.3073 +
  1.3074 +JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
  1.3075 +  JNIWrapper("SetStaticObjectField");
  1.3076 +#ifndef USDT2
  1.3077 +  DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value);
  1.3078 +#else /* USDT2 */
  1.3079 + HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(
  1.3080 +                                        env, clazz, (uintptr_t) fieldID, value);
  1.3081 +#endif /* USDT2 */
  1.3082 +  JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
  1.3083 +  assert(id->is_static_field_id(), "invalid static field id");
  1.3084 +  // Keep JVMTI addition small and only check enabled flag here.
  1.3085 +  // jni_SetField_probe() assumes that is okay to create handles.
  1.3086 +  if (JvmtiExport::should_post_field_modification()) {
  1.3087 +    jvalue field_value;
  1.3088 +    field_value.l = value;
  1.3089 +    JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);
  1.3090 +  }
  1.3091 +  id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
  1.3092 +#ifndef USDT2
  1.3093 +  DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);
  1.3094 +#else /* USDT2 */
  1.3095 +  HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN(
  1.3096 +                                          );
  1.3097 +#endif /* USDT2 */
  1.3098 +JNI_END
  1.3099 +
  1.3100 +
  1.3101 +#ifndef USDT2
  1.3102 +#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \
  1.3103 +\
  1.3104 +JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
  1.3105 +  JNIWrapper("SetStatic" XSTR(Result) "Field"); \
  1.3106 +  FP_SELECT_##Result( \
  1.3107 +     DTRACE_PROBE4(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID, value), \
  1.3108 +     DTRACE_PROBE3(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID)); \
  1.3109 +\
  1.3110 +  JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
  1.3111 +  assert(id->is_static_field_id(), "invalid static field id"); \
  1.3112 +  /* Keep JVMTI addition small and only check enabled flag here. */ \
  1.3113 +  /* jni_SetField_probe() assumes that is okay to create handles. */ \
  1.3114 +  if (JvmtiExport::should_post_field_modification()) { \
  1.3115 +    jvalue field_value; \
  1.3116 +    field_value.unionType = value; \
  1.3117 +    JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
  1.3118 +  } \
  1.3119 +  id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
  1.3120 +  DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\
  1.3121 +JNI_END
  1.3122 +
  1.3123 +DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z)
  1.3124 +DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b)
  1.3125 +DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c)
  1.3126 +DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s)
  1.3127 +DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i)
  1.3128 +DEFINE_SETSTATICFIELD(jlong,    long,   Long,    'J', j)
  1.3129 +DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f)
  1.3130 +DEFINE_SETSTATICFIELD(jdouble,  double, Double,  'D', d)
  1.3131 +
  1.3132 +#else /* USDT2 */
  1.3133 +
  1.3134 +#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \
  1.3135 +                              , EntryProbe, ReturnProbe) \
  1.3136 +\
  1.3137 +JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
  1.3138 +  JNIWrapper("SetStatic" XSTR(Result) "Field"); \
  1.3139 +  EntryProbe; \
  1.3140 +\
  1.3141 +  JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
  1.3142 +  assert(id->is_static_field_id(), "invalid static field id"); \
  1.3143 +  /* Keep JVMTI addition small and only check enabled flag here. */ \
  1.3144 +  /* jni_SetField_probe() assumes that is okay to create handles. */ \
  1.3145 +  if (JvmtiExport::should_post_field_modification()) { \
  1.3146 +    jvalue field_value; \
  1.3147 +    field_value.unionType = value; \
  1.3148 +    JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
  1.3149 +  } \
  1.3150 +  id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
  1.3151 +  ReturnProbe;\
  1.3152 +JNI_END
  1.3153 +
  1.3154 +DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z
  1.3155 +                      , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
  1.3156 +                      HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
  1.3157 +DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b
  1.3158 +                      , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
  1.3159 +                      HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())
  1.3160 +DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c
  1.3161 +                      , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
  1.3162 +                      HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())
  1.3163 +DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s
  1.3164 +                      , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
  1.3165 +                      HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())
  1.3166 +DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i
  1.3167 +                      , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
  1.3168 +                      HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())
  1.3169 +DEFINE_SETSTATICFIELD(jlong,    long,   Long,    'J', j
  1.3170 +                      , HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
  1.3171 +                      HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN())
  1.3172 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.3173 +DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f
  1.3174 +                      , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
  1.3175 +                      HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())
  1.3176 +DEFINE_SETSTATICFIELD(jdouble,  double, Double,  'D', d
  1.3177 +                      , HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
  1.3178 +                      HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN())
  1.3179 +#endif /* USDT2 */
  1.3180 +
  1.3181 +//
  1.3182 +// String Operations
  1.3183 +//
  1.3184 +
  1.3185 +// Unicode Interface
  1.3186 +
  1.3187 +#ifndef USDT2
  1.3188 +DT_RETURN_MARK_DECL(NewString, jstring);
  1.3189 +#else /* USDT2 */
  1.3190 +DT_RETURN_MARK_DECL(NewString, jstring
  1.3191 +                    , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
  1.3192 +#endif /* USDT2 */
  1.3193 +
  1.3194 +JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
  1.3195 +  JNIWrapper("NewString");
  1.3196 +#ifndef USDT2
  1.3197 +  DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len);
  1.3198 +#else /* USDT2 */
  1.3199 + HOTSPOT_JNI_NEWSTRING_ENTRY(
  1.3200 +                             env, (uint16_t *) unicodeChars, len);
  1.3201 +#endif /* USDT2 */
  1.3202 +  jstring ret = NULL;
  1.3203 +  DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
  1.3204 +  oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
  1.3205 +  ret = (jstring) JNIHandles::make_local(env, string);
  1.3206 +  return ret;
  1.3207 +JNI_END
  1.3208 +
  1.3209 +
  1.3210 +JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
  1.3211 +  JNIWrapper("GetStringLength");
  1.3212 +#ifndef USDT2
  1.3213 +  DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string);
  1.3214 +#else /* USDT2 */
  1.3215 +  HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(
  1.3216 +                                    env, string);
  1.3217 +#endif /* USDT2 */
  1.3218 +  jsize ret = 0;
  1.3219 +  oop s = JNIHandles::resolve_non_null(string);
  1.3220 +  if (java_lang_String::value(s) != NULL) {
  1.3221 +    ret = java_lang_String::length(s);
  1.3222 +  }
  1.3223 +#ifndef USDT2
  1.3224 +  DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
  1.3225 +#else /* USDT2 */
  1.3226 + HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(
  1.3227 +                                    ret);
  1.3228 +#endif /* USDT2 */
  1.3229 +  return ret;
  1.3230 +JNI_END
  1.3231 +
  1.3232 +
  1.3233 +JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
  1.3234 +  JNIEnv *env, jstring string, jboolean *isCopy))
  1.3235 +  JNIWrapper("GetStringChars");
  1.3236 +#ifndef USDT2
  1.3237 +  DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy);
  1.3238 +#else /* USDT2 */
  1.3239 + HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
  1.3240 +                                  env, string, (uintptr_t *) isCopy);
  1.3241 +#endif /* USDT2 */
  1.3242 +  jchar* buf = NULL;
  1.3243 +  oop s = JNIHandles::resolve_non_null(string);
  1.3244 +  typeArrayOop s_value = java_lang_String::value(s);
  1.3245 +  if (s_value != NULL) {
  1.3246 +    int s_len = java_lang_String::length(s);
  1.3247 +    int s_offset = java_lang_String::offset(s);
  1.3248 +    buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal);  // add one for zero termination
  1.3249 +    /* JNI Specification states return NULL on OOM */
  1.3250 +    if (buf != NULL) {
  1.3251 +      if (s_len > 0) {
  1.3252 +        memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
  1.3253 +      }
  1.3254 +      buf[s_len] = 0;
  1.3255 +      //%note jni_5
  1.3256 +      if (isCopy != NULL) {
  1.3257 +        *isCopy = JNI_TRUE;
  1.3258 +      }
  1.3259 +    }
  1.3260 +  }
  1.3261 +#ifndef USDT2
  1.3262 +  DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
  1.3263 +#else /* USDT2 */
  1.3264 +  HOTSPOT_JNI_GETSTRINGCHARS_RETURN(
  1.3265 +                                    buf);
  1.3266 +#endif /* USDT2 */
  1.3267 +  return buf;
  1.3268 +JNI_END
  1.3269 +
  1.3270 +
  1.3271 +JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
  1.3272 +  JNIWrapper("ReleaseStringChars");
  1.3273 +#ifndef USDT2
  1.3274 +  DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars);
  1.3275 +#else /* USDT2 */
  1.3276 +  HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(
  1.3277 +                                       env, str, (uint16_t *) chars);
  1.3278 +#endif /* USDT2 */
  1.3279 +  //%note jni_6
  1.3280 +  if (chars != NULL) {
  1.3281 +    // Since String objects are supposed to be immutable, don't copy any
  1.3282 +    // new data back.  A bad user will have to go after the char array.
  1.3283 +    FreeHeap((void*) chars);
  1.3284 +  }
  1.3285 +#ifndef USDT2
  1.3286 +  DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return);
  1.3287 +#else /* USDT2 */
  1.3288 +  HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN(
  1.3289 +);
  1.3290 +#endif /* USDT2 */
  1.3291 +JNI_END
  1.3292 +
  1.3293 +
  1.3294 +// UTF Interface
  1.3295 +
  1.3296 +#ifndef USDT2
  1.3297 +DT_RETURN_MARK_DECL(NewStringUTF, jstring);
  1.3298 +#else /* USDT2 */
  1.3299 +DT_RETURN_MARK_DECL(NewStringUTF, jstring
  1.3300 +                    , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
  1.3301 +#endif /* USDT2 */
  1.3302 +
  1.3303 +JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
  1.3304 +  JNIWrapper("NewStringUTF");
  1.3305 +#ifndef USDT2
  1.3306 +  DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes);
  1.3307 +#else /* USDT2 */
  1.3308 +  HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(
  1.3309 +                                 env, (char *) bytes);
  1.3310 +#endif /* USDT2 */
  1.3311 +  jstring ret;
  1.3312 +  DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
  1.3313 +
  1.3314 +  oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
  1.3315 +  ret = (jstring) JNIHandles::make_local(env, result);
  1.3316 +  return ret;
  1.3317 +JNI_END
  1.3318 +
  1.3319 +
  1.3320 +JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
  1.3321 +  JNIWrapper("GetStringUTFLength");
  1.3322 +#ifndef USDT2
  1.3323 +  DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string);
  1.3324 +#else /* USDT2 */
  1.3325 + HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(
  1.3326 +                                      env, string);
  1.3327 +#endif /* USDT2 */
  1.3328 +  jsize ret = 0;
  1.3329 +  oop java_string = JNIHandles::resolve_non_null(string);
  1.3330 +  if (java_lang_String::value(java_string) != NULL) {
  1.3331 +    ret = java_lang_String::utf8_length(java_string);
  1.3332 +  }
  1.3333 +#ifndef USDT2
  1.3334 +  DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
  1.3335 +#else /* USDT2 */
  1.3336 +  HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(
  1.3337 +                                        ret);
  1.3338 +#endif /* USDT2 */
  1.3339 +  return ret;
  1.3340 +JNI_END
  1.3341 +
  1.3342 +
  1.3343 +JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
  1.3344 +  JNIWrapper("GetStringUTFChars");
  1.3345 +#ifndef USDT2
  1.3346 +  DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy);
  1.3347 +#else /* USDT2 */
  1.3348 + HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(
  1.3349 +                                     env, string, (uintptr_t *) isCopy);
  1.3350 +#endif /* USDT2 */
  1.3351 +  char* result = NULL;
  1.3352 +  oop java_string = JNIHandles::resolve_non_null(string);
  1.3353 +  if (java_lang_String::value(java_string) != NULL) {
  1.3354 +    size_t length = java_lang_String::utf8_length(java_string);
  1.3355 +    /* JNI Specification states return NULL on OOM */
  1.3356 +    result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);
  1.3357 +    if (result != NULL) {
  1.3358 +      java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
  1.3359 +      if (isCopy != NULL) {
  1.3360 +        *isCopy = JNI_TRUE;
  1.3361 +      }
  1.3362 +    }
  1.3363 +  }
  1.3364 +#ifndef USDT2
  1.3365 +  DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
  1.3366 +#else /* USDT2 */
  1.3367 + HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(
  1.3368 +                                      result);
  1.3369 +#endif /* USDT2 */
  1.3370 +  return result;
  1.3371 +JNI_END
  1.3372 +
  1.3373 +
  1.3374 +JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
  1.3375 +  JNIWrapper("ReleaseStringUTFChars");
  1.3376 +#ifndef USDT2
  1.3377 +  DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars);
  1.3378 +#else /* USDT2 */
  1.3379 + HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(
  1.3380 +                                         env, str, (char *) chars);
  1.3381 +#endif /* USDT2 */
  1.3382 +  if (chars != NULL) {
  1.3383 +    FreeHeap((char*) chars);
  1.3384 +  }
  1.3385 +#ifndef USDT2
  1.3386 +  DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return);
  1.3387 +#else /* USDT2 */
  1.3388 +HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN(
  1.3389 +);
  1.3390 +#endif /* USDT2 */
  1.3391 +JNI_END
  1.3392 +
  1.3393 +
  1.3394 +JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
  1.3395 +  JNIWrapper("GetArrayLength");
  1.3396 +#ifndef USDT2
  1.3397 +  DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array);
  1.3398 +#else /* USDT2 */
  1.3399 + HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(
  1.3400 +                                  env, array);
  1.3401 +#endif /* USDT2 */
  1.3402 +  arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
  1.3403 +  assert(a->is_array(), "must be array");
  1.3404 +  jsize ret = a->length();
  1.3405 +#ifndef USDT2
  1.3406 +  DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret);
  1.3407 +#else /* USDT2 */
  1.3408 + HOTSPOT_JNI_GETARRAYLENGTH_RETURN(
  1.3409 +                                   ret);
  1.3410 +#endif /* USDT2 */
  1.3411 +  return ret;
  1.3412 +JNI_END
  1.3413 +
  1.3414 +
  1.3415 +//
  1.3416 +// Object Array Operations
  1.3417 +//
  1.3418 +
  1.3419 +#ifndef USDT2
  1.3420 +DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);
  1.3421 +#else /* USDT2 */
  1.3422 +DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
  1.3423 +                    , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
  1.3424 +#endif /* USDT2 */
  1.3425 +
  1.3426 +JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
  1.3427 +  JNIWrapper("NewObjectArray");
  1.3428 +#ifndef USDT2
  1.3429 +  DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement);
  1.3430 +#else /* USDT2 */
  1.3431 + HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(
  1.3432 +                                  env, length, elementClass, initialElement);
  1.3433 +#endif /* USDT2 */
  1.3434 +  jobjectArray ret = NULL;
  1.3435 +  DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
  1.3436 +  KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));
  1.3437 +  Klass* ako = ek()->array_klass(CHECK_NULL);
  1.3438 +  KlassHandle ak = KlassHandle(THREAD, ako);
  1.3439 +  ObjArrayKlass::cast(ak())->initialize(CHECK_NULL);
  1.3440 +  objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL);
  1.3441 +  oop initial_value = JNIHandles::resolve(initialElement);
  1.3442 +  if (initial_value != NULL) {  // array already initialized with NULL
  1.3443 +    for (int index = 0; index < length; index++) {
  1.3444 +      result->obj_at_put(index, initial_value);
  1.3445 +    }
  1.3446 +  }
  1.3447 +  ret = (jobjectArray) JNIHandles::make_local(env, result);
  1.3448 +  return ret;
  1.3449 +JNI_END
  1.3450 +
  1.3451 +#ifndef USDT2
  1.3452 +DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);
  1.3453 +#else /* USDT2 */
  1.3454 +DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
  1.3455 +                    , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
  1.3456 +#endif /* USDT2 */
  1.3457 +
  1.3458 +JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
  1.3459 +  JNIWrapper("GetObjectArrayElement");
  1.3460 +#ifndef USDT2
  1.3461 +  DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index);
  1.3462 +#else /* USDT2 */
  1.3463 + HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(
  1.3464 +                                         env, array, index);
  1.3465 +#endif /* USDT2 */
  1.3466 +  jobject ret = NULL;
  1.3467 +  DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
  1.3468 +  objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
  1.3469 +  if (a->is_within_bounds(index)) {
  1.3470 +    ret = JNIHandles::make_local(env, a->obj_at(index));
  1.3471 +    return ret;
  1.3472 +  } else {
  1.3473 +    char buf[jintAsStringSize];
  1.3474 +    sprintf(buf, "%d", index);
  1.3475 +    THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
  1.3476 +  }
  1.3477 +JNI_END
  1.3478 +
  1.3479 +#ifndef USDT2
  1.3480 +DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);
  1.3481 +#else /* USDT2 */
  1.3482 +DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
  1.3483 +                         , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
  1.3484 +#endif /* USDT2 */
  1.3485 +
  1.3486 +JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
  1.3487 +  JNIWrapper("SetObjectArrayElement");
  1.3488 +#ifndef USDT2
  1.3489 +  DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value);
  1.3490 +#else /* USDT2 */
  1.3491 + HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(
  1.3492 +                                         env, array, index, value);
  1.3493 +#endif /* USDT2 */
  1.3494 +  DT_VOID_RETURN_MARK(SetObjectArrayElement);
  1.3495 +
  1.3496 +  objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
  1.3497 +  oop v = JNIHandles::resolve(value);
  1.3498 +  if (a->is_within_bounds(index)) {
  1.3499 +    if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {
  1.3500 +      a->obj_at_put(index, v);
  1.3501 +    } else {
  1.3502 +      THROW(vmSymbols::java_lang_ArrayStoreException());
  1.3503 +    }
  1.3504 +  } else {
  1.3505 +    char buf[jintAsStringSize];
  1.3506 +    sprintf(buf, "%d", index);
  1.3507 +    THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
  1.3508 +  }
  1.3509 +JNI_END
  1.3510 +
  1.3511 +
  1.3512 +#ifndef USDT2
  1.3513 +#define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \
  1.3514 +\
  1.3515 +  DT_RETURN_MARK_DECL(New##Result##Array, Return); \
  1.3516 +\
  1.3517 +JNI_ENTRY(Return, \
  1.3518 +          jni_New##Result##Array(JNIEnv *env, jsize len)) \
  1.3519 +  JNIWrapper("New" XSTR(Result) "Array"); \
  1.3520 +  DTRACE_PROBE2(hotspot_jni, New##Result##Array__entry, env, len);\
  1.3521 +  Return ret = NULL;\
  1.3522 +  DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
  1.3523 +\
  1.3524 +  oop obj= oopFactory::Allocator(len, CHECK_0); \
  1.3525 +  ret = (Return) JNIHandles::make_local(env, obj); \
  1.3526 +  return ret;\
  1.3527 +JNI_END
  1.3528 +
  1.3529 +DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean)
  1.3530 +DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte)
  1.3531 +DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short)
  1.3532 +DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char)
  1.3533 +DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int)
  1.3534 +DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long)
  1.3535 +DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float)
  1.3536 +DEFINE_NEWSCALARARRAY(jdoubleArray,  new_doubleArray, Double)
  1.3537 +
  1.3538 +#else /* USDT2 */
  1.3539 +
  1.3540 +#define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
  1.3541 +                              ,EntryProbe,ReturnProbe)  \
  1.3542 +\
  1.3543 +  DT_RETURN_MARK_DECL(New##Result##Array, Return \
  1.3544 +                      , ReturnProbe); \
  1.3545 +\
  1.3546 +JNI_ENTRY(Return, \
  1.3547 +          jni_New##Result##Array(JNIEnv *env, jsize len)) \
  1.3548 +  JNIWrapper("New" XSTR(Result) "Array"); \
  1.3549 +  EntryProbe; \
  1.3550 +  Return ret = NULL;\
  1.3551 +  DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
  1.3552 +\
  1.3553 +  oop obj= oopFactory::Allocator(len, CHECK_0); \
  1.3554 +  ret = (Return) JNIHandles::make_local(env, obj); \
  1.3555 +  return ret;\
  1.3556 +JNI_END
  1.3557 +
  1.3558 +DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean,
  1.3559 +                      HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),
  1.3560 +                      HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))
  1.3561 +DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte,
  1.3562 +                      HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),
  1.3563 +                      HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))
  1.3564 +DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short,
  1.3565 +                      HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),
  1.3566 +                      HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))
  1.3567 +DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char,
  1.3568 +                      HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),
  1.3569 +                      HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))
  1.3570 +DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int,
  1.3571 +                      HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),
  1.3572 +                      HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))
  1.3573 +DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long,
  1.3574 +                      HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),
  1.3575 +                      HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))
  1.3576 +DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float,
  1.3577 +                      HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),
  1.3578 +                      HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))
  1.3579 +DEFINE_NEWSCALARARRAY(jdoubleArray,  new_doubleArray, Double,
  1.3580 +                      HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len),
  1.3581 +                      HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref))
  1.3582 +#endif /* USDT2 */
  1.3583 +
  1.3584 +// Return an address which will fault if the caller writes to it.
  1.3585 +
  1.3586 +static char* get_bad_address() {
  1.3587 +  static char* bad_address = NULL;
  1.3588 +  if (bad_address == NULL) {
  1.3589 +    size_t size = os::vm_allocation_granularity();
  1.3590 +    bad_address = os::reserve_memory(size);
  1.3591 +    if (bad_address != NULL) {
  1.3592 +      os::protect_memory(bad_address, size, os::MEM_PROT_READ,
  1.3593 +                         /*is_committed*/false);
  1.3594 +    }
  1.3595 +  }
  1.3596 +  return bad_address;
  1.3597 +}
  1.3598 +
  1.3599 +
  1.3600 +#ifndef USDT2
  1.3601 +#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag) \
  1.3602 +\
  1.3603 +JNI_QUICK_ENTRY(ElementType*, \
  1.3604 +          jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
  1.3605 +  JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
  1.3606 +  DTRACE_PROBE3(hotspot_jni, Get##Result##ArrayElements__entry, env, array, isCopy);\
  1.3607 +  /* allocate an chunk of memory in c land */ \
  1.3608 +  typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3609 +  ElementType* result; \
  1.3610 +  int len = a->length(); \
  1.3611 +  if (len == 0) { \
  1.3612 +    /* Empty array: legal but useless, can't return NULL. \
  1.3613 +     * Return a pointer to something useless. \
  1.3614 +     * Avoid asserts in typeArrayOop. */ \
  1.3615 +    result = (ElementType*)get_bad_address(); \
  1.3616 +  } else { \
  1.3617 +    /* JNI Specification states return NULL on OOM */                    \
  1.3618 +    result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
  1.3619 +    if (result != NULL) {                                                \
  1.3620 +      /* copy the array to the c chunk */                                \
  1.3621 +      memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len);      \
  1.3622 +      if (isCopy) {                                                      \
  1.3623 +        *isCopy = JNI_TRUE;                                              \
  1.3624 +      }                                                                  \
  1.3625 +    }                                                                    \
  1.3626 +  } \
  1.3627 +  DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\
  1.3628 +  return result; \
  1.3629 +JNI_END
  1.3630 +
  1.3631 +DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
  1.3632 +DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
  1.3633 +DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
  1.3634 +DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
  1.3635 +DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
  1.3636 +DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
  1.3637 +DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
  1.3638 +DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
  1.3639 +
  1.3640 +#else /* USDT2 */
  1.3641 +
  1.3642 +#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
  1.3643 +                                      , EntryProbe, ReturnProbe) \
  1.3644 +\
  1.3645 +JNI_QUICK_ENTRY(ElementType*, \
  1.3646 +          jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
  1.3647 +  JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
  1.3648 +  EntryProbe; \
  1.3649 +  /* allocate an chunk of memory in c land */ \
  1.3650 +  typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3651 +  ElementType* result; \
  1.3652 +  int len = a->length(); \
  1.3653 +  if (len == 0) { \
  1.3654 +    /* Empty array: legal but useless, can't return NULL. \
  1.3655 +     * Return a pointer to something useless. \
  1.3656 +     * Avoid asserts in typeArrayOop. */ \
  1.3657 +    result = (ElementType*)get_bad_address(); \
  1.3658 +  } else { \
  1.3659 +    /* JNI Specification states return NULL on OOM */                    \
  1.3660 +    result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \
  1.3661 +    if (result != NULL) {                                                \
  1.3662 +      /* copy the array to the c chunk */                                \
  1.3663 +      memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len);      \
  1.3664 +      if (isCopy) {                                                      \
  1.3665 +        *isCopy = JNI_TRUE;                                              \
  1.3666 +      }                                                                  \
  1.3667 +    }                                                                    \
  1.3668 +  } \
  1.3669 +  ReturnProbe; \
  1.3670 +  return result; \
  1.3671 +JNI_END
  1.3672 +
  1.3673 +DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
  1.3674 +                              , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
  1.3675 +                              HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))
  1.3676 +DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
  1.3677 +                              , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
  1.3678 +                              HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))
  1.3679 +DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
  1.3680 +                              , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
  1.3681 +                              HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result))
  1.3682 +DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
  1.3683 +                              , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
  1.3684 +                              HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))
  1.3685 +DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
  1.3686 +                              , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
  1.3687 +                              HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))
  1.3688 +DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
  1.3689 +                              , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
  1.3690 +                              HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
  1.3691 +// Float and double probes don't return value because dtrace doesn't currently support it
  1.3692 +DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
  1.3693 +                              , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
  1.3694 +                              HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
  1.3695 +DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double
  1.3696 +                              , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
  1.3697 +                              HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
  1.3698 +#endif /* USDT2 */
  1.3699 +
  1.3700 +#ifndef USDT2
  1.3701 +#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag) \
  1.3702 +\
  1.3703 +JNI_QUICK_ENTRY(void, \
  1.3704 +          jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
  1.3705 +                                             ElementType *buf, jint mode)) \
  1.3706 +  JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
  1.3707 +  DTRACE_PROBE4(hotspot_jni, Release##Result##ArrayElements__entry, env, array, buf, mode);\
  1.3708 +  typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3709 +  int len = a->length(); \
  1.3710 +  if (len != 0) {   /* Empty array:  nothing to free or copy. */  \
  1.3711 +    if ((mode == 0) || (mode == JNI_COMMIT)) { \
  1.3712 +      memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
  1.3713 +    } \
  1.3714 +    if ((mode == 0) || (mode == JNI_ABORT)) { \
  1.3715 +      FreeHeap(buf); \
  1.3716 +    } \
  1.3717 +  } \
  1.3718 +  DTRACE_PROBE(hotspot_jni, Release##Result##ArrayElements__return);\
  1.3719 +JNI_END
  1.3720 +
  1.3721 +DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
  1.3722 +DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
  1.3723 +DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
  1.3724 +DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
  1.3725 +DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
  1.3726 +DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
  1.3727 +DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
  1.3728 +DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
  1.3729 +
  1.3730 +#else /* USDT2 */
  1.3731 +
  1.3732 +#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
  1.3733 +                                          , EntryProbe, ReturnProbe);\
  1.3734 +\
  1.3735 +JNI_QUICK_ENTRY(void, \
  1.3736 +          jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
  1.3737 +                                             ElementType *buf, jint mode)) \
  1.3738 +  JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
  1.3739 +  EntryProbe; \
  1.3740 +  typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3741 +  int len = a->length(); \
  1.3742 +  if (len != 0) {   /* Empty array:  nothing to free or copy. */  \
  1.3743 +    if ((mode == 0) || (mode == JNI_COMMIT)) { \
  1.3744 +      memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
  1.3745 +    } \
  1.3746 +    if ((mode == 0) || (mode == JNI_ABORT)) { \
  1.3747 +      FreeHeap(buf); \
  1.3748 +    } \
  1.3749 +  } \
  1.3750 +  ReturnProbe; \
  1.3751 +JNI_END
  1.3752 +
  1.3753 +DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
  1.3754 +                                  , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
  1.3755 +                                  HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
  1.3756 +DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
  1.3757 +                                  , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
  1.3758 +                                  HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
  1.3759 +DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
  1.3760 +                                  ,  HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
  1.3761 +                                  HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())
  1.3762 +DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
  1.3763 +                                  ,  HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
  1.3764 +                                  HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())
  1.3765 +DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
  1.3766 +                                  , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),
  1.3767 +                                  HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())
  1.3768 +DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
  1.3769 +                                  , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
  1.3770 +                                  HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())
  1.3771 +DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
  1.3772 +                                  , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
  1.3773 +                                  HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
  1.3774 +DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double
  1.3775 +                                  , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
  1.3776 +                                  HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
  1.3777 +#endif /* USDT2 */
  1.3778 +
  1.3779 +#ifndef USDT2
  1.3780 +#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
  1.3781 +  DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion);\
  1.3782 +\
  1.3783 +JNI_ENTRY(void, \
  1.3784 +jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
  1.3785 +             jsize len, ElementType *buf)) \
  1.3786 +  JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
  1.3787 +  DTRACE_PROBE5(hotspot_jni, Get##Result##ArrayRegion__entry, env, array, start, len, buf);\
  1.3788 +  DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
  1.3789 +  typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3790 +  if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
  1.3791 +    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
  1.3792 +  } else { \
  1.3793 +    if (len > 0) { \
  1.3794 +      int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \
  1.3795 +      memcpy((u_char*) buf, \
  1.3796 +             (u_char*) src->Tag##_at_addr(start), \
  1.3797 +             len << sc);                          \
  1.3798 +    } \
  1.3799 +  } \
  1.3800 +JNI_END
  1.3801 +
  1.3802 +DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool)
  1.3803 +DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte)
  1.3804 +DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short)
  1.3805 +DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char)
  1.3806 +DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int)
  1.3807 +DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long)
  1.3808 +DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float)
  1.3809 +DEFINE_GETSCALARARRAYREGION(T_DOUBLE,  jdouble, Double,  double)
  1.3810 +
  1.3811 +#else /* USDT2 */
  1.3812 +
  1.3813 +#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
  1.3814 +                                    , EntryProbe, ReturnProbe); \
  1.3815 +  DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
  1.3816 +                           , ReturnProbe); \
  1.3817 +\
  1.3818 +JNI_ENTRY(void, \
  1.3819 +jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
  1.3820 +             jsize len, ElementType *buf)) \
  1.3821 +  JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
  1.3822 +  EntryProbe; \
  1.3823 +  DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
  1.3824 +  typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3825 +  if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
  1.3826 +    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
  1.3827 +  } else { \
  1.3828 +    if (len > 0) { \
  1.3829 +      int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \
  1.3830 +      memcpy((u_char*) buf, \
  1.3831 +             (u_char*) src->Tag##_at_addr(start), \
  1.3832 +             len << sc);                          \
  1.3833 +    } \
  1.3834 +  } \
  1.3835 +JNI_END
  1.3836 +
  1.3837 +DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
  1.3838 +                            , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
  1.3839 +                            HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
  1.3840 +DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte
  1.3841 +                            ,  HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
  1.3842 +                            HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
  1.3843 +DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short
  1.3844 +                            , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
  1.3845 +                            HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());
  1.3846 +DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char
  1.3847 +                            ,  HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),
  1.3848 +                            HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());
  1.3849 +DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int
  1.3850 +                            , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),
  1.3851 +                            HOTSPOT_JNI_GETINTARRAYREGION_RETURN());
  1.3852 +DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long
  1.3853 +                            ,  HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
  1.3854 +                            HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());
  1.3855 +DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float
  1.3856 +                            , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
  1.3857 +                            HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
  1.3858 +DEFINE_GETSCALARARRAYREGION(T_DOUBLE,  jdouble, Double,  double
  1.3859 +                            , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
  1.3860 +                            HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
  1.3861 +#endif /* USDT2 */
  1.3862 +
  1.3863 +#ifndef USDT2
  1.3864 +#define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
  1.3865 +  DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion);\
  1.3866 +\
  1.3867 +JNI_ENTRY(void, \
  1.3868 +jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
  1.3869 +             jsize len, const ElementType *buf)) \
  1.3870 +  JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
  1.3871 +  DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\
  1.3872 +  DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
  1.3873 +  typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3874 +  if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
  1.3875 +    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
  1.3876 +  } else { \
  1.3877 +    if (len > 0) { \
  1.3878 +      int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
  1.3879 +      memcpy((u_char*) dst->Tag##_at_addr(start), \
  1.3880 +             (u_char*) buf, \
  1.3881 +             len << sc);    \
  1.3882 +    } \
  1.3883 +  } \
  1.3884 +JNI_END
  1.3885 +
  1.3886 +DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool)
  1.3887 +DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte)
  1.3888 +DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short)
  1.3889 +DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char)
  1.3890 +DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int)
  1.3891 +DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long)
  1.3892 +DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float)
  1.3893 +DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double)
  1.3894 +
  1.3895 +#else /* USDT2 */
  1.3896 +
  1.3897 +#define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
  1.3898 +                                    , EntryProbe, ReturnProbe); \
  1.3899 +  DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
  1.3900 +                           ,ReturnProbe);           \
  1.3901 +\
  1.3902 +JNI_ENTRY(void, \
  1.3903 +jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
  1.3904 +             jsize len, const ElementType *buf)) \
  1.3905 +  JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
  1.3906 +  EntryProbe; \
  1.3907 +  DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
  1.3908 +  typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
  1.3909 +  if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
  1.3910 +    THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
  1.3911 +  } else { \
  1.3912 +    if (len > 0) { \
  1.3913 +      int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \
  1.3914 +      memcpy((u_char*) dst->Tag##_at_addr(start), \
  1.3915 +             (u_char*) buf, \
  1.3916 +             len << sc);    \
  1.3917 +    } \
  1.3918 +  } \
  1.3919 +JNI_END
  1.3920 +
  1.3921 +DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
  1.3922 +                            , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
  1.3923 +                            HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
  1.3924 +DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte
  1.3925 +                            , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
  1.3926 +                            HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
  1.3927 +DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short
  1.3928 +                            , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
  1.3929 +                            HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())
  1.3930 +DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char
  1.3931 +                            , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
  1.3932 +                            HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())
  1.3933 +DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int
  1.3934 +                            , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),
  1.3935 +                            HOTSPOT_JNI_SETINTARRAYREGION_RETURN())
  1.3936 +DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long
  1.3937 +                            , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
  1.3938 +                            HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
  1.3939 +DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float
  1.3940 +                            , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
  1.3941 +                            HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
  1.3942 +DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double
  1.3943 +                            , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
  1.3944 +                            HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
  1.3945 +#endif /* USDT2 */
  1.3946 +
  1.3947 +
  1.3948 +//
  1.3949 +// Interception of natives
  1.3950 +//
  1.3951 +
  1.3952 +// The RegisterNatives call being attempted tried to register with a method that
  1.3953 +// is not native.  Ask JVM TI what prefixes have been specified.  Then check
  1.3954 +// to see if the native method is now wrapped with the prefixes.  See the
  1.3955 +// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
  1.3956 +static Method* find_prefixed_native(KlassHandle k,
  1.3957 +                                      Symbol* name, Symbol* signature, TRAPS) {
  1.3958 +#if INCLUDE_JVMTI
  1.3959 +  ResourceMark rm(THREAD);
  1.3960 +  Method* method;
  1.3961 +  int name_len = name->utf8_length();
  1.3962 +  char* name_str = name->as_utf8();
  1.3963 +  int prefix_count;
  1.3964 +  char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
  1.3965 +  for (int i = 0; i < prefix_count; i++) {
  1.3966 +    char* prefix = prefixes[i];
  1.3967 +    int prefix_len = (int)strlen(prefix);
  1.3968 +
  1.3969 +    // try adding this prefix to the method name and see if it matches another method name
  1.3970 +    int trial_len = name_len + prefix_len;
  1.3971 +    char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
  1.3972 +    strcpy(trial_name_str, prefix);
  1.3973 +    strcat(trial_name_str, name_str);
  1.3974 +    TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
  1.3975 +    if (trial_name == NULL) {
  1.3976 +      continue; // no such symbol, so this prefix wasn't used, try the next prefix
  1.3977 +    }
  1.3978 +    method = k()->lookup_method(trial_name, signature);
  1.3979 +    if (method == NULL) {
  1.3980 +      continue; // signature doesn't match, try the next prefix
  1.3981 +    }
  1.3982 +    if (method->is_native()) {
  1.3983 +      method->set_is_prefixed_native();
  1.3984 +      return method; // wahoo, we found a prefixed version of the method, return it
  1.3985 +    }
  1.3986 +    // found as non-native, so prefix is good, add it, probably just need more prefixes
  1.3987 +    name_len = trial_len;
  1.3988 +    name_str = trial_name_str;
  1.3989 +  }
  1.3990 +#endif // INCLUDE_JVMTI
  1.3991 +  return NULL; // not found
  1.3992 +}
  1.3993 +
  1.3994 +static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
  1.3995 +  Method* method = k()->lookup_method(name, signature);
  1.3996 +  if (method == NULL) {
  1.3997 +    ResourceMark rm;
  1.3998 +    stringStream st;
  1.3999 +    st.print("Method %s name or signature does not match",
  1.4000 +             Method::name_and_sig_as_C_string(k(), name, signature));
  1.4001 +    THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
  1.4002 +  }
  1.4003 +  if (!method->is_native()) {
  1.4004 +    // trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
  1.4005 +    method = find_prefixed_native(k, name, signature, THREAD);
  1.4006 +    if (method == NULL) {
  1.4007 +      ResourceMark rm;
  1.4008 +      stringStream st;
  1.4009 +      st.print("Method %s is not declared as native",
  1.4010 +               Method::name_and_sig_as_C_string(k(), name, signature));
  1.4011 +      THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
  1.4012 +    }
  1.4013 +  }
  1.4014 +
  1.4015 +  if (entry != NULL) {
  1.4016 +    method->set_native_function(entry,
  1.4017 +      Method::native_bind_event_is_interesting);
  1.4018 +  } else {
  1.4019 +    method->clear_native_function();
  1.4020 +  }
  1.4021 +  if (PrintJNIResolving) {
  1.4022 +    ResourceMark rm(THREAD);
  1.4023 +    tty->print_cr("[Registering JNI native method %s.%s]",
  1.4024 +      method->method_holder()->external_name(),
  1.4025 +      method->name()->as_C_string());
  1.4026 +  }
  1.4027 +  return true;
  1.4028 +}
  1.4029 +
  1.4030 +#ifndef USDT2
  1.4031 +DT_RETURN_MARK_DECL(RegisterNatives, jint);
  1.4032 +#else /* USDT2 */
  1.4033 +DT_RETURN_MARK_DECL(RegisterNatives, jint
  1.4034 +                    , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
  1.4035 +#endif /* USDT2 */
  1.4036 +
  1.4037 +JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
  1.4038 +                                    const JNINativeMethod *methods,
  1.4039 +                                    jint nMethods))
  1.4040 +  JNIWrapper("RegisterNatives");
  1.4041 +#ifndef USDT2
  1.4042 +  DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);
  1.4043 +#else /* USDT2 */
  1.4044 +  HOTSPOT_JNI_REGISTERNATIVES_ENTRY(
  1.4045 +                                    env, clazz, (void *) methods, nMethods);
  1.4046 +#endif /* USDT2 */
  1.4047 +  jint ret = 0;
  1.4048 +  DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
  1.4049 +
  1.4050 +  KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
  1.4051 +
  1.4052 +  for (int index = 0; index < nMethods; index++) {
  1.4053 +    const char* meth_name = methods[index].name;
  1.4054 +    const char* meth_sig = methods[index].signature;
  1.4055 +    int meth_name_len = (int)strlen(meth_name);
  1.4056 +
  1.4057 +    // The class should have been loaded (we have an instance of the class
  1.4058 +    // passed in) so the method and signature should already be in the symbol
  1.4059 +    // table.  If they're not there, the method doesn't exist.
  1.4060 +    TempNewSymbol  name = SymbolTable::probe(meth_name, meth_name_len);
  1.4061 +    TempNewSymbol  signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
  1.4062 +
  1.4063 +    if (name == NULL || signature == NULL) {
  1.4064 +      ResourceMark rm;
  1.4065 +      stringStream st;
  1.4066 +      st.print("Method %s.%s%s not found", h_k()->external_name(), meth_name, meth_sig);
  1.4067 +      // Must return negative value on failure
  1.4068 +      THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
  1.4069 +    }
  1.4070 +
  1.4071 +    bool res = register_native(h_k, name, signature,
  1.4072 +                               (address) methods[index].fnPtr, THREAD);
  1.4073 +    if (!res) {
  1.4074 +      ret = -1;
  1.4075 +      break;
  1.4076 +    }
  1.4077 +  }
  1.4078 +  return ret;
  1.4079 +JNI_END
  1.4080 +
  1.4081 +
  1.4082 +JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
  1.4083 +  JNIWrapper("UnregisterNatives");
  1.4084 +#ifndef USDT2
  1.4085 +  DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz);
  1.4086 +#else /* USDT2 */
  1.4087 + HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(
  1.4088 +                                     env, clazz);
  1.4089 +#endif /* USDT2 */
  1.4090 +  Klass* k   = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
  1.4091 +  //%note jni_2
  1.4092 +  if (k->oop_is_instance()) {
  1.4093 +    for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {
  1.4094 +      Method* m = InstanceKlass::cast(k)->methods()->at(index);
  1.4095 +      if (m->is_native()) {
  1.4096 +        m->clear_native_function();
  1.4097 +        m->set_signature_handler(NULL);
  1.4098 +      }
  1.4099 +    }
  1.4100 +  }
  1.4101 +#ifndef USDT2
  1.4102 +  DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0);
  1.4103 +#else /* USDT2 */
  1.4104 + HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(
  1.4105 +                                      0);
  1.4106 +#endif /* USDT2 */
  1.4107 +  return 0;
  1.4108 +JNI_END
  1.4109 +
  1.4110 +//
  1.4111 +// Monitor functions
  1.4112 +//
  1.4113 +
  1.4114 +#ifndef USDT2
  1.4115 +DT_RETURN_MARK_DECL(MonitorEnter, jint);
  1.4116 +#else /* USDT2 */
  1.4117 +DT_RETURN_MARK_DECL(MonitorEnter, jint
  1.4118 +                    , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
  1.4119 +#endif /* USDT2 */
  1.4120 +
  1.4121 +JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
  1.4122 +#ifndef USDT2
  1.4123 +  DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj);
  1.4124 +#else /* USDT2 */
  1.4125 + HOTSPOT_JNI_MONITORENTER_ENTRY(
  1.4126 +                                env, jobj);
  1.4127 +#endif /* USDT2 */
  1.4128 +  jint ret = JNI_ERR;
  1.4129 +  DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
  1.4130 +
  1.4131 +  // If the object is null, we can't do anything with it
  1.4132 +  if (jobj == NULL) {
  1.4133 +    THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
  1.4134 +  }
  1.4135 +
  1.4136 +  Handle obj(thread, JNIHandles::resolve_non_null(jobj));
  1.4137 +  ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
  1.4138 +  ret = JNI_OK;
  1.4139 +  return ret;
  1.4140 +JNI_END
  1.4141 +
  1.4142 +#ifndef USDT2
  1.4143 +DT_RETURN_MARK_DECL(MonitorExit, jint);
  1.4144 +#else /* USDT2 */
  1.4145 +DT_RETURN_MARK_DECL(MonitorExit, jint
  1.4146 +                    , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
  1.4147 +#endif /* USDT2 */
  1.4148 +
  1.4149 +JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
  1.4150 +#ifndef USDT2
  1.4151 +  DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj);
  1.4152 +#else /* USDT2 */
  1.4153 + HOTSPOT_JNI_MONITOREXIT_ENTRY(
  1.4154 +                               env, jobj);
  1.4155 +#endif /* USDT2 */
  1.4156 +  jint ret = JNI_ERR;
  1.4157 +  DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
  1.4158 +
  1.4159 +  // Don't do anything with a null object
  1.4160 +  if (jobj == NULL) {
  1.4161 +    THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
  1.4162 +  }
  1.4163 +
  1.4164 +  Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
  1.4165 +  ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
  1.4166 +
  1.4167 +  ret = JNI_OK;
  1.4168 +  return ret;
  1.4169 +JNI_END
  1.4170 +
  1.4171 +//
  1.4172 +// Extensions
  1.4173 +//
  1.4174 +
  1.4175 +#ifndef USDT2
  1.4176 +DT_VOID_RETURN_MARK_DECL(GetStringRegion);
  1.4177 +#else /* USDT2 */
  1.4178 +DT_VOID_RETURN_MARK_DECL(GetStringRegion
  1.4179 +                         , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
  1.4180 +#endif /* USDT2 */
  1.4181 +
  1.4182 +JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
  1.4183 +  JNIWrapper("GetStringRegion");
  1.4184 +#ifndef USDT2
  1.4185 +  DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf);
  1.4186 +#else /* USDT2 */
  1.4187 + HOTSPOT_JNI_GETSTRINGREGION_ENTRY(
  1.4188 +                                   env, string, start, len, buf);
  1.4189 +#endif /* USDT2 */
  1.4190 +  DT_VOID_RETURN_MARK(GetStringRegion);
  1.4191 +  oop s = JNIHandles::resolve_non_null(string);
  1.4192 +  int s_len = java_lang_String::length(s);
  1.4193 +  if (start < 0 || len < 0 || start + len > s_len) {
  1.4194 +    THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
  1.4195 +  } else {
  1.4196 +    if (len > 0) {
  1.4197 +      int s_offset = java_lang_String::offset(s);
  1.4198 +      typeArrayOop s_value = java_lang_String::value(s);
  1.4199 +      memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
  1.4200 +    }
  1.4201 +  }
  1.4202 +JNI_END
  1.4203 +
  1.4204 +#ifndef USDT2
  1.4205 +DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);
  1.4206 +#else /* USDT2 */
  1.4207 +DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
  1.4208 +                         , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
  1.4209 +#endif /* USDT2 */
  1.4210 +
  1.4211 +JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
  1.4212 +  JNIWrapper("GetStringUTFRegion");
  1.4213 +#ifndef USDT2
  1.4214 +  DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf);
  1.4215 +#else /* USDT2 */
  1.4216 + HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(
  1.4217 +                                      env, string, start, len, buf);
  1.4218 +#endif /* USDT2 */
  1.4219 +  DT_VOID_RETURN_MARK(GetStringUTFRegion);
  1.4220 +  oop s = JNIHandles::resolve_non_null(string);
  1.4221 +  int s_len = java_lang_String::length(s);
  1.4222 +  if (start < 0 || len < 0 || start + len > s_len) {
  1.4223 +    THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
  1.4224 +  } else {
  1.4225 +    //%note jni_7
  1.4226 +    if (len > 0) {
  1.4227 +      ResourceMark rm(THREAD);
  1.4228 +      char *utf_region = java_lang_String::as_utf8_string(s, start, len);
  1.4229 +      int utf_len = (int)strlen(utf_region);
  1.4230 +      memcpy(buf, utf_region, utf_len);
  1.4231 +      buf[utf_len] = 0;
  1.4232 +    } else {
  1.4233 +      // JDK null-terminates the buffer even in len is zero
  1.4234 +      if (buf != NULL) {
  1.4235 +        buf[0] = 0;
  1.4236 +      }
  1.4237 +    }
  1.4238 +  }
  1.4239 +JNI_END
  1.4240 +
  1.4241 +
  1.4242 +JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
  1.4243 +  JNIWrapper("GetPrimitiveArrayCritical");
  1.4244 +#ifndef USDT2
  1.4245 +  DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
  1.4246 +#else /* USDT2 */
  1.4247 + HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(
  1.4248 +                                             env, array, (uintptr_t *) isCopy);
  1.4249 +#endif /* USDT2 */
  1.4250 +  GC_locker::lock_critical(thread);
  1.4251 +  if (isCopy != NULL) {
  1.4252 +    *isCopy = JNI_FALSE;
  1.4253 +  }
  1.4254 +  oop a = JNIHandles::resolve_non_null(array);
  1.4255 +  assert(a->is_array(), "just checking");
  1.4256 +  BasicType type;
  1.4257 +  if (a->is_objArray()) {
  1.4258 +    type = T_OBJECT;
  1.4259 +  } else {
  1.4260 +    type = TypeArrayKlass::cast(a->klass())->element_type();
  1.4261 +  }
  1.4262 +  void* ret = arrayOop(a)->base(type);
  1.4263 +#ifndef USDT2
  1.4264 +  DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
  1.4265 +#else /* USDT2 */
  1.4266 + HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(
  1.4267 +                                              ret);
  1.4268 +#endif /* USDT2 */
  1.4269 +  return ret;
  1.4270 +JNI_END
  1.4271 +
  1.4272 +
  1.4273 +JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
  1.4274 +  JNIWrapper("ReleasePrimitiveArrayCritical");
  1.4275 +#ifndef USDT2
  1.4276 +  DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
  1.4277 +#else /* USDT2 */
  1.4278 +  HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(
  1.4279 +                                                  env, array, carray, mode);
  1.4280 +#endif /* USDT2 */
  1.4281 +  // The array, carray and mode arguments are ignored
  1.4282 +  GC_locker::unlock_critical(thread);
  1.4283 +#ifndef USDT2
  1.4284 +  DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
  1.4285 +#else /* USDT2 */
  1.4286 +HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(
  1.4287 +);
  1.4288 +#endif /* USDT2 */
  1.4289 +JNI_END
  1.4290 +
  1.4291 +
  1.4292 +JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
  1.4293 +  JNIWrapper("GetStringCritical");
  1.4294 +#ifndef USDT2
  1.4295 +  DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
  1.4296 +#else /* USDT2 */
  1.4297 +  HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(
  1.4298 +                                      env, string, (uintptr_t *) isCopy);
  1.4299 +#endif /* USDT2 */
  1.4300 +  GC_locker::lock_critical(thread);
  1.4301 +  if (isCopy != NULL) {
  1.4302 +    *isCopy = JNI_FALSE;
  1.4303 +  }
  1.4304 +  oop s = JNIHandles::resolve_non_null(string);
  1.4305 +  int s_len = java_lang_String::length(s);
  1.4306 +  typeArrayOop s_value = java_lang_String::value(s);
  1.4307 +  int s_offset = java_lang_String::offset(s);
  1.4308 +  const jchar* ret;
  1.4309 +  if (s_len > 0) {
  1.4310 +    ret = s_value->char_at_addr(s_offset);
  1.4311 +  } else {
  1.4312 +    ret = (jchar*) s_value->base(T_CHAR);
  1.4313 +  }
  1.4314 +#ifndef USDT2
  1.4315 +  DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
  1.4316 +#else /* USDT2 */
  1.4317 + HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(
  1.4318 +                                      (uint16_t *) ret);
  1.4319 +#endif /* USDT2 */
  1.4320 +  return ret;
  1.4321 +JNI_END
  1.4322 +
  1.4323 +
  1.4324 +JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
  1.4325 +  JNIWrapper("ReleaseStringCritical");
  1.4326 +#ifndef USDT2
  1.4327 +  DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
  1.4328 +#else /* USDT2 */
  1.4329 +  HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(
  1.4330 +                                          env, str, (uint16_t *) chars);
  1.4331 +#endif /* USDT2 */
  1.4332 +  // The str and chars arguments are ignored
  1.4333 +  GC_locker::unlock_critical(thread);
  1.4334 +#ifndef USDT2
  1.4335 +  DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
  1.4336 +#else /* USDT2 */
  1.4337 +HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(
  1.4338 +);
  1.4339 +#endif /* USDT2 */
  1.4340 +JNI_END
  1.4341 +
  1.4342 +
  1.4343 +JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
  1.4344 +  JNIWrapper("jni_NewWeakGlobalRef");
  1.4345 +#ifndef USDT2
  1.4346 +  DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
  1.4347 +#else /* USDT2 */
  1.4348 + HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(
  1.4349 +                                    env, ref);
  1.4350 +#endif /* USDT2 */
  1.4351 +  Handle ref_handle(thread, JNIHandles::resolve(ref));
  1.4352 +  jweak ret = JNIHandles::make_weak_global(ref_handle);
  1.4353 +#ifndef USDT2
  1.4354 +  DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret);
  1.4355 +#else /* USDT2 */
  1.4356 + HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(
  1.4357 +                                     ret);
  1.4358 +#endif /* USDT2 */
  1.4359 +  return ret;
  1.4360 +JNI_END
  1.4361 +
  1.4362 +// Must be JNI_ENTRY (with HandleMark)
  1.4363 +JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
  1.4364 +  JNIWrapper("jni_DeleteWeakGlobalRef");
  1.4365 +#ifndef USDT2
  1.4366 +  DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref);
  1.4367 +#else /* USDT2 */
  1.4368 +  HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(
  1.4369 +                                        env, ref);
  1.4370 +#endif /* USDT2 */
  1.4371 +  JNIHandles::destroy_weak_global(ref);
  1.4372 +#ifndef USDT2
  1.4373 +  DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return);
  1.4374 +#else /* USDT2 */
  1.4375 +  HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN(
  1.4376 +                                         );
  1.4377 +#endif /* USDT2 */
  1.4378 +JNI_END
  1.4379 +
  1.4380 +
  1.4381 +JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
  1.4382 +  JNIWrapper("jni_ExceptionCheck");
  1.4383 +#ifndef USDT2
  1.4384 +  DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env);
  1.4385 +#else /* USDT2 */
  1.4386 + HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(
  1.4387 +                                  env);
  1.4388 +#endif /* USDT2 */
  1.4389 +  jni_check_async_exceptions(thread);
  1.4390 +  jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
  1.4391 +#ifndef USDT2
  1.4392 +  DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret);
  1.4393 +#else /* USDT2 */
  1.4394 + HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(
  1.4395 +                                   ret);
  1.4396 +#endif /* USDT2 */
  1.4397 +  return ret;
  1.4398 +JNI_END
  1.4399 +
  1.4400 +
  1.4401 +// Initialization state for three routines below relating to
  1.4402 +// java.nio.DirectBuffers
  1.4403 +static          jint directBufferSupportInitializeStarted = 0;
  1.4404 +static volatile jint directBufferSupportInitializeEnded   = 0;
  1.4405 +static volatile jint directBufferSupportInitializeFailed  = 0;
  1.4406 +static jclass    bufferClass                 = NULL;
  1.4407 +static jclass    directBufferClass           = NULL;
  1.4408 +static jclass    directByteBufferClass       = NULL;
  1.4409 +static jmethodID directByteBufferConstructor = NULL;
  1.4410 +static jfieldID  directBufferAddressField    = NULL;
  1.4411 +static jfieldID  bufferCapacityField         = NULL;
  1.4412 +
  1.4413 +static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
  1.4414 +  Handle loader;            // null (bootstrap) loader
  1.4415 +  Handle protection_domain; // null protection domain
  1.4416 +
  1.4417 +  TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
  1.4418 +  jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
  1.4419 +
  1.4420 +  if (TraceClassResolution && result != NULL) {
  1.4421 +    trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));
  1.4422 +  }
  1.4423 +  return result;
  1.4424 +}
  1.4425 +
  1.4426 +// These lookups are done with the NULL (bootstrap) ClassLoader to
  1.4427 +// circumvent any security checks that would be done by jni_FindClass.
  1.4428 +JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env))
  1.4429 +{
  1.4430 +  if ((bufferClass           = lookupOne(env, "java/nio/Buffer", thread))           == NULL) { return false; }
  1.4431 +  if ((directBufferClass     = lookupOne(env, "sun/nio/ch/DirectBuffer", thread))   == NULL) { return false; }
  1.4432 +  if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; }
  1.4433 +  return true;
  1.4434 +}
  1.4435 +JNI_END
  1.4436 +
  1.4437 +
  1.4438 +static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {
  1.4439 +  if (directBufferSupportInitializeFailed) {
  1.4440 +    return false;
  1.4441 +  }
  1.4442 +
  1.4443 +  if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) {
  1.4444 +    if (!lookupDirectBufferClasses(env)) {
  1.4445 +      directBufferSupportInitializeFailed = 1;
  1.4446 +      return false;
  1.4447 +    }
  1.4448 +
  1.4449 +    // Make global references for these
  1.4450 +    bufferClass           = (jclass) env->NewGlobalRef(bufferClass);
  1.4451 +    directBufferClass     = (jclass) env->NewGlobalRef(directBufferClass);
  1.4452 +    directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);
  1.4453 +
  1.4454 +    // Get needed field and method IDs
  1.4455 +    directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");
  1.4456 +    if (env->ExceptionCheck()) {
  1.4457 +      env->ExceptionClear();
  1.4458 +      directBufferSupportInitializeFailed = 1;
  1.4459 +      return false;
  1.4460 +    }
  1.4461 +    directBufferAddressField    = env->GetFieldID(bufferClass, "address", "J");
  1.4462 +    if (env->ExceptionCheck()) {
  1.4463 +      env->ExceptionClear();
  1.4464 +      directBufferSupportInitializeFailed = 1;
  1.4465 +      return false;
  1.4466 +    }
  1.4467 +    bufferCapacityField         = env->GetFieldID(bufferClass, "capacity", "I");
  1.4468 +    if (env->ExceptionCheck()) {
  1.4469 +      env->ExceptionClear();
  1.4470 +      directBufferSupportInitializeFailed = 1;
  1.4471 +      return false;
  1.4472 +    }
  1.4473 +
  1.4474 +    if ((directByteBufferConstructor == NULL) ||
  1.4475 +        (directBufferAddressField    == NULL) ||
  1.4476 +        (bufferCapacityField         == NULL)) {
  1.4477 +      directBufferSupportInitializeFailed = 1;
  1.4478 +      return false;
  1.4479 +    }
  1.4480 +
  1.4481 +    directBufferSupportInitializeEnded = 1;
  1.4482 +  } else {
  1.4483 +    while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {
  1.4484 +      // Set state as yield_all can call os:sleep. On Solaris, yield_all calls
  1.4485 +      // os::sleep which requires the VM state transition. On other platforms, it
  1.4486 +      // is not necessary. The following call to change the VM state is purposely
  1.4487 +      // put inside the loop to avoid potential deadlock when multiple threads
  1.4488 +      // try to call this method. See 6791815 for more details.
  1.4489 +      ThreadInVMfromNative tivn(thread);
  1.4490 +      os::yield_all();
  1.4491 +    }
  1.4492 +  }
  1.4493 +
  1.4494 +  return !directBufferSupportInitializeFailed;
  1.4495 +}
  1.4496 +
  1.4497 +extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)
  1.4498 +{
  1.4499 +  // thread_from_jni_environment() will block if VM is gone.
  1.4500 +  JavaThread* thread = JavaThread::thread_from_jni_environment(env);
  1.4501 +
  1.4502 +  JNIWrapper("jni_NewDirectByteBuffer");
  1.4503 +#ifndef USDT2
  1.4504 +  DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity);
  1.4505 +#else /* USDT2 */
  1.4506 + HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(
  1.4507 +                                       env, address, capacity);
  1.4508 +#endif /* USDT2 */
  1.4509 +
  1.4510 +  if (!directBufferSupportInitializeEnded) {
  1.4511 +    if (!initializeDirectBufferSupport(env, thread)) {
  1.4512 +#ifndef USDT2
  1.4513 +      DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, NULL);
  1.4514 +#else /* USDT2 */
  1.4515 +      HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(
  1.4516 +                                             NULL);
  1.4517 +#endif /* USDT2 */
  1.4518 +      return NULL;
  1.4519 +    }
  1.4520 +  }
  1.4521 +
  1.4522 +  // Being paranoid about accidental sign extension on address
  1.4523 +  jlong addr = (jlong) ((uintptr_t) address);
  1.4524 +  // NOTE that package-private DirectByteBuffer constructor currently
  1.4525 +  // takes int capacity
  1.4526 +  jint  cap  = (jint)  capacity;
  1.4527 +  jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
  1.4528 +#ifndef USDT2
  1.4529 +  DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret);
  1.4530 +#else /* USDT2 */
  1.4531 +  HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(
  1.4532 +                                         ret);
  1.4533 +#endif /* USDT2 */
  1.4534 +  return ret;
  1.4535 +}
  1.4536 +
  1.4537 +#ifndef USDT2
  1.4538 +DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);
  1.4539 +#else /* USDT2 */
  1.4540 +DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
  1.4541 +                    , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
  1.4542 +#endif /* USDT2 */
  1.4543 +
  1.4544 +extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
  1.4545 +{
  1.4546 +  // thread_from_jni_environment() will block if VM is gone.
  1.4547 +  JavaThread* thread = JavaThread::thread_from_jni_environment(env);
  1.4548 +
  1.4549 +  JNIWrapper("jni_GetDirectBufferAddress");
  1.4550 +#ifndef USDT2
  1.4551 +  DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf);
  1.4552 +#else /* USDT2 */
  1.4553 +  HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(
  1.4554 +                                           env, buf);
  1.4555 +#endif /* USDT2 */
  1.4556 +  void* ret = NULL;
  1.4557 +  DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
  1.4558 +
  1.4559 +  if (!directBufferSupportInitializeEnded) {
  1.4560 +    if (!initializeDirectBufferSupport(env, thread)) {
  1.4561 +      return 0;
  1.4562 +    }
  1.4563 +  }
  1.4564 +
  1.4565 +  if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {
  1.4566 +    return 0;
  1.4567 +  }
  1.4568 +
  1.4569 +  ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);
  1.4570 +  return ret;
  1.4571 +}
  1.4572 +
  1.4573 +#ifndef USDT2
  1.4574 +DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);
  1.4575 +#else /* USDT2 */
  1.4576 +DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
  1.4577 +                    , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
  1.4578 +#endif /* USDT2 */
  1.4579 +
  1.4580 +extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
  1.4581 +{
  1.4582 +  // thread_from_jni_environment() will block if VM is gone.
  1.4583 +  JavaThread* thread = JavaThread::thread_from_jni_environment(env);
  1.4584 +
  1.4585 +  JNIWrapper("jni_GetDirectBufferCapacity");
  1.4586 +#ifndef USDT2
  1.4587 +  DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf);
  1.4588 +#else /* USDT2 */
  1.4589 +  HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(
  1.4590 +                                            env, buf);
  1.4591 +#endif /* USDT2 */
  1.4592 +  jlong ret = -1;
  1.4593 +  DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
  1.4594 +
  1.4595 +  if (!directBufferSupportInitializeEnded) {
  1.4596 +    if (!initializeDirectBufferSupport(env, thread)) {
  1.4597 +      ret = 0;
  1.4598 +      return ret;
  1.4599 +    }
  1.4600 +  }
  1.4601 +
  1.4602 +  if (buf == NULL) {
  1.4603 +    return -1;
  1.4604 +  }
  1.4605 +
  1.4606 +  if (!env->IsInstanceOf(buf, directBufferClass)) {
  1.4607 +    return -1;
  1.4608 +  }
  1.4609 +
  1.4610 +  // NOTE that capacity is currently an int in the implementation
  1.4611 +  ret = env->GetIntField(buf, bufferCapacityField);
  1.4612 +  return ret;
  1.4613 +}
  1.4614 +
  1.4615 +
  1.4616 +JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
  1.4617 +  JNIWrapper("GetVersion");
  1.4618 +#ifndef USDT2
  1.4619 +  DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env);
  1.4620 +#else /* USDT2 */
  1.4621 +  HOTSPOT_JNI_GETVERSION_ENTRY(
  1.4622 +                               env);
  1.4623 +#endif /* USDT2 */
  1.4624 +#ifndef USDT2
  1.4625 +  DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion);
  1.4626 +#else /* USDT2 */
  1.4627 +  HOTSPOT_JNI_GETVERSION_RETURN(
  1.4628 +                                CurrentVersion);
  1.4629 +#endif /* USDT2 */
  1.4630 +  return CurrentVersion;
  1.4631 +JNI_END
  1.4632 +
  1.4633 +extern struct JavaVM_ main_vm;
  1.4634 +
  1.4635 +JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
  1.4636 +  JNIWrapper("jni_GetJavaVM");
  1.4637 +#ifndef USDT2
  1.4638 +  DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm);
  1.4639 +#else /* USDT2 */
  1.4640 +  HOTSPOT_JNI_GETJAVAVM_ENTRY(
  1.4641 +                              env, (void **) vm);
  1.4642 +#endif /* USDT2 */
  1.4643 +  *vm  = (JavaVM *)(&main_vm);
  1.4644 +#ifndef USDT2
  1.4645 +  DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK);
  1.4646 +#else /* USDT2 */
  1.4647 +  HOTSPOT_JNI_GETJAVAVM_RETURN(
  1.4648 +                               JNI_OK);
  1.4649 +#endif /* USDT2 */
  1.4650 +  return JNI_OK;
  1.4651 +JNI_END
  1.4652 +
  1.4653 +// Structure containing all jni functions
  1.4654 +struct JNINativeInterface_ jni_NativeInterface = {
  1.4655 +    NULL,
  1.4656 +    NULL,
  1.4657 +    NULL,
  1.4658 +
  1.4659 +    NULL,
  1.4660 +
  1.4661 +    jni_GetVersion,
  1.4662 +
  1.4663 +    jni_DefineClass,
  1.4664 +    jni_FindClass,
  1.4665 +
  1.4666 +    jni_FromReflectedMethod,
  1.4667 +    jni_FromReflectedField,
  1.4668 +
  1.4669 +    jni_ToReflectedMethod,
  1.4670 +
  1.4671 +    jni_GetSuperclass,
  1.4672 +    jni_IsAssignableFrom,
  1.4673 +
  1.4674 +    jni_ToReflectedField,
  1.4675 +
  1.4676 +    jni_Throw,
  1.4677 +    jni_ThrowNew,
  1.4678 +    jni_ExceptionOccurred,
  1.4679 +    jni_ExceptionDescribe,
  1.4680 +    jni_ExceptionClear,
  1.4681 +    jni_FatalError,
  1.4682 +
  1.4683 +    jni_PushLocalFrame,
  1.4684 +    jni_PopLocalFrame,
  1.4685 +
  1.4686 +    jni_NewGlobalRef,
  1.4687 +    jni_DeleteGlobalRef,
  1.4688 +    jni_DeleteLocalRef,
  1.4689 +    jni_IsSameObject,
  1.4690 +
  1.4691 +    jni_NewLocalRef,
  1.4692 +    jni_EnsureLocalCapacity,
  1.4693 +
  1.4694 +    jni_AllocObject,
  1.4695 +    jni_NewObject,
  1.4696 +    jni_NewObjectV,
  1.4697 +    jni_NewObjectA,
  1.4698 +
  1.4699 +    jni_GetObjectClass,
  1.4700 +    jni_IsInstanceOf,
  1.4701 +
  1.4702 +    jni_GetMethodID,
  1.4703 +
  1.4704 +    jni_CallObjectMethod,
  1.4705 +    jni_CallObjectMethodV,
  1.4706 +    jni_CallObjectMethodA,
  1.4707 +    jni_CallBooleanMethod,
  1.4708 +    jni_CallBooleanMethodV,
  1.4709 +    jni_CallBooleanMethodA,
  1.4710 +    jni_CallByteMethod,
  1.4711 +    jni_CallByteMethodV,
  1.4712 +    jni_CallByteMethodA,
  1.4713 +    jni_CallCharMethod,
  1.4714 +    jni_CallCharMethodV,
  1.4715 +    jni_CallCharMethodA,
  1.4716 +    jni_CallShortMethod,
  1.4717 +    jni_CallShortMethodV,
  1.4718 +    jni_CallShortMethodA,
  1.4719 +    jni_CallIntMethod,
  1.4720 +    jni_CallIntMethodV,
  1.4721 +    jni_CallIntMethodA,
  1.4722 +    jni_CallLongMethod,
  1.4723 +    jni_CallLongMethodV,
  1.4724 +    jni_CallLongMethodA,
  1.4725 +    jni_CallFloatMethod,
  1.4726 +    jni_CallFloatMethodV,
  1.4727 +    jni_CallFloatMethodA,
  1.4728 +    jni_CallDoubleMethod,
  1.4729 +    jni_CallDoubleMethodV,
  1.4730 +    jni_CallDoubleMethodA,
  1.4731 +    jni_CallVoidMethod,
  1.4732 +    jni_CallVoidMethodV,
  1.4733 +    jni_CallVoidMethodA,
  1.4734 +
  1.4735 +    jni_CallNonvirtualObjectMethod,
  1.4736 +    jni_CallNonvirtualObjectMethodV,
  1.4737 +    jni_CallNonvirtualObjectMethodA,
  1.4738 +    jni_CallNonvirtualBooleanMethod,
  1.4739 +    jni_CallNonvirtualBooleanMethodV,
  1.4740 +    jni_CallNonvirtualBooleanMethodA,
  1.4741 +    jni_CallNonvirtualByteMethod,
  1.4742 +    jni_CallNonvirtualByteMethodV,
  1.4743 +    jni_CallNonvirtualByteMethodA,
  1.4744 +    jni_CallNonvirtualCharMethod,
  1.4745 +    jni_CallNonvirtualCharMethodV,
  1.4746 +    jni_CallNonvirtualCharMethodA,
  1.4747 +    jni_CallNonvirtualShortMethod,
  1.4748 +    jni_CallNonvirtualShortMethodV,
  1.4749 +    jni_CallNonvirtualShortMethodA,
  1.4750 +    jni_CallNonvirtualIntMethod,
  1.4751 +    jni_CallNonvirtualIntMethodV,
  1.4752 +    jni_CallNonvirtualIntMethodA,
  1.4753 +    jni_CallNonvirtualLongMethod,
  1.4754 +    jni_CallNonvirtualLongMethodV,
  1.4755 +    jni_CallNonvirtualLongMethodA,
  1.4756 +    jni_CallNonvirtualFloatMethod,
  1.4757 +    jni_CallNonvirtualFloatMethodV,
  1.4758 +    jni_CallNonvirtualFloatMethodA,
  1.4759 +    jni_CallNonvirtualDoubleMethod,
  1.4760 +    jni_CallNonvirtualDoubleMethodV,
  1.4761 +    jni_CallNonvirtualDoubleMethodA,
  1.4762 +    jni_CallNonvirtualVoidMethod,
  1.4763 +    jni_CallNonvirtualVoidMethodV,
  1.4764 +    jni_CallNonvirtualVoidMethodA,
  1.4765 +
  1.4766 +    jni_GetFieldID,
  1.4767 +
  1.4768 +    jni_GetObjectField,
  1.4769 +    jni_GetBooleanField,
  1.4770 +    jni_GetByteField,
  1.4771 +    jni_GetCharField,
  1.4772 +    jni_GetShortField,
  1.4773 +    jni_GetIntField,
  1.4774 +    jni_GetLongField,
  1.4775 +    jni_GetFloatField,
  1.4776 +    jni_GetDoubleField,
  1.4777 +
  1.4778 +    jni_SetObjectField,
  1.4779 +    jni_SetBooleanField,
  1.4780 +    jni_SetByteField,
  1.4781 +    jni_SetCharField,
  1.4782 +    jni_SetShortField,
  1.4783 +    jni_SetIntField,
  1.4784 +    jni_SetLongField,
  1.4785 +    jni_SetFloatField,
  1.4786 +    jni_SetDoubleField,
  1.4787 +
  1.4788 +    jni_GetStaticMethodID,
  1.4789 +
  1.4790 +    jni_CallStaticObjectMethod,
  1.4791 +    jni_CallStaticObjectMethodV,
  1.4792 +    jni_CallStaticObjectMethodA,
  1.4793 +    jni_CallStaticBooleanMethod,
  1.4794 +    jni_CallStaticBooleanMethodV,
  1.4795 +    jni_CallStaticBooleanMethodA,
  1.4796 +    jni_CallStaticByteMethod,
  1.4797 +    jni_CallStaticByteMethodV,
  1.4798 +    jni_CallStaticByteMethodA,
  1.4799 +    jni_CallStaticCharMethod,
  1.4800 +    jni_CallStaticCharMethodV,
  1.4801 +    jni_CallStaticCharMethodA,
  1.4802 +    jni_CallStaticShortMethod,
  1.4803 +    jni_CallStaticShortMethodV,
  1.4804 +    jni_CallStaticShortMethodA,
  1.4805 +    jni_CallStaticIntMethod,
  1.4806 +    jni_CallStaticIntMethodV,
  1.4807 +    jni_CallStaticIntMethodA,
  1.4808 +    jni_CallStaticLongMethod,
  1.4809 +    jni_CallStaticLongMethodV,
  1.4810 +    jni_CallStaticLongMethodA,
  1.4811 +    jni_CallStaticFloatMethod,
  1.4812 +    jni_CallStaticFloatMethodV,
  1.4813 +    jni_CallStaticFloatMethodA,
  1.4814 +    jni_CallStaticDoubleMethod,
  1.4815 +    jni_CallStaticDoubleMethodV,
  1.4816 +    jni_CallStaticDoubleMethodA,
  1.4817 +    jni_CallStaticVoidMethod,
  1.4818 +    jni_CallStaticVoidMethodV,
  1.4819 +    jni_CallStaticVoidMethodA,
  1.4820 +
  1.4821 +    jni_GetStaticFieldID,
  1.4822 +
  1.4823 +    jni_GetStaticObjectField,
  1.4824 +    jni_GetStaticBooleanField,
  1.4825 +    jni_GetStaticByteField,
  1.4826 +    jni_GetStaticCharField,
  1.4827 +    jni_GetStaticShortField,
  1.4828 +    jni_GetStaticIntField,
  1.4829 +    jni_GetStaticLongField,
  1.4830 +    jni_GetStaticFloatField,
  1.4831 +    jni_GetStaticDoubleField,
  1.4832 +
  1.4833 +    jni_SetStaticObjectField,
  1.4834 +    jni_SetStaticBooleanField,
  1.4835 +    jni_SetStaticByteField,
  1.4836 +    jni_SetStaticCharField,
  1.4837 +    jni_SetStaticShortField,
  1.4838 +    jni_SetStaticIntField,
  1.4839 +    jni_SetStaticLongField,
  1.4840 +    jni_SetStaticFloatField,
  1.4841 +    jni_SetStaticDoubleField,
  1.4842 +
  1.4843 +    jni_NewString,
  1.4844 +    jni_GetStringLength,
  1.4845 +    jni_GetStringChars,
  1.4846 +    jni_ReleaseStringChars,
  1.4847 +
  1.4848 +    jni_NewStringUTF,
  1.4849 +    jni_GetStringUTFLength,
  1.4850 +    jni_GetStringUTFChars,
  1.4851 +    jni_ReleaseStringUTFChars,
  1.4852 +
  1.4853 +    jni_GetArrayLength,
  1.4854 +
  1.4855 +    jni_NewObjectArray,
  1.4856 +    jni_GetObjectArrayElement,
  1.4857 +    jni_SetObjectArrayElement,
  1.4858 +
  1.4859 +    jni_NewBooleanArray,
  1.4860 +    jni_NewByteArray,
  1.4861 +    jni_NewCharArray,
  1.4862 +    jni_NewShortArray,
  1.4863 +    jni_NewIntArray,
  1.4864 +    jni_NewLongArray,
  1.4865 +    jni_NewFloatArray,
  1.4866 +    jni_NewDoubleArray,
  1.4867 +
  1.4868 +    jni_GetBooleanArrayElements,
  1.4869 +    jni_GetByteArrayElements,
  1.4870 +    jni_GetCharArrayElements,
  1.4871 +    jni_GetShortArrayElements,
  1.4872 +    jni_GetIntArrayElements,
  1.4873 +    jni_GetLongArrayElements,
  1.4874 +    jni_GetFloatArrayElements,
  1.4875 +    jni_GetDoubleArrayElements,
  1.4876 +
  1.4877 +    jni_ReleaseBooleanArrayElements,
  1.4878 +    jni_ReleaseByteArrayElements,
  1.4879 +    jni_ReleaseCharArrayElements,
  1.4880 +    jni_ReleaseShortArrayElements,
  1.4881 +    jni_ReleaseIntArrayElements,
  1.4882 +    jni_ReleaseLongArrayElements,
  1.4883 +    jni_ReleaseFloatArrayElements,
  1.4884 +    jni_ReleaseDoubleArrayElements,
  1.4885 +
  1.4886 +    jni_GetBooleanArrayRegion,
  1.4887 +    jni_GetByteArrayRegion,
  1.4888 +    jni_GetCharArrayRegion,
  1.4889 +    jni_GetShortArrayRegion,
  1.4890 +    jni_GetIntArrayRegion,
  1.4891 +    jni_GetLongArrayRegion,
  1.4892 +    jni_GetFloatArrayRegion,
  1.4893 +    jni_GetDoubleArrayRegion,
  1.4894 +
  1.4895 +    jni_SetBooleanArrayRegion,
  1.4896 +    jni_SetByteArrayRegion,
  1.4897 +    jni_SetCharArrayRegion,
  1.4898 +    jni_SetShortArrayRegion,
  1.4899 +    jni_SetIntArrayRegion,
  1.4900 +    jni_SetLongArrayRegion,
  1.4901 +    jni_SetFloatArrayRegion,
  1.4902 +    jni_SetDoubleArrayRegion,
  1.4903 +
  1.4904 +    jni_RegisterNatives,
  1.4905 +    jni_UnregisterNatives,
  1.4906 +
  1.4907 +    jni_MonitorEnter,
  1.4908 +    jni_MonitorExit,
  1.4909 +
  1.4910 +    jni_GetJavaVM,
  1.4911 +
  1.4912 +    jni_GetStringRegion,
  1.4913 +    jni_GetStringUTFRegion,
  1.4914 +
  1.4915 +    jni_GetPrimitiveArrayCritical,
  1.4916 +    jni_ReleasePrimitiveArrayCritical,
  1.4917 +
  1.4918 +    jni_GetStringCritical,
  1.4919 +    jni_ReleaseStringCritical,
  1.4920 +
  1.4921 +    jni_NewWeakGlobalRef,
  1.4922 +    jni_DeleteWeakGlobalRef,
  1.4923 +
  1.4924 +    jni_ExceptionCheck,
  1.4925 +
  1.4926 +    jni_NewDirectByteBuffer,
  1.4927 +    jni_GetDirectBufferAddress,
  1.4928 +    jni_GetDirectBufferCapacity,
  1.4929 +
  1.4930 +    // New 1_6 features
  1.4931 +
  1.4932 +    jni_GetObjectRefType
  1.4933 +};
  1.4934 +
  1.4935 +
  1.4936 +// For jvmti use to modify jni function table.
  1.4937 +// Java threads in native contiues to run until it is transitioned
  1.4938 +// to VM at safepoint. Before the transition or before it is blocked
  1.4939 +// for safepoint it may access jni function table. VM could crash if
  1.4940 +// any java thread access the jni function table in the middle of memcpy.
  1.4941 +// To avoid this each function pointers are copied automically.
  1.4942 +void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
  1.4943 +  assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
  1.4944 +  intptr_t *a = (intptr_t *) jni_functions();
  1.4945 +  intptr_t *b = (intptr_t *) new_jni_NativeInterface;
  1.4946 +  for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
  1.4947 +    Atomic::store_ptr(*b++, a++);
  1.4948 +  }
  1.4949 +}
  1.4950 +
  1.4951 +void quicken_jni_functions() {
  1.4952 +  // Replace Get<Primitive>Field with fast versions
  1.4953 +  if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access()
  1.4954 +      && !VerifyJNIFields && !TraceJNICalls && !CountJNICalls && !CheckJNICalls
  1.4955 +#if defined(_WINDOWS) && defined(IA32) && defined(COMPILER2)
  1.4956 +      // windows x86 currently needs SEH wrapper and the gain of the fast
  1.4957 +      // versions currently isn't certain for server vm on uniprocessor.
  1.4958 +      && os::is_MP()
  1.4959 +#endif
  1.4960 +  ) {
  1.4961 +    address func;
  1.4962 +    func = JNI_FastGetField::generate_fast_get_boolean_field();
  1.4963 +    if (func != (address)-1) {
  1.4964 +      jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
  1.4965 +    }
  1.4966 +    func = JNI_FastGetField::generate_fast_get_byte_field();
  1.4967 +    if (func != (address)-1) {
  1.4968 +      jni_NativeInterface.GetByteField = (GetByteField_t)func;
  1.4969 +    }
  1.4970 +    func = JNI_FastGetField::generate_fast_get_char_field();
  1.4971 +    if (func != (address)-1) {
  1.4972 +      jni_NativeInterface.GetCharField = (GetCharField_t)func;
  1.4973 +    }
  1.4974 +    func = JNI_FastGetField::generate_fast_get_short_field();
  1.4975 +    if (func != (address)-1) {
  1.4976 +      jni_NativeInterface.GetShortField = (GetShortField_t)func;
  1.4977 +    }
  1.4978 +    func = JNI_FastGetField::generate_fast_get_int_field();
  1.4979 +    if (func != (address)-1) {
  1.4980 +      jni_NativeInterface.GetIntField = (GetIntField_t)func;
  1.4981 +    }
  1.4982 +    func = JNI_FastGetField::generate_fast_get_long_field();
  1.4983 +    if (func != (address)-1) {
  1.4984 +      jni_NativeInterface.GetLongField = (GetLongField_t)func;
  1.4985 +    }
  1.4986 +    func = JNI_FastGetField::generate_fast_get_float_field();
  1.4987 +    if (func != (address)-1) {
  1.4988 +      jni_NativeInterface.GetFloatField = (GetFloatField_t)func;
  1.4989 +    }
  1.4990 +    func = JNI_FastGetField::generate_fast_get_double_field();
  1.4991 +    if (func != (address)-1) {
  1.4992 +      jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;
  1.4993 +    }
  1.4994 +  }
  1.4995 +}
  1.4996 +
  1.4997 +// Returns the function structure
  1.4998 +struct JNINativeInterface_* jni_functions() {
  1.4999 +#if INCLUDE_JNI_CHECK
  1.5000 +  if (CheckJNICalls) return jni_functions_check();
  1.5001 +#endif // INCLUDE_JNI_CHECK
  1.5002 +  return &jni_NativeInterface;
  1.5003 +}
  1.5004 +
  1.5005 +// Returns the function structure
  1.5006 +struct JNINativeInterface_* jni_functions_nocheck() {
  1.5007 +  return &jni_NativeInterface;
  1.5008 +}
  1.5009 +
  1.5010 +
  1.5011 +// Invocation API
  1.5012 +
  1.5013 +
  1.5014 +// Forward declaration
  1.5015 +extern const struct JNIInvokeInterface_ jni_InvokeInterface;
  1.5016 +
  1.5017 +// Global invocation API vars
  1.5018 +volatile jint vm_created = 0;
  1.5019 +// Indicate whether it is safe to recreate VM
  1.5020 +volatile jint safe_to_recreate_vm = 1;
  1.5021 +struct JavaVM_ main_vm = {&jni_InvokeInterface};
  1.5022 +
  1.5023 +
  1.5024 +#define JAVASTACKSIZE (400 * 1024)    /* Default size of a thread java stack */
  1.5025 +enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
  1.5026 +
  1.5027 +#ifndef USDT2
  1.5028 +HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*);
  1.5029 +DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint);
  1.5030 +#else /* USDT2 */
  1.5031 +DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
  1.5032 +                    , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
  1.5033 +#endif /* USDT2 */
  1.5034 +
  1.5035 +_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
  1.5036 +#ifndef USDT2
  1.5037 +  HS_DTRACE_PROBE1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, args_);
  1.5038 +#else /* USDT2 */
  1.5039 +  HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(
  1.5040 +                                             args_);
  1.5041 +#endif /* USDT2 */
  1.5042 +  JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
  1.5043 +  jint ret = JNI_ERR;
  1.5044 +  DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
  1.5045 +
  1.5046 +  if (Threads::is_supported_jni_version(args->version)) {
  1.5047 +    ret = JNI_OK;
  1.5048 +  }
  1.5049 +  // 1.1 style no longer supported in hotspot.
  1.5050 +  // According the JNI spec, we should update args->version on return.
  1.5051 +  // We also use the structure to communicate with launcher about default
  1.5052 +  // stack size.
  1.5053 +  if (args->version == JNI_VERSION_1_1) {
  1.5054 +    args->version = JNI_VERSION_1_2;
  1.5055 +    // javaStackSize is int in arguments structure
  1.5056 +    assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow");
  1.5057 +    args->javaStackSize = (jint)(ThreadStackSize * K);
  1.5058 +  }
  1.5059 +  return ret;
  1.5060 +}
  1.5061 +
  1.5062 +#ifndef PRODUCT
  1.5063 +
  1.5064 +#include "gc_implementation/shared/gcTimer.hpp"
  1.5065 +#include "gc_interface/collectedHeap.hpp"
  1.5066 +#if INCLUDE_ALL_GCS
  1.5067 +#include "gc_implementation/g1/heapRegionRemSet.hpp"
  1.5068 +#endif
  1.5069 +#include "utilities/quickSort.hpp"
  1.5070 +#include "utilities/ostream.hpp"
  1.5071 +#if INCLUDE_VM_STRUCTS
  1.5072 +#include "runtime/vmStructs.hpp"
  1.5073 +#endif
  1.5074 +
  1.5075 +#define run_unit_test(unit_test_function_call)              \
  1.5076 +  tty->print_cr("Running test: " #unit_test_function_call); \
  1.5077 +  unit_test_function_call
  1.5078 +
  1.5079 +// Forward declaration
  1.5080 +void TestReservedSpace_test();
  1.5081 +void TestReserveMemorySpecial_test();
  1.5082 +void TestVirtualSpace_test();
  1.5083 +void TestMetaspaceAux_test();
  1.5084 +void TestMetachunk_test();
  1.5085 +void TestVirtualSpaceNode_test();
  1.5086 +void TestNewSize_test();
  1.5087 +#if INCLUDE_ALL_GCS
  1.5088 +void TestOldFreeSpaceCalculation_test();
  1.5089 +void TestG1BiasedArray_test();
  1.5090 +void TestCodeCacheRemSet_test();
  1.5091 +#endif
  1.5092 +
  1.5093 +void execute_internal_vm_tests() {
  1.5094 +  if (ExecuteInternalVMTests) {
  1.5095 +    tty->print_cr("Running internal VM tests");
  1.5096 +    run_unit_test(TestReservedSpace_test());
  1.5097 +    run_unit_test(TestReserveMemorySpecial_test());
  1.5098 +    run_unit_test(TestVirtualSpace_test());
  1.5099 +    run_unit_test(TestMetaspaceAux_test());
  1.5100 +    run_unit_test(TestMetachunk_test());
  1.5101 +    run_unit_test(TestVirtualSpaceNode_test());
  1.5102 +    run_unit_test(GlobalDefinitions::test_globals());
  1.5103 +    run_unit_test(GCTimerAllTest::all());
  1.5104 +    run_unit_test(arrayOopDesc::test_max_array_length());
  1.5105 +    run_unit_test(CollectedHeap::test_is_in());
  1.5106 +    run_unit_test(QuickSort::test_quick_sort());
  1.5107 +    run_unit_test(AltHashing::test_alt_hash());
  1.5108 +    run_unit_test(test_loggc_filename());
  1.5109 +    run_unit_test(TestNewSize_test());
  1.5110 +#if INCLUDE_VM_STRUCTS
  1.5111 +    run_unit_test(VMStructs::test());
  1.5112 +#endif
  1.5113 +#if INCLUDE_ALL_GCS
  1.5114 +    run_unit_test(TestOldFreeSpaceCalculation_test());
  1.5115 +    run_unit_test(TestG1BiasedArray_test());
  1.5116 +    run_unit_test(HeapRegionRemSet::test_prt());
  1.5117 +    run_unit_test(TestCodeCacheRemSet_test());
  1.5118 +#endif
  1.5119 +    tty->print_cr("All internal VM tests passed");
  1.5120 +  }
  1.5121 +}
  1.5122 +
  1.5123 +#undef run_unit_test
  1.5124 +
  1.5125 +#endif
  1.5126 +
  1.5127 +#ifndef USDT2
  1.5128 +HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
  1.5129 +DT_RETURN_MARK_DECL(CreateJavaVM, jint);
  1.5130 +#else /* USDT2 */
  1.5131 +DT_RETURN_MARK_DECL(CreateJavaVM, jint
  1.5132 +                    , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
  1.5133 +#endif /* USDT2 */
  1.5134 +
  1.5135 +_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
  1.5136 +#ifndef USDT2
  1.5137 +  HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
  1.5138 +#else /* USDT2 */
  1.5139 +  HOTSPOT_JNI_CREATEJAVAVM_ENTRY(
  1.5140 +                                 (void **) vm, penv, args);
  1.5141 +#endif /* USDT2 */
  1.5142 +
  1.5143 +  jint result = JNI_ERR;
  1.5144 +  DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
  1.5145 +
  1.5146 +  // We're about to use Atomic::xchg for synchronization.  Some Zero
  1.5147 +  // platforms use the GCC builtin __sync_lock_test_and_set for this,
  1.5148 +  // but __sync_lock_test_and_set is not guaranteed to do what we want
  1.5149 +  // on all architectures.  So we check it works before relying on it.
  1.5150 +#if defined(ZERO) && defined(ASSERT)
  1.5151 +  {
  1.5152 +    jint a = 0xcafebabe;
  1.5153 +    jint b = Atomic::xchg(0xdeadbeef, &a);
  1.5154 +    void *c = &a;
  1.5155 +    void *d = Atomic::xchg_ptr(&b, &c);
  1.5156 +    assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
  1.5157 +    assert(c == &b && d == &a, "Atomic::xchg_ptr() works");
  1.5158 +  }
  1.5159 +#endif // ZERO && ASSERT
  1.5160 +
  1.5161 +  // At the moment it's only possible to have one Java VM,
  1.5162 +  // since some of the runtime state is in global variables.
  1.5163 +
  1.5164 +  // We cannot use our mutex locks here, since they only work on
  1.5165 +  // Threads. We do an atomic compare and exchange to ensure only
  1.5166 +  // one thread can call this method at a time
  1.5167 +
  1.5168 +  // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
  1.5169 +  // the add/dec implementations are dependent on whether we are running
  1.5170 +  // on a multiprocessor, and at this stage of initialization the os::is_MP
  1.5171 +  // function used to determine this will always return false. Atomic::xchg
  1.5172 +  // does not have this problem.
  1.5173 +  if (Atomic::xchg(1, &vm_created) == 1) {
  1.5174 +    return JNI_EEXIST;   // already created, or create attempt in progress
  1.5175 +  }
  1.5176 +  if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
  1.5177 +    return JNI_ERR;  // someone tried and failed and retry not allowed.
  1.5178 +  }
  1.5179 +
  1.5180 +  assert(vm_created == 1, "vm_created is true during the creation");
  1.5181 +
  1.5182 +  /**
  1.5183 +   * Certain errors during initialization are recoverable and do not
  1.5184 +   * prevent this method from being called again at a later time
  1.5185 +   * (perhaps with different arguments).  However, at a certain
  1.5186 +   * point during initialization if an error occurs we cannot allow
  1.5187 +   * this function to be called again (or it will crash).  In those
  1.5188 +   * situations, the 'canTryAgain' flag is set to false, which atomically
  1.5189 +   * sets safe_to_recreate_vm to 1, such that any new call to
  1.5190 +   * JNI_CreateJavaVM will immediately fail using the above logic.
  1.5191 +   */
  1.5192 +  bool can_try_again = true;
  1.5193 +
  1.5194 +  result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
  1.5195 +  if (result == JNI_OK) {
  1.5196 +    JavaThread *thread = JavaThread::current();
  1.5197 +    /* thread is thread_in_vm here */
  1.5198 +    *vm = (JavaVM *)(&main_vm);
  1.5199 +    *(JNIEnv**)penv = thread->jni_environment();
  1.5200 +
  1.5201 +    // Tracks the time application was running before GC
  1.5202 +    RuntimeService::record_application_start();
  1.5203 +
  1.5204 +    // Notify JVMTI
  1.5205 +    if (JvmtiExport::should_post_thread_life()) {
  1.5206 +       JvmtiExport::post_thread_start(thread);
  1.5207 +    }
  1.5208 +
  1.5209 +    EventThreadStart event;
  1.5210 +    if (event.should_commit()) {
  1.5211 +      event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
  1.5212 +      event.commit();
  1.5213 +    }
  1.5214 +
  1.5215 +#ifndef PRODUCT
  1.5216 +  #ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED
  1.5217 +    #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
  1.5218 +  #endif
  1.5219 +
  1.5220 +    // Check if we should compile all classes on bootclasspath
  1.5221 +    if (CompileTheWorld) ClassLoader::compile_the_world();
  1.5222 +    if (ReplayCompiles) ciReplay::replay(thread);
  1.5223 +
  1.5224 +    // Some platforms (like Win*) need a wrapper around these test
  1.5225 +    // functions in order to properly handle error conditions.
  1.5226 +    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(test_error_handler);
  1.5227 +    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(execute_internal_vm_tests);
  1.5228 +#endif
  1.5229 +
  1.5230 +    // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
  1.5231 +    ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
  1.5232 +  } else {
  1.5233 +    if (can_try_again) {
  1.5234 +      // reset safe_to_recreate_vm to 1 so that retrial would be possible
  1.5235 +      safe_to_recreate_vm = 1;
  1.5236 +    }
  1.5237 +
  1.5238 +    // Creation failed. We must reset vm_created
  1.5239 +    *vm = 0;
  1.5240 +    *(JNIEnv**)penv = 0;
  1.5241 +    // reset vm_created last to avoid race condition. Use OrderAccess to
  1.5242 +    // control both compiler and architectural-based reordering.
  1.5243 +    OrderAccess::release_store(&vm_created, 0);
  1.5244 +  }
  1.5245 +
  1.5246 +  return result;
  1.5247 +}
  1.5248 +
  1.5249 +#ifndef USDT2
  1.5250 +HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \
  1.5251 +  JavaVM**, jsize, jsize*);
  1.5252 +HS_DTRACE_PROBE_DECL1(hotspot_jni, GetCreatedJavaVMs__return, jint);
  1.5253 +#endif /* !USDT2 */
  1.5254 +
  1.5255 +_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
  1.5256 +  // See bug 4367188, the wrapper can sometimes cause VM crashes
  1.5257 +  // JNIWrapper("GetCreatedJavaVMs");
  1.5258 +#ifndef USDT2
  1.5259 +  HS_DTRACE_PROBE3(hotspot_jni, GetCreatedJavaVMs__entry, \
  1.5260 +    vm_buf, bufLen, numVMs);
  1.5261 +#else /* USDT2 */
  1.5262 +  HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY(
  1.5263 +                                      (void **) vm_buf, bufLen, (uintptr_t *) numVMs);
  1.5264 +#endif /* USDT2 */
  1.5265 +  if (vm_created) {
  1.5266 +    if (numVMs != NULL) *numVMs = 1;
  1.5267 +    if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
  1.5268 +  } else {
  1.5269 +    if (numVMs != NULL) *numVMs = 0;
  1.5270 +  }
  1.5271 +#ifndef USDT2
  1.5272 +  HS_DTRACE_PROBE1(hotspot_jni, GetCreatedJavaVMs__return, JNI_OK);
  1.5273 +#else /* USDT2 */
  1.5274 +  HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(
  1.5275 +                                    JNI_OK);
  1.5276 +#endif /* USDT2 */
  1.5277 +  return JNI_OK;
  1.5278 +}
  1.5279 +
  1.5280 +extern "C" {
  1.5281 +
  1.5282 +#ifndef USDT2
  1.5283 +DT_RETURN_MARK_DECL(DestroyJavaVM, jint);
  1.5284 +#else /* USDT2 */
  1.5285 +DT_RETURN_MARK_DECL(DestroyJavaVM, jint
  1.5286 +                    , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
  1.5287 +#endif /* USDT2 */
  1.5288 +
  1.5289 +jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
  1.5290 +#ifndef USDT2
  1.5291 +  DTRACE_PROBE1(hotspot_jni, DestroyJavaVM__entry, vm);
  1.5292 +#else /* USDT2 */
  1.5293 +  HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(
  1.5294 +                                  vm);
  1.5295 +#endif /* USDT2 */
  1.5296 +  jint res = JNI_ERR;
  1.5297 +  DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
  1.5298 +
  1.5299 +  if (!vm_created) {
  1.5300 +    res = JNI_ERR;
  1.5301 +    return res;
  1.5302 +  }
  1.5303 +
  1.5304 +  JNIWrapper("DestroyJavaVM");
  1.5305 +  JNIEnv *env;
  1.5306 +  JavaVMAttachArgs destroyargs;
  1.5307 +  destroyargs.version = CurrentVersion;
  1.5308 +  destroyargs.name = (char *)"DestroyJavaVM";
  1.5309 +  destroyargs.group = NULL;
  1.5310 +  res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
  1.5311 +  if (res != JNI_OK) {
  1.5312 +    return res;
  1.5313 +  }
  1.5314 +
  1.5315 +  // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
  1.5316 +  JavaThread* thread = JavaThread::current();
  1.5317 +  ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
  1.5318 +  if (Threads::destroy_vm()) {
  1.5319 +    // Should not change thread state, VM is gone
  1.5320 +    vm_created = false;
  1.5321 +    res = JNI_OK;
  1.5322 +    return res;
  1.5323 +  } else {
  1.5324 +    ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
  1.5325 +    res = JNI_ERR;
  1.5326 +    return res;
  1.5327 +  }
  1.5328 +}
  1.5329 +
  1.5330 +
  1.5331 +static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) {
  1.5332 +  JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args;
  1.5333 +
  1.5334 +  // Check below commented out from JDK1.2fcs as well
  1.5335 +  /*
  1.5336 +  if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) {
  1.5337 +    return JNI_EVERSION;
  1.5338 +  }
  1.5339 +  */
  1.5340 +
  1.5341 +  Thread* t = ThreadLocalStorage::get_thread_slow();
  1.5342 +  if (t != NULL) {
  1.5343 +    // If the thread has been attached this operation is a no-op
  1.5344 +    *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();
  1.5345 +    return JNI_OK;
  1.5346 +  }
  1.5347 +
  1.5348 +  // Create a thread and mark it as attaching so it will be skipped by the
  1.5349 +  // ThreadsListEnumerator - see CR 6404306
  1.5350 +  JavaThread* thread = new JavaThread(true);
  1.5351 +
  1.5352 +  // Set correct safepoint info. The thread is going to call into Java when
  1.5353 +  // initializing the Java level thread object. Hence, the correct state must
  1.5354 +  // be set in order for the Safepoint code to deal with it correctly.
  1.5355 +  thread->set_thread_state(_thread_in_vm);
  1.5356 +  // Must do this before initialize_thread_local_storage
  1.5357 +  thread->record_stack_base_and_size();
  1.5358 +
  1.5359 +  thread->initialize_thread_local_storage();
  1.5360 +
  1.5361 +  if (!os::create_attached_thread(thread)) {
  1.5362 +    delete thread;
  1.5363 +    return JNI_ERR;
  1.5364 +  }
  1.5365 +  // Enable stack overflow checks
  1.5366 +  thread->create_stack_guard_pages();
  1.5367 +
  1.5368 +  thread->initialize_tlab();
  1.5369 +
  1.5370 +  thread->cache_global_variables();
  1.5371 +
  1.5372 +  // Crucial that we do not have a safepoint check for this thread, since it has
  1.5373 +  // not been added to the Thread list yet.
  1.5374 +  { Threads_lock->lock_without_safepoint_check();
  1.5375 +    // This must be inside this lock in order to get FullGCALot to work properly, i.e., to
  1.5376 +    // avoid this thread trying to do a GC before it is added to the thread-list
  1.5377 +    thread->set_active_handles(JNIHandleBlock::allocate_block());
  1.5378 +    Threads::add(thread, daemon);
  1.5379 +    Threads_lock->unlock();
  1.5380 +  }
  1.5381 +  // Create thread group and name info from attach arguments
  1.5382 +  oop group = NULL;
  1.5383 +  char* thread_name = NULL;
  1.5384 +  if (args != NULL && Threads::is_supported_jni_version(args->version)) {
  1.5385 +    group = JNIHandles::resolve(args->group);
  1.5386 +    thread_name = args->name; // may be NULL
  1.5387 +  }
  1.5388 +  if (group == NULL) group = Universe::main_thread_group();
  1.5389 +
  1.5390 +  // Create Java level thread object and attach it to this thread
  1.5391 +  bool attach_failed = false;
  1.5392 +  {
  1.5393 +    EXCEPTION_MARK;
  1.5394 +    HandleMark hm(THREAD);
  1.5395 +    Handle thread_group(THREAD, group);
  1.5396 +    thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD);
  1.5397 +    if (HAS_PENDING_EXCEPTION) {
  1.5398 +      CLEAR_PENDING_EXCEPTION;
  1.5399 +      // cleanup outside the handle mark.
  1.5400 +      attach_failed = true;
  1.5401 +    }
  1.5402 +  }
  1.5403 +
  1.5404 +  if (attach_failed) {
  1.5405 +    // Added missing cleanup
  1.5406 +    thread->cleanup_failed_attach_current_thread();
  1.5407 +    return JNI_ERR;
  1.5408 +  }
  1.5409 +
  1.5410 +  // mark the thread as no longer attaching
  1.5411 +  // this uses a fence to push the change through so we don't have
  1.5412 +  // to regrab the threads_lock
  1.5413 +  thread->set_done_attaching_via_jni();
  1.5414 +
  1.5415 +  // Set java thread status.
  1.5416 +  java_lang_Thread::set_thread_status(thread->threadObj(),
  1.5417 +              java_lang_Thread::RUNNABLE);
  1.5418 +
  1.5419 +  // Notify the debugger
  1.5420 +  if (JvmtiExport::should_post_thread_life()) {
  1.5421 +    JvmtiExport::post_thread_start(thread);
  1.5422 +  }
  1.5423 +
  1.5424 +  EventThreadStart event;
  1.5425 +  if (event.should_commit()) {
  1.5426 +    event.set_javalangthread(java_lang_Thread::thread_id(thread->threadObj()));
  1.5427 +    event.commit();
  1.5428 +  }
  1.5429 +
  1.5430 +  *(JNIEnv**)penv = thread->jni_environment();
  1.5431 +
  1.5432 +  // Now leaving the VM, so change thread_state. This is normally automatically taken care
  1.5433 +  // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
  1.5434 +  // using ThreadStateTransition::transition, we do a callback to the safepoint code if
  1.5435 +  // needed.
  1.5436 +
  1.5437 +  ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
  1.5438 +
  1.5439 +  // Perform any platform dependent FPU setup
  1.5440 +  os::setup_fpu();
  1.5441 +
  1.5442 +  return JNI_OK;
  1.5443 +}
  1.5444 +
  1.5445 +
  1.5446 +jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
  1.5447 +#ifndef USDT2
  1.5448 +  DTRACE_PROBE3(hotspot_jni, AttachCurrentThread__entry, vm, penv, _args);
  1.5449 +#else /* USDT2 */
  1.5450 +  HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(
  1.5451 +                                        vm, penv, _args);
  1.5452 +#endif /* USDT2 */
  1.5453 +  if (!vm_created) {
  1.5454 +#ifndef USDT2
  1.5455 +    DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, JNI_ERR);
  1.5456 +#else /* USDT2 */
  1.5457 +  HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(
  1.5458 +                                         (uint32_t) JNI_ERR);
  1.5459 +#endif /* USDT2 */
  1.5460 +    return JNI_ERR;
  1.5461 +  }
  1.5462 +
  1.5463 +  JNIWrapper("AttachCurrentThread");
  1.5464 +  jint ret = attach_current_thread(vm, penv, _args, false);
  1.5465 +#ifndef USDT2
  1.5466 +  DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, ret);
  1.5467 +#else /* USDT2 */
  1.5468 +  HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(
  1.5469 +                                         ret);
  1.5470 +#endif /* USDT2 */
  1.5471 +  return ret;
  1.5472 +}
  1.5473 +
  1.5474 +
  1.5475 +jint JNICALL jni_DetachCurrentThread(JavaVM *vm)  {
  1.5476 +#ifndef USDT2
  1.5477 +  DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__entry, vm);
  1.5478 +#else /* USDT2 */
  1.5479 +  HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(
  1.5480 +                                        vm);
  1.5481 +#endif /* USDT2 */
  1.5482 +  VM_Exit::block_if_vm_exited();
  1.5483 +
  1.5484 +  JNIWrapper("DetachCurrentThread");
  1.5485 +
  1.5486 +  // If the thread has been deattacted the operations is a no-op
  1.5487 +  if (ThreadLocalStorage::thread() == NULL) {
  1.5488 +#ifndef USDT2
  1.5489 +    DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
  1.5490 +#else /* USDT2 */
  1.5491 +  HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
  1.5492 +                                         JNI_OK);
  1.5493 +#endif /* USDT2 */
  1.5494 +    return JNI_OK;
  1.5495 +  }
  1.5496 +
  1.5497 +  JavaThread* thread = JavaThread::current();
  1.5498 +  if (thread->has_last_Java_frame()) {
  1.5499 +#ifndef USDT2
  1.5500 +    DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_ERR);
  1.5501 +#else /* USDT2 */
  1.5502 +  HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
  1.5503 +                                         (uint32_t) JNI_ERR);
  1.5504 +#endif /* USDT2 */
  1.5505 +    // Can't detach a thread that's running java, that can't work.
  1.5506 +    return JNI_ERR;
  1.5507 +  }
  1.5508 +
  1.5509 +  // Safepoint support. Have to do call-back to safepoint code, if in the
  1.5510 +  // middel of a safepoint operation
  1.5511 +  ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
  1.5512 +
  1.5513 +  // XXX: Note that JavaThread::exit() call below removes the guards on the
  1.5514 +  // stack pages set up via enable_stack_{red,yellow}_zone() calls
  1.5515 +  // above in jni_AttachCurrentThread. Unfortunately, while the setting
  1.5516 +  // of the guards is visible in jni_AttachCurrentThread above,
  1.5517 +  // the removal of the guards is buried below in JavaThread::exit()
  1.5518 +  // here. The abstraction should be more symmetrically either exposed
  1.5519 +  // or hidden (e.g. it could probably be hidden in the same
  1.5520 +  // (platform-dependent) methods where we do alternate stack
  1.5521 +  // maintenance work?)
  1.5522 +  thread->exit(false, JavaThread::jni_detach);
  1.5523 +  delete thread;
  1.5524 +
  1.5525 +#ifndef USDT2
  1.5526 +  DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
  1.5527 +#else /* USDT2 */
  1.5528 +  HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
  1.5529 +                                         JNI_OK);
  1.5530 +#endif /* USDT2 */
  1.5531 +  return JNI_OK;
  1.5532 +}
  1.5533 +
  1.5534 +#ifndef USDT2
  1.5535 +DT_RETURN_MARK_DECL(GetEnv, jint);
  1.5536 +#else /* USDT2 */
  1.5537 +DT_RETURN_MARK_DECL(GetEnv, jint
  1.5538 +                    , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
  1.5539 +#endif /* USDT2 */
  1.5540 +
  1.5541 +jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
  1.5542 +#ifndef USDT2
  1.5543 +  DTRACE_PROBE3(hotspot_jni, GetEnv__entry, vm, penv, version);
  1.5544 +#else /* USDT2 */
  1.5545 +  HOTSPOT_JNI_GETENV_ENTRY(
  1.5546 +                           vm, penv, version);
  1.5547 +#endif /* USDT2 */
  1.5548 +  jint ret = JNI_ERR;
  1.5549 +  DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
  1.5550 +
  1.5551 +  if (!vm_created) {
  1.5552 +    *penv = NULL;
  1.5553 +    ret = JNI_EDETACHED;
  1.5554 +    return ret;
  1.5555 +  }
  1.5556 +
  1.5557 +  if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {
  1.5558 +    return ret;
  1.5559 +  }
  1.5560 +
  1.5561 +#ifndef JVMPI_VERSION_1
  1.5562 +// need these in order to be polite about older agents
  1.5563 +#define JVMPI_VERSION_1   ((jint)0x10000001)
  1.5564 +#define JVMPI_VERSION_1_1 ((jint)0x10000002)
  1.5565 +#define JVMPI_VERSION_1_2 ((jint)0x10000003)
  1.5566 +#endif // !JVMPI_VERSION_1
  1.5567 +
  1.5568 +  Thread* thread = ThreadLocalStorage::thread();
  1.5569 +  if (thread != NULL && thread->is_Java_thread()) {
  1.5570 +    if (Threads::is_supported_jni_version_including_1_1(version)) {
  1.5571 +      *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
  1.5572 +      ret = JNI_OK;
  1.5573 +      return ret;
  1.5574 +
  1.5575 +    } else if (version == JVMPI_VERSION_1 ||
  1.5576 +               version == JVMPI_VERSION_1_1 ||
  1.5577 +               version == JVMPI_VERSION_1_2) {
  1.5578 +      tty->print_cr("ERROR: JVMPI, an experimental interface, is no longer supported.");
  1.5579 +      tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
  1.5580 +      ret = JNI_EVERSION;
  1.5581 +      return ret;
  1.5582 +    } else if (JvmtiExport::is_jvmdi_version(version)) {
  1.5583 +      tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");
  1.5584 +      tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
  1.5585 +      ret = JNI_EVERSION;
  1.5586 +      return ret;
  1.5587 +    } else {
  1.5588 +      *penv = NULL;
  1.5589 +      ret = JNI_EVERSION;
  1.5590 +      return ret;
  1.5591 +    }
  1.5592 +  } else {
  1.5593 +    *penv = NULL;
  1.5594 +    ret = JNI_EDETACHED;
  1.5595 +    return ret;
  1.5596 +  }
  1.5597 +}
  1.5598 +
  1.5599 +
  1.5600 +jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
  1.5601 +#ifndef USDT2
  1.5602 +  DTRACE_PROBE3(hotspot_jni, AttachCurrentThreadAsDaemon__entry, vm, penv, _args);
  1.5603 +#else /* USDT2 */
  1.5604 +  HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(
  1.5605 +                                                vm, penv, _args);
  1.5606 +#endif /* USDT2 */
  1.5607 +  if (!vm_created) {
  1.5608 +#ifndef USDT2
  1.5609 +    DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, JNI_ERR);
  1.5610 +#else /* USDT2 */
  1.5611 +  HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(
  1.5612 +                                                 (uint32_t) JNI_ERR);
  1.5613 +#endif /* USDT2 */
  1.5614 +    return JNI_ERR;
  1.5615 +  }
  1.5616 +
  1.5617 +  JNIWrapper("AttachCurrentThreadAsDaemon");
  1.5618 +  jint ret = attach_current_thread(vm, penv, _args, true);
  1.5619 +#ifndef USDT2
  1.5620 +  DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, ret);
  1.5621 +#else /* USDT2 */
  1.5622 +  HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(
  1.5623 +                                                 ret);
  1.5624 +#endif /* USDT2 */
  1.5625 +  return ret;
  1.5626 +}
  1.5627 +
  1.5628 +
  1.5629 +} // End extern "C"
  1.5630 +
  1.5631 +const struct JNIInvokeInterface_ jni_InvokeInterface = {
  1.5632 +    NULL,
  1.5633 +    NULL,
  1.5634 +    NULL,
  1.5635 +
  1.5636 +    jni_DestroyJavaVM,
  1.5637 +    jni_AttachCurrentThread,
  1.5638 +    jni_DetachCurrentThread,
  1.5639 +    jni_GetEnv,
  1.5640 +    jni_AttachCurrentThreadAsDaemon
  1.5641 +};

mercurial