1 /*
   2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/classLoader.hpp"
  27 #include "classfile/javaClasses.hpp"
  28 #include "classfile/symbolTable.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 #include "interpreter/linkResolver.hpp"
  32 #ifndef SERIALGC
  33 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
  34 #endif // SERIALGC
  35 #include "memory/allocation.inline.hpp"
  36 #include "memory/gcLocker.inline.hpp"
  37 #include "memory/oopFactory.hpp"
  38 #include "memory/universe.inline.hpp"
  39 #include "oops/instanceKlass.hpp"
  40 #include "oops/instanceOop.hpp"
  41 #include "oops/markOop.hpp"
  42 #include "oops/methodOop.hpp"
  43 #include "oops/objArrayKlass.hpp"
  44 #include "oops/objArrayOop.hpp"
  45 #include "oops/oop.inline.hpp"
  46 #include "oops/symbol.hpp"
  47 #include "oops/typeArrayKlass.hpp"
  48 #include "oops/typeArrayOop.hpp"
  49 #include "prims/jni.h"
  50 #include "prims/jniCheck.hpp"
  51 #include "prims/jniFastGetField.hpp"
  52 #include "prims/jvm.h"
  53 #include "prims/jvm_misc.hpp"
  54 #include "prims/jvmtiExport.hpp"
  55 #include "prims/jvmtiThreadState.hpp"
  56 #include "runtime/compilationPolicy.hpp"
  57 #include "runtime/fieldDescriptor.hpp"
  58 #include "runtime/fprofiler.hpp"
  59 #include "runtime/handles.inline.hpp"
  60 #include "runtime/interfaceSupport.hpp"
  61 #include "runtime/java.hpp"
  62 #include "runtime/javaCalls.hpp"
  63 #include "runtime/jfieldIDWorkaround.hpp"
  64 #include "runtime/reflection.hpp"
  65 #include "runtime/sharedRuntime.hpp"
  66 #include "runtime/signature.hpp"
  67 #include "runtime/vm_operations.hpp"
  68 #include "services/runtimeService.hpp"
  69 #include "utilities/defaultStream.hpp"
  70 #include "utilities/dtrace.hpp"
  71 #include "utilities/events.hpp"
  72 #include "utilities/histogram.hpp"
  73 #ifdef TARGET_OS_FAMILY_linux
  74 # include "os_linux.inline.hpp"
  75 # include "thread_linux.inline.hpp"
  76 #endif
  77 #ifdef TARGET_OS_FAMILY_solaris
  78 # include "os_solaris.inline.hpp"
  79 # include "thread_solaris.inline.hpp"
  80 #endif
  81 #ifdef TARGET_OS_FAMILY_windows
  82 # include "os_windows.inline.hpp"
  83 # include "thread_windows.inline.hpp"
  84 #endif
  85 #ifdef TARGET_OS_FAMILY_bsd
  86 # include "os_bsd.inline.hpp"
  87 # include "thread_bsd.inline.hpp"
  88 #endif
  89 
  90 static jint CurrentVersion = JNI_VERSION_1_6;
  91 
  92 
  93 // The DT_RETURN_MARK macros create a scoped object to fire the dtrace
  94 // '-return' probe regardless of the return path is taken out of the function.
  95 // Methods that have multiple return paths use this to avoid having to
  96 // instrument each return path.  Methods that use CHECK or THROW must use this
  97 // since those macros can cause an immedate uninstrumented return.
  98 //
  99 // In order to get the return value, a reference to the variable containing
 100 // the return value must be passed to the contructor of the object, and
 101 // the return value must be set before return (since the mark object has
 102 // a reference to it).
 103 //
 104 // Example:
 105 // DT_RETURN_MARK_DECL(SomeFunc, int);
 106 // JNI_ENTRY(int, SomeFunc, ...)
 107 //   int return_value = 0;
 108 //   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
 109 //   foo(CHECK_0)
 110 //   return_value = 5;
 111 //   return return_value;
 112 // JNI_END
 113 #ifndef USDT2
 114 #define DT_RETURN_MARK_DECL(name, type)                                    \
 115   HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type);                \
 116   DTRACE_ONLY(                                                             \
 117     class DTraceReturnProbeMark_##name {                                   \
 118      public:                                                               \
 119       const type& _ret_ref;                                                \
 120       DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
 121       ~DTraceReturnProbeMark_##name() {                                    \
 122         HS_DTRACE_PROBE1(hotspot_jni, name##__return, _ret_ref);           \
 123       }                                                                    \
 124     }                                                                      \
 125   )
 126 // Void functions are simpler since there's no return value
 127 #define DT_VOID_RETURN_MARK_DECL(name)                                     \
 128   HS_DTRACE_PROBE_DECL0(hotspot_jni, name##__return);                      \
 129   DTRACE_ONLY(                                                             \
 130     class DTraceReturnProbeMark_##name {                                   \
 131      public:                                                               \
 132       ~DTraceReturnProbeMark_##name() {                                    \
 133         HS_DTRACE_PROBE0(hotspot_jni, name##__return);                     \
 134       }                                                                    \
 135     }                                                                      \
 136   )
 137 
 138 #else /* USDT2 */
 139 
 140 #define DT_RETURN_MARK_DECL(name, type, probe)                             \
 141   DTRACE_ONLY(                                                             \
 142     class DTraceReturnProbeMark_##name {                                   \
 143      public:                                                               \
 144       const type& _ret_ref;                                                \
 145       DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
 146       ~DTraceReturnProbeMark_##name() {                                    \
 147         probe;                                                             \
 148       }                                                                    \
 149     }                                                                      \
 150   )
 151 // Void functions are simpler since there's no return value
 152 #define DT_VOID_RETURN_MARK_DECL(name, probe)                              \
 153   DTRACE_ONLY(                                                             \
 154     class DTraceReturnProbeMark_##name {                                   \
 155      public:                                                               \
 156       ~DTraceReturnProbeMark_##name() {                                    \
 157         probe;                                                             \
 158       }                                                                    \
 159     }                                                                      \
 160   )
 161 #endif /* USDT2 */
 162 
 163 // Place these macros in the function to mark the return.  Non-void
 164 // functions need the type and address of the return value.
 165 #define DT_RETURN_MARK(name, type, ref) \
 166   DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )
 167 #define DT_VOID_RETURN_MARK(name) \
 168   DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )
 169 
 170 
 171 // Use these to select distinct code for floating-point vs. non-floating point
 172 // situations.  Used from within common macros where we need slightly
 173 // different behavior for Float/Double
 174 #define FP_SELECT_Boolean(intcode, fpcode) intcode
 175 #define FP_SELECT_Byte(intcode, fpcode)    intcode
 176 #define FP_SELECT_Char(intcode, fpcode)    intcode
 177 #define FP_SELECT_Short(intcode, fpcode)   intcode
 178 #define FP_SELECT_Object(intcode, fpcode)  intcode
 179 #define FP_SELECT_Int(intcode, fpcode)     intcode
 180 #define FP_SELECT_Long(intcode, fpcode)    intcode
 181 #define FP_SELECT_Float(intcode, fpcode)   fpcode
 182 #define FP_SELECT_Double(intcode, fpcode)  fpcode
 183 #define FP_SELECT(TypeName, intcode, fpcode) \
 184   FP_SELECT_##TypeName(intcode, fpcode)
 185 
 186 #define COMMA ,
 187 
 188 // Choose DT_RETURN_MARK macros  based on the type: float/double -> void
 189 // (dtrace doesn't do FP yet)
 190 #ifndef USDT2
 191 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \
 192   FP_SELECT(TypeName, \
 193     DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) )
 194 #else /* USDT2 */
 195 #define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe)    \
 196   FP_SELECT(TypeName, \
 197     DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
 198 #endif /* USDT2 */
 199 #define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
 200   FP_SELECT(TypeName, \
 201     DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
 202 
 203 
 204 // out-of-line helpers for class jfieldIDWorkaround:
 205 
 206 bool jfieldIDWorkaround::is_valid_jfieldID(klassOop k, jfieldID id) {
 207   if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
 208     uintptr_t as_uint = (uintptr_t) id;
 209     intptr_t offset = raw_instance_offset(id);
 210     if (is_checked_jfieldID(id)) {
 211       if (!klass_hash_ok(k, id)) {
 212         return false;
 213       }
 214     }
 215     return instanceKlass::cast(k)->contains_field_offset(offset);
 216   } else {
 217     JNIid* result = (JNIid*) id;
 218 #ifdef ASSERT
 219     return result != NULL && result->is_static_field_id();
 220 #else
 221     return result != NULL;
 222 #endif
 223   }
 224 }
 225 
 226 
 227 intptr_t jfieldIDWorkaround::encode_klass_hash(klassOop k, intptr_t offset) {
 228   if (offset <= small_offset_mask) {
 229     klassOop field_klass = k;
 230     klassOop super_klass = Klass::cast(field_klass)->super();
 231     // With compressed oops the most super class with nonstatic fields would
 232     // be the owner of fields embedded in the header.
 233     while (instanceKlass::cast(super_klass)->has_nonstatic_fields() &&
 234            instanceKlass::cast(super_klass)->contains_field_offset(offset)) {
 235       field_klass = super_klass;   // super contains the field also
 236       super_klass = Klass::cast(field_klass)->super();
 237     }
 238     debug_only(No_Safepoint_Verifier nosafepoint;)
 239     uintptr_t klass_hash = field_klass->identity_hash();
 240     return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
 241   } else {
 242 #if 0
 243     #ifndef PRODUCT
 244     {
 245       ResourceMark rm;
 246       warning("VerifyJNIFields: long offset %d in %s", offset, Klass::cast(k)->external_name());
 247     }
 248     #endif
 249 #endif
 250     return 0;
 251   }
 252 }
 253 
 254 bool jfieldIDWorkaround::klass_hash_ok(klassOop k, jfieldID id) {
 255   uintptr_t as_uint = (uintptr_t) id;
 256   intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
 257   do {
 258     debug_only(No_Safepoint_Verifier nosafepoint;)
 259     // Could use a non-blocking query for identity_hash here...
 260     if ((k->identity_hash() & klass_mask) == klass_hash)
 261       return true;
 262     k = Klass::cast(k)->super();
 263   } while (k != NULL);
 264   return false;
 265 }
 266 
 267 void jfieldIDWorkaround::verify_instance_jfieldID(klassOop k, jfieldID id) {
 268   guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
 269   uintptr_t as_uint = (uintptr_t) id;
 270   intptr_t offset = raw_instance_offset(id);
 271   if (VerifyJNIFields) {
 272     if (is_checked_jfieldID(id)) {
 273       guarantee(klass_hash_ok(k, id),
 274     "Bug in native code: jfieldID class must match object");
 275     } else {
 276 #if 0
 277       #ifndef PRODUCT
 278       if (Verbose) {
 279   ResourceMark rm;
 280   warning("VerifyJNIFields: unverified offset %d for %s", offset, Klass::cast(k)->external_name());
 281       }
 282       #endif
 283 #endif
 284     }
 285   }
 286   guarantee(instanceKlass::cast(k)->contains_field_offset(offset),
 287       "Bug in native code: jfieldID offset must address interior of object");
 288 }
 289 
 290 // Pick a reasonable higher bound for local capacity requested
 291 // for EnsureLocalCapacity and PushLocalFrame.  We don't want it too
 292 // high because a test (or very unusual application) may try to allocate
 293 // that many handles and run out of swap space.  An implementation is
 294 // permitted to allocate more handles than the ensured capacity, so this
 295 // value is set high enough to prevent compatibility problems.
 296 const int MAX_REASONABLE_LOCAL_CAPACITY = 4*K;
 297 
 298 
 299 // Wrapper to trace JNI functions
 300 
 301 #ifdef ASSERT
 302   Histogram* JNIHistogram;
 303   static volatile jint JNIHistogram_lock = 0;
 304 
 305   class JNITraceWrapper : public StackObj {
 306    public:
 307     JNITraceWrapper(const char* format, ...) {
 308       if (TraceJNICalls) {
 309         va_list ap;
 310         va_start(ap, format);
 311         tty->print("JNI ");
 312         tty->vprint_cr(format, ap);
 313         va_end(ap);
 314       }
 315     }
 316   };
 317 
 318   class JNIHistogramElement : public HistogramElement {
 319     public:
 320      JNIHistogramElement(const char* name);
 321   };
 322 
 323   JNIHistogramElement::JNIHistogramElement(const char* elementName) {
 324     _name = elementName;
 325     uintx count = 0;
 326 
 327     while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) {
 328       while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) {
 329         count +=1;
 330         if ( (WarnOnStalledSpinLock > 0)
 331           && (count % WarnOnStalledSpinLock == 0)) {
 332           warning("JNIHistogram_lock seems to be stalled");
 333         }
 334       }
 335      }
 336 
 337 
 338     if(JNIHistogram == NULL)
 339       JNIHistogram = new Histogram("JNI Call Counts",100);
 340 
 341     JNIHistogram->add_element(this);
 342     Atomic::dec(&JNIHistogram_lock);
 343   }
 344 
 345   #define JNICountWrapper(arg)                                     \
 346      static JNIHistogramElement* e = new JNIHistogramElement(arg); \
 347       /* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \
 348      if (e != NULL) e->increment_count()
 349   #define JNIWrapper(arg) JNICountWrapper(arg); JNITraceWrapper(arg)
 350 #else
 351   #define JNIWrapper(arg)
 352 #endif
 353 
 354 
 355 // Implementation of JNI entries
 356 
 357 #ifndef USDT2
 358 DT_RETURN_MARK_DECL(DefineClass, jclass);
 359 #else /* USDT2 */
 360 DT_RETURN_MARK_DECL(DefineClass, jclass
 361                     , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));
 362 #endif /* USDT2 */
 363 
 364 JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,
 365                                   const jbyte *buf, jsize bufLen))
 366   JNIWrapper("DefineClass");
 367 
 368 #ifndef USDT2
 369   DTRACE_PROBE5(hotspot_jni, DefineClass__entry,
 370     env, name, loaderRef, buf, bufLen);
 371 #else /* USDT2 */
 372   HOTSPOT_JNI_DEFINECLASS_ENTRY(
 373     env, (char*) name, loaderRef, (char*) buf, bufLen);
 374 #endif /* USDT2 */
 375   jclass cls = NULL;
 376   DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);
 377 
 378   // Since exceptions can be thrown, class initialization can take place
 379   // if name is NULL no check for class name in .class stream has to be made.
 380   if (name != NULL) {
 381     const int str_len = (int)strlen(name);
 382     if (str_len > Symbol::max_length()) {
 383       // It's impossible to create this class;  the name cannot fit
 384       // into the constant pool.
 385       THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
 386     }
 387   }
 388   TempNewSymbol class_name = SymbolTable::new_symbol(name, THREAD);
 389 
 390   ResourceMark rm(THREAD);
 391   ClassFileStream st((u1*) buf, bufLen, NULL);
 392   Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));
 393 
 394   if (UsePerfData && !class_loader.is_null()) {
 395     // check whether the current caller thread holds the lock or not.
 396     // If not, increment the corresponding counter
 397     if (ObjectSynchronizer::
 398         query_lock_ownership((JavaThread*)THREAD, class_loader) !=
 399         ObjectSynchronizer::owner_self) {
 400       ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
 401     }
 402   }
 403   klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
 404                                                      Handle(), &st, true,
 405                                                      CHECK_NULL);
 406 
 407   if (TraceClassResolution && k != NULL) {
 408     trace_class_resolution(k);
 409   }
 410 
 411   cls = (jclass)JNIHandles::make_local(
 412     env, Klass::cast(k)->java_mirror());
 413   return cls;
 414 JNI_END
 415 
 416 
 417 
 418 static bool first_time_FindClass = true;
 419 
 420 #ifndef USDT2
 421 DT_RETURN_MARK_DECL(FindClass, jclass);
 422 #else /* USDT2 */
 423 DT_RETURN_MARK_DECL(FindClass, jclass
 424                     , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
 425 #endif /* USDT2 */
 426 
 427 JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))
 428   JNIWrapper("FindClass");
 429 #ifndef USDT2
 430   DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);
 431 #else /* USDT2 */
 432   HOTSPOT_JNI_FINDCLASS_ENTRY(
 433                               env, (char *)name);
 434 #endif /* USDT2 */
 435 
 436   jclass result = NULL;
 437   DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);
 438 
 439   // Remember if we are the first invocation of jni_FindClass
 440   bool first_time = first_time_FindClass;
 441   first_time_FindClass = false;
 442 
 443   // Sanity check the name:  it cannot be null or larger than the maximum size
 444   // name we can fit in the constant pool.
 445   if (name == NULL || (int)strlen(name) > Symbol::max_length()) {
 446     THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);
 447   }
 448 
 449   //%note jni_3
 450   Handle loader;
 451   Handle protection_domain;
 452   // Find calling class
 453   instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));
 454   if (k.not_null()) {
 455     loader = Handle(THREAD, k->class_loader());
 456     // Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed
 457     // in the correct class context.
 458     if (loader.is_null() &&
 459         k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {
 460       JavaValue result(T_OBJECT);
 461       JavaCalls::call_static(&result, k,
 462                                       vmSymbols::getFromClass_name(),
 463                                       vmSymbols::void_class_signature(),
 464                                       thread);
 465       if (HAS_PENDING_EXCEPTION) {
 466         Handle ex(thread, thread->pending_exception());
 467         CLEAR_PENDING_EXCEPTION;
 468         THROW_HANDLE_0(ex);
 469       }
 470       oop mirror = (oop) result.get_jobject();
 471       loader = Handle(THREAD,
 472         instanceKlass::cast(java_lang_Class::as_klassOop(mirror))->class_loader());
 473       protection_domain = Handle(THREAD,
 474         instanceKlass::cast(java_lang_Class::as_klassOop(mirror))->protection_domain());
 475     }
 476   } else {
 477     // We call ClassLoader.getSystemClassLoader to obtain the system class loader.
 478     loader = Handle(THREAD, SystemDictionary::java_system_loader());
 479   }
 480 
 481   TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
 482   result = find_class_from_class_loader(env, sym, true, loader,
 483                                         protection_domain, true, thread);
 484 
 485   if (TraceClassResolution && result != NULL) {
 486     trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
 487   }
 488 
 489   // If we were the first invocation of jni_FindClass, we enable compilation again
 490   // rather than just allowing invocation counter to overflow and decay.
 491   // Controlled by flag DelayCompilationDuringStartup.
 492   if (first_time && !CompileTheWorld)
 493     CompilationPolicy::completed_vm_startup();
 494 
 495   return result;
 496 JNI_END
 497 
 498 #ifndef USDT2
 499 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);
 500 #else /* USDT2 */
 501 DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
 502                     , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
 503 #endif /* USDT2 */
 504 
 505 JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))
 506   JNIWrapper("FromReflectedMethod");
 507 #ifndef USDT2
 508   DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method);
 509 #else /* USDT2 */
 510   HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(
 511                                         env, method);
 512 #endif /* USDT2 */
 513   jmethodID ret = NULL;
 514   DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);
 515 
 516   // method is a handle to a java.lang.reflect.Method object
 517   oop reflected  = JNIHandles::resolve_non_null(method);
 518   oop mirror     = NULL;
 519   int slot       = 0;
 520 
 521   if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {
 522     mirror = java_lang_reflect_Constructor::clazz(reflected);
 523     slot   = java_lang_reflect_Constructor::slot(reflected);
 524   } else {
 525     assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");
 526     mirror = java_lang_reflect_Method::clazz(reflected);
 527     slot   = java_lang_reflect_Method::slot(reflected);
 528   }
 529   klassOop k     = java_lang_Class::as_klassOop(mirror);
 530 
 531   KlassHandle k1(THREAD, k);
 532   // Make sure class is initialized before handing id's out to methods
 533   Klass::cast(k1())->initialize(CHECK_NULL);
 534   methodOop m = instanceKlass::cast(k1())->method_with_idnum(slot);
 535   ret = m==NULL? NULL : m->jmethod_id();  // return NULL if reflected method deleted
 536   return ret;
 537 JNI_END
 538 
 539 #ifndef USDT2
 540 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);
 541 #else /* USDT2 */
 542 DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
 543                     , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
 544 #endif /* USDT2 */
 545 
 546 JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))
 547   JNIWrapper("FromReflectedField");
 548 #ifndef USDT2
 549   DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field);
 550 #else /* USDT2 */
 551   HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(
 552                                        env, field);
 553 #endif /* USDT2 */
 554   jfieldID ret = NULL;
 555   DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);
 556 
 557   // field is a handle to a java.lang.reflect.Field object
 558   oop reflected   = JNIHandles::resolve_non_null(field);
 559   oop mirror      = java_lang_reflect_Field::clazz(reflected);
 560   klassOop k      = java_lang_Class::as_klassOop(mirror);
 561   int slot        = java_lang_reflect_Field::slot(reflected);
 562   int modifiers   = java_lang_reflect_Field::modifiers(reflected);
 563 
 564   KlassHandle k1(THREAD, k);
 565   // Make sure class is initialized before handing id's out to fields
 566   Klass::cast(k1())->initialize(CHECK_NULL);
 567 
 568   // First check if this is a static field
 569   if (modifiers & JVM_ACC_STATIC) {
 570     intptr_t offset = instanceKlass::cast(k1())->field_offset( slot );
 571     JNIid* id = instanceKlass::cast(k1())->jni_id_for(offset);
 572     assert(id != NULL, "corrupt Field object");
 573     debug_only(id->set_is_static_field_id();)
 574     // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the klassOop
 575     ret = jfieldIDWorkaround::to_static_jfieldID(id);
 576     return ret;
 577   }
 578 
 579   // The slot is the index of the field description in the field-array
 580   // The jfieldID is the offset of the field within the object
 581   // It may also have hash bits for k, if VerifyJNIFields is turned on.
 582   intptr_t offset = instanceKlass::cast(k1())->field_offset( slot );
 583   assert(instanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");
 584   ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);
 585   return ret;
 586 JNI_END
 587 
 588 #ifndef USDT2
 589 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);
 590 #else /* USDT2 */
 591 DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
 592                     , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
 593 #endif /* USDT2 */
 594 
 595 JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))
 596   JNIWrapper("ToReflectedMethod");
 597 #ifndef USDT2
 598   DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic);
 599 #else /* USDT2 */
 600   HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(
 601                                       env, cls, (uintptr_t) method_id, isStatic);
 602 #endif /* USDT2 */
 603   jobject ret = NULL;
 604   DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);
 605 
 606   methodHandle m (THREAD, JNIHandles::resolve_jmethod_id(method_id));
 607   assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");
 608   oop reflection_method;
 609   if (m->is_initializer()) {
 610     reflection_method = Reflection::new_constructor(m, CHECK_NULL);
 611   } else {
 612     reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL);
 613   }
 614   ret = JNIHandles::make_local(env, reflection_method);
 615   return ret;
 616 JNI_END
 617 
 618 #ifndef USDT2
 619 DT_RETURN_MARK_DECL(GetSuperclass, jclass);
 620 #else /* USDT2 */
 621 DT_RETURN_MARK_DECL(GetSuperclass, jclass
 622                     , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
 623 #endif /* USDT2 */
 624 
 625 JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))
 626   JNIWrapper("GetSuperclass");
 627 #ifndef USDT2
 628   DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub);
 629 #else /* USDT2 */
 630   HOTSPOT_JNI_GETSUPERCLASS_ENTRY(
 631                                   env, sub);
 632 #endif /* USDT2 */
 633   jclass obj = NULL;
 634   DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);
 635 
 636   oop mirror = JNIHandles::resolve_non_null(sub);
 637   // primitive classes return NULL
 638   if (java_lang_Class::is_primitive(mirror)) return NULL;
 639 
 640   // Rules of Class.getSuperClass as implemented by KLass::java_super:
 641   // arrays return Object
 642   // interfaces return NULL
 643   // proper classes return Klass::super()
 644   klassOop k = java_lang_Class::as_klassOop(mirror);
 645   if (Klass::cast(k)->is_interface()) return NULL;
 646 
 647   // return mirror for superclass
 648   klassOop super = Klass::cast(k)->java_super();
 649   // super2 is the value computed by the compiler's getSuperClass intrinsic:
 650   debug_only(klassOop super2 = ( Klass::cast(k)->oop_is_javaArray()
 651                                  ? SystemDictionary::Object_klass()
 652                                  : Klass::cast(k)->super() ) );
 653   assert(super == super2,
 654          "java_super computation depends on interface, array, other super");
 655   obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(Klass::cast(super)->java_mirror());
 656   return obj;
 657 JNI_END
 658 
 659 JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))
 660   JNIWrapper("IsSubclassOf");
 661 #ifndef USDT2
 662   DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super);
 663 #else /* USDT2 */
 664   HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(
 665                                      env, sub, super);
 666 #endif /* USDT2 */
 667   oop sub_mirror   = JNIHandles::resolve_non_null(sub);
 668   oop super_mirror = JNIHandles::resolve_non_null(super);
 669   if (java_lang_Class::is_primitive(sub_mirror) ||
 670       java_lang_Class::is_primitive(super_mirror)) {
 671     jboolean ret = (sub_mirror == super_mirror);
 672 #ifndef USDT2
 673     DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
 674 #else /* USDT2 */
 675     HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(
 676                                         ret);
 677 #endif /* USDT2 */
 678     return ret;
 679   }
 680   klassOop sub_klass   = java_lang_Class::as_klassOop(sub_mirror);
 681   klassOop super_klass = java_lang_Class::as_klassOop(super_mirror);
 682   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
 683   jboolean ret = Klass::cast(sub_klass)->is_subtype_of(super_klass) ?
 684                    JNI_TRUE : JNI_FALSE;
 685 #ifndef USDT2
 686   DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);
 687 #else /* USDT2 */
 688   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(
 689                                       ret);
 690 #endif /* USDT2 */
 691   return ret;
 692 JNI_END
 693 
 694 #ifndef USDT2
 695 DT_RETURN_MARK_DECL(Throw, jint);
 696 #else /* USDT2 */
 697 DT_RETURN_MARK_DECL(Throw, jint
 698                     , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
 699 #endif /* USDT2 */
 700 
 701 JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))
 702   JNIWrapper("Throw");
 703 #ifndef USDT2
 704   DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj);
 705 #else /* USDT2 */
 706   HOTSPOT_JNI_THROW_ENTRY(
 707  env, obj);
 708 #endif /* USDT2 */
 709   jint ret = JNI_OK;
 710   DT_RETURN_MARK(Throw, jint, (const jint&)ret);
 711 
 712   THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);
 713   ShouldNotReachHere();
 714 JNI_END
 715 
 716 #ifndef USDT2
 717 DT_RETURN_MARK_DECL(ThrowNew, jint);
 718 #else /* USDT2 */
 719 DT_RETURN_MARK_DECL(ThrowNew, jint
 720                     , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
 721 #endif /* USDT2 */
 722 
 723 JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))
 724   JNIWrapper("ThrowNew");
 725 #ifndef USDT2
 726   DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message);
 727 #else /* USDT2 */
 728   HOTSPOT_JNI_THROWNEW_ENTRY(
 729                              env, clazz, (char *) message);
 730 #endif /* USDT2 */
 731   jint ret = JNI_OK;
 732   DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);
 733 
 734   instanceKlass* k = instanceKlass::cast(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
 735   Symbol*  name = k->name();
 736   Handle class_loader (THREAD,  k->class_loader());
 737   Handle protection_domain (THREAD, k->protection_domain());
 738   THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);
 739   ShouldNotReachHere();
 740 JNI_END
 741 
 742 
 743 // JNI functions only transform a pending async exception to a synchronous
 744 // exception in ExceptionOccurred and ExceptionCheck calls, since
 745 // delivering an async exception in other places won't change the native
 746 // code's control flow and would be harmful when native code further calls
 747 // JNI functions with a pending exception. Async exception is also checked
 748 // during the call, so ExceptionOccurred/ExceptionCheck won't return
 749 // false but deliver the async exception at the very end during
 750 // state transition.
 751 
 752 static void jni_check_async_exceptions(JavaThread *thread) {
 753   assert(thread == Thread::current(), "must be itself");
 754   thread->check_and_handle_async_exceptions();
 755 }
 756 
 757 JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))
 758   JNIWrapper("ExceptionOccurred");
 759 #ifndef USDT2
 760   DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env);
 761 #else /* USDT2 */
 762   HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(
 763                                       env);
 764 #endif /* USDT2 */
 765   jni_check_async_exceptions(thread);
 766   oop exception = thread->pending_exception();
 767   jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);
 768 #ifndef USDT2
 769   DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret);
 770 #else /* USDT2 */
 771   HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(
 772                                        ret);
 773 #endif /* USDT2 */
 774   return ret;
 775 JNI_END
 776 
 777 
 778 JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))
 779   JNIWrapper("ExceptionDescribe");
 780 #ifndef USDT2
 781   DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env);
 782 #else /* USDT2 */
 783   HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(
 784                                       env);
 785 #endif /* USDT2 */
 786   if (thread->has_pending_exception()) {
 787     Handle ex(thread, thread->pending_exception());
 788     thread->clear_pending_exception();
 789     if (ex->is_a(SystemDictionary::ThreadDeath_klass())) {
 790       // Don't print anything if we are being killed.
 791     } else {
 792       jio_fprintf(defaultStream::error_stream(), "Exception ");
 793       if (thread != NULL && thread->threadObj() != NULL) {
 794         ResourceMark rm(THREAD);
 795         jio_fprintf(defaultStream::error_stream(),
 796         "in thread \"%s\" ", thread->get_thread_name());
 797       }
 798       if (ex->is_a(SystemDictionary::Throwable_klass())) {
 799         JavaValue result(T_VOID);
 800         JavaCalls::call_virtual(&result,
 801                                 ex,
 802                                 KlassHandle(THREAD,
 803                                   SystemDictionary::Throwable_klass()),
 804                                 vmSymbols::printStackTrace_name(),
 805                                 vmSymbols::void_method_signature(),
 806                                 THREAD);
 807         // If an exception is thrown in the call it gets thrown away. Not much
 808         // we can do with it. The native code that calls this, does not check
 809         // for the exception - hence, it might still be in the thread when DestroyVM gets
 810         // called, potentially causing a few asserts to trigger - since no pending exception
 811         // is expected.
 812         CLEAR_PENDING_EXCEPTION;
 813       } else {
 814         ResourceMark rm(THREAD);
 815         jio_fprintf(defaultStream::error_stream(),
 816         ". Uncaught exception of type %s.",
 817         Klass::cast(ex->klass())->external_name());
 818       }
 819     }
 820   }
 821 #ifndef USDT2
 822   DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return);
 823 #else /* USDT2 */
 824   HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN(
 825                                        );
 826 #endif /* USDT2 */
 827 JNI_END
 828 
 829 
 830 JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env))
 831   JNIWrapper("ExceptionClear");
 832 #ifndef USDT2
 833   DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env);
 834 #else /* USDT2 */
 835   HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(
 836                                    env);
 837 #endif /* USDT2 */
 838 
 839   // The jni code might be using this API to clear java thrown exception.
 840   // So just mark jvmti thread exception state as exception caught.
 841   JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();
 842   if (state != NULL && state->is_exception_detected()) {
 843     state->set_exception_caught();
 844   }
 845   thread->clear_pending_exception();
 846 #ifndef USDT2
 847   DTRACE_PROBE(hotspot_jni, ExceptionClear__return);
 848 #else /* USDT2 */
 849   HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN(
 850                                     );
 851 #endif /* USDT2 */
 852 JNI_END
 853 
 854 
 855 JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))
 856   JNIWrapper("FatalError");
 857 #ifndef USDT2
 858   DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);
 859 #else /* USDT2 */
 860   HOTSPOT_JNI_FATALERROR_ENTRY(
 861                                env, (char *) msg);
 862 #endif /* USDT2 */
 863   tty->print_cr("FATAL ERROR in native method: %s", msg);
 864   thread->print_stack();
 865   os::abort(); // Dump core and abort
 866 JNI_END
 867 
 868 
 869 JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))
 870   JNIWrapper("PushLocalFrame");
 871 #ifndef USDT2
 872   DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity);
 873 #else /* USDT2 */
 874   HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(
 875                                    env, capacity);
 876 #endif /* USDT2 */
 877   //%note jni_11
 878   if (capacity < 0 && capacity > MAX_REASONABLE_LOCAL_CAPACITY) {
 879 #ifndef USDT2
 880     DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);
 881 #else /* USDT2 */
 882     HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(
 883                                       (uint32_t)JNI_ERR);
 884 #endif /* USDT2 */
 885     return JNI_ERR;
 886   }
 887   JNIHandleBlock* old_handles = thread->active_handles();
 888   JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);
 889   assert(new_handles != NULL, "should not be NULL");
 890   new_handles->set_pop_frame_link(old_handles);
 891   thread->set_active_handles(new_handles);
 892   jint ret = JNI_OK;
 893 #ifndef USDT2
 894   DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret);
 895 #else /* USDT2 */
 896   HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(
 897                                     ret);
 898 #endif /* USDT2 */
 899   return ret;
 900 JNI_END
 901 
 902 
 903 JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))
 904   JNIWrapper("PopLocalFrame");
 905 #ifndef USDT2
 906   DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result);
 907 #else /* USDT2 */
 908   HOTSPOT_JNI_POPLOCALFRAME_ENTRY(
 909                                   env, result);
 910 #endif /* USDT2 */
 911   //%note jni_11
 912   Handle result_handle(thread, JNIHandles::resolve(result));
 913   JNIHandleBlock* old_handles = thread->active_handles();
 914   JNIHandleBlock* new_handles = old_handles->pop_frame_link();
 915   if (new_handles != NULL) {
 916     // As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.
 917     // This way code will still work if PopLocalFrame is called without a corresponding
 918     // PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise
 919     // the release_block call will release the blocks.
 920     thread->set_active_handles(new_handles);
 921     old_handles->set_pop_frame_link(NULL);              // clear link we won't release new_handles below
 922     JNIHandleBlock::release_block(old_handles, thread); // may block
 923     result = JNIHandles::make_local(thread, result_handle());
 924   }
 925 #ifndef USDT2
 926   DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result);
 927 #else /* USDT2 */
 928   HOTSPOT_JNI_POPLOCALFRAME_RETURN(
 929                                    result);
 930 #endif /* USDT2 */
 931   return result;
 932 JNI_END
 933 
 934 
 935 JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))
 936   JNIWrapper("NewGlobalRef");
 937 #ifndef USDT2
 938   DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref);
 939 #else /* USDT2 */
 940   HOTSPOT_JNI_NEWGLOBALREF_ENTRY(
 941                                  env, ref);
 942 #endif /* USDT2 */
 943   Handle ref_handle(thread, JNIHandles::resolve(ref));
 944   jobject ret = JNIHandles::make_global(ref_handle);
 945 #ifndef USDT2
 946   DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret);
 947 #else /* USDT2 */
 948   HOTSPOT_JNI_NEWGLOBALREF_RETURN(
 949                                   ret);
 950 #endif /* USDT2 */
 951   return ret;
 952 JNI_END
 953 
 954 // Must be JNI_ENTRY (with HandleMark)
 955 JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))
 956   JNIWrapper("DeleteGlobalRef");
 957 #ifndef USDT2
 958   DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref);
 959 #else /* USDT2 */
 960   HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(
 961                                     env, ref);
 962 #endif /* USDT2 */
 963   JNIHandles::destroy_global(ref);
 964 #ifndef USDT2
 965   DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return);
 966 #else /* USDT2 */
 967   HOTSPOT_JNI_DELETEGLOBALREF_RETURN(
 968                                      );
 969 #endif /* USDT2 */
 970 JNI_END
 971 
 972 JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))
 973   JNIWrapper("DeleteLocalRef");
 974 #ifndef USDT2
 975   DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj);
 976 #else /* USDT2 */
 977   HOTSPOT_JNI_DELETELOCALREF_ENTRY(
 978                                    env, obj);
 979 #endif /* USDT2 */
 980   JNIHandles::destroy_local(obj);
 981 #ifndef USDT2
 982   DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return);
 983 #else /* USDT2 */
 984   HOTSPOT_JNI_DELETELOCALREF_RETURN(
 985                                     );
 986 #endif /* USDT2 */
 987 JNI_END
 988 
 989 JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))
 990   JNIWrapper("IsSameObject");
 991 #ifndef USDT2
 992   DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2);
 993 #else /* USDT2 */
 994   HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(
 995                                  env, r1, r2);
 996 #endif /* USDT2 */
 997   oop a = JNIHandles::resolve(r1);
 998   oop b = JNIHandles::resolve(r2);
 999   jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;
1000 #ifndef USDT2
1001   DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret);
1002 #else /* USDT2 */
1003   HOTSPOT_JNI_ISSAMEOBJECT_RETURN(
1004                                   ret);
1005 #endif /* USDT2 */
1006   return ret;
1007 JNI_END
1008 
1009 
1010 JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))
1011   JNIWrapper("NewLocalRef");
1012 #ifndef USDT2
1013   DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref);
1014 #else /* USDT2 */
1015   HOTSPOT_JNI_NEWLOCALREF_ENTRY(
1016                                 env, ref);
1017 #endif /* USDT2 */
1018   jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));
1019 #ifndef USDT2
1020   DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret);
1021 #else /* USDT2 */
1022   HOTSPOT_JNI_NEWLOCALREF_RETURN(
1023                                  ret);
1024 #endif /* USDT2 */
1025   return ret;
1026 JNI_END
1027 
1028 JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))
1029   JNIWrapper("EnsureLocalCapacity");
1030 #ifndef USDT2
1031   DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity);
1032 #else /* USDT2 */
1033   HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(
1034                                         env, capacity);
1035 #endif /* USDT2 */
1036   jint ret;
1037   if (capacity >= 0 && capacity <= MAX_REASONABLE_LOCAL_CAPACITY) {
1038     ret = JNI_OK;
1039   } else {
1040     ret = JNI_ERR;
1041   }
1042 #ifndef USDT2
1043   DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret);
1044 #else /* USDT2 */
1045   HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(
1046                                          ret);
1047 #endif /* USDT2 */
1048   return ret;
1049 JNI_END
1050 
1051 // Return the Handle Type
1052 JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))
1053   JNIWrapper("GetObjectRefType");
1054 #ifndef USDT2
1055   DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj);
1056 #else /* USDT2 */
1057   HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(
1058                                      env, obj);
1059 #endif /* USDT2 */
1060   jobjectRefType ret;
1061   if (JNIHandles::is_local_handle(thread, obj) ||
1062       JNIHandles::is_frame_handle(thread, obj))
1063     ret = JNILocalRefType;
1064   else if (JNIHandles::is_global_handle(obj))
1065     ret = JNIGlobalRefType;
1066   else if (JNIHandles::is_weak_global_handle(obj))
1067     ret = JNIWeakGlobalRefType;
1068   else
1069     ret = JNIInvalidRefType;
1070 #ifndef USDT2
1071   DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret);
1072 #else /* USDT2 */
1073   HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN(
1074                                       (void *) ret);
1075 #endif /* USDT2 */
1076   return ret;
1077 JNI_END
1078 
1079 
1080 class JNI_ArgumentPusher : public SignatureIterator {
1081  protected:
1082   JavaCallArguments*  _arguments;
1083 
1084   virtual void get_bool   () = 0;
1085   virtual void get_char   () = 0;
1086   virtual void get_short  () = 0;
1087   virtual void get_byte   () = 0;
1088   virtual void get_int    () = 0;
1089   virtual void get_long   () = 0;
1090   virtual void get_float  () = 0;
1091   virtual void get_double () = 0;
1092   virtual void get_object () = 0;
1093 
1094   JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {
1095     this->_return_type = T_ILLEGAL;
1096     _arguments = NULL;
1097   }
1098 
1099  public:
1100   virtual void iterate( uint64_t fingerprint ) = 0;
1101 
1102   void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }
1103 
1104   inline void do_bool()                     { if (!is_return_type()) get_bool();   }
1105   inline void do_char()                     { if (!is_return_type()) get_char();   }
1106   inline void do_short()                    { if (!is_return_type()) get_short();  }
1107   inline void do_byte()                     { if (!is_return_type()) get_byte();   }
1108   inline void do_int()                      { if (!is_return_type()) get_int();    }
1109   inline void do_long()                     { if (!is_return_type()) get_long();   }
1110   inline void do_float()                    { if (!is_return_type()) get_float();  }
1111   inline void do_double()                   { if (!is_return_type()) get_double(); }
1112   inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }
1113   inline void do_array(int begin, int end)  { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array
1114   inline void do_void()                     { }
1115 
1116   JavaCallArguments* arguments()     { return _arguments; }
1117   void push_receiver(Handle h)       { _arguments->push_oop(h); }
1118 };
1119 
1120 
1121 class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {
1122  protected:
1123   va_list _ap;
1124 
1125   inline void get_bool()   { _arguments->push_int(va_arg(_ap, jint)); } // bool is coerced to int when using va_arg
1126   inline void get_char()   { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg
1127   inline void get_short()  { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg
1128   inline void get_byte()   { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg
1129   inline void get_int()    { _arguments->push_int(va_arg(_ap, jint)); }
1130 
1131   // each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests
1132 
1133   inline void get_long()   { _arguments->push_long(va_arg(_ap, jlong)); }
1134   inline void get_float()  { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg
1135   inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }
1136   inline void get_object() { jobject l = va_arg(_ap, jobject);
1137                              _arguments->push_oop(Handle((oop *)l, false)); }
1138 
1139   inline void set_ap(va_list rap) {
1140 #ifdef va_copy
1141     va_copy(_ap, rap);
1142 #elif defined (__va_copy)
1143     __va_copy(_ap, rap);
1144 #else
1145     _ap = rap;
1146 #endif
1147   }
1148 
1149  public:
1150   JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap)
1151        : JNI_ArgumentPusher(signature) {
1152     set_ap(rap);
1153   }
1154   JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)
1155       : JNI_ArgumentPusher(JNIHandles::resolve_jmethod_id(method_id)->signature()) {
1156     set_ap(rap);
1157   }
1158 
1159   // Optimized path if we have the bitvector form of signature
1160   void iterate( uint64_t fingerprint ) {
1161     if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments
1162     else {
1163       _return_type = (BasicType)((fingerprint >> static_feature_size) &
1164                                   result_feature_mask);
1165 
1166       assert(fingerprint, "Fingerprint should not be 0");
1167       fingerprint = fingerprint >> (static_feature_size + result_feature_size);
1168       while ( 1 ) {
1169         switch ( fingerprint & parameter_feature_mask ) {
1170           case bool_parm:
1171           case char_parm:
1172           case short_parm:
1173           case byte_parm:
1174           case int_parm:
1175             get_int();
1176             break;
1177           case obj_parm:
1178             get_object();
1179             break;
1180           case long_parm:
1181             get_long();
1182             break;
1183           case float_parm:
1184             get_float();
1185             break;
1186           case double_parm:
1187             get_double();
1188             break;
1189           case done_parm:
1190             return;
1191             break;
1192           default:
1193             ShouldNotReachHere();
1194             break;
1195         }
1196         fingerprint >>= parameter_feature_size;
1197       }
1198     }
1199   }
1200 };
1201 
1202 
1203 class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {
1204  protected:
1205   const jvalue *_ap;
1206 
1207   inline void get_bool()   { _arguments->push_int((jint)(_ap++)->z); }
1208   inline void get_char()   { _arguments->push_int((jint)(_ap++)->c); }
1209   inline void get_short()  { _arguments->push_int((jint)(_ap++)->s); }
1210   inline void get_byte()   { _arguments->push_int((jint)(_ap++)->b); }
1211   inline void get_int()    { _arguments->push_int((jint)(_ap++)->i); }
1212 
1213   inline void get_long()   { _arguments->push_long((_ap++)->j);  }
1214   inline void get_float()  { _arguments->push_float((_ap++)->f); }
1215   inline void get_double() { _arguments->push_double((_ap++)->d);}
1216   inline void get_object() { _arguments->push_oop(Handle((oop *)(_ap++)->l, false)); }
1217 
1218   inline void set_ap(const jvalue *rap) { _ap = rap; }
1219 
1220  public:
1221   JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap)
1222        : JNI_ArgumentPusher(signature) {
1223     set_ap(rap);
1224   }
1225   JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)
1226       : JNI_ArgumentPusher(JNIHandles::resolve_jmethod_id(method_id)->signature()) {
1227     set_ap(rap);
1228   }
1229 
1230   // Optimized path if we have the bitvector form of signature
1231   void iterate( uint64_t fingerprint ) {
1232     if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments
1233     else {
1234       _return_type = (BasicType)((fingerprint >> static_feature_size) &
1235                                   result_feature_mask);
1236       assert(fingerprint, "Fingerprint should not be 0");
1237       fingerprint = fingerprint >> (static_feature_size + result_feature_size);
1238       while ( 1 ) {
1239         switch ( fingerprint & parameter_feature_mask ) {
1240           case bool_parm:
1241             get_bool();
1242             break;
1243           case char_parm:
1244             get_char();
1245             break;
1246           case short_parm:
1247             get_short();
1248             break;
1249           case byte_parm:
1250             get_byte();
1251             break;
1252           case int_parm:
1253             get_int();
1254             break;
1255           case obj_parm:
1256             get_object();
1257             break;
1258           case long_parm:
1259             get_long();
1260             break;
1261           case float_parm:
1262             get_float();
1263             break;
1264           case double_parm:
1265             get_double();
1266             break;
1267           case done_parm:
1268             return;
1269             break;
1270           default:
1271             ShouldNotReachHere();
1272             break;
1273         }
1274         fingerprint >>= parameter_feature_size;
1275       }
1276     }
1277   }
1278 };
1279 
1280 
1281 enum JNICallType {
1282   JNI_STATIC,
1283   JNI_VIRTUAL,
1284   JNI_NONVIRTUAL
1285 };
1286 
1287 static methodHandle jni_resolve_interface_call(Handle recv, methodHandle method, TRAPS) {
1288   assert(!method.is_null() , "method should not be null");
1289 
1290   KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc)
1291   if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass());
1292   KlassHandle spec_klass (THREAD, method->method_holder());
1293   Symbol*  name  = method->name();
1294   Symbol*  signature  = method->signature();
1295   CallInfo info;
1296   LinkResolver::resolve_interface_call(info, recv, recv_klass,  spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle()));
1297   return info.selected_method();
1298 }
1299 
1300 static methodHandle jni_resolve_virtual_call(Handle recv, methodHandle method, TRAPS) {
1301   assert(!method.is_null() , "method should not be null");
1302 
1303   KlassHandle recv_klass; // Default to NULL (use of ?: can confuse gcc)
1304   if (recv.not_null()) recv_klass = KlassHandle(THREAD, recv->klass());
1305   KlassHandle spec_klass (THREAD, method->method_holder());
1306   Symbol*  name  = method->name();
1307   Symbol*  signature  = method->signature();
1308   CallInfo info;
1309   LinkResolver::resolve_virtual_call(info, recv, recv_klass,  spec_klass, name, signature, KlassHandle(), false, true, CHECK_(methodHandle()));
1310   return info.selected_method();
1311 }
1312 
1313 
1314 
1315 static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1316   methodHandle method(THREAD, JNIHandles::resolve_jmethod_id(method_id));
1317 
1318   // Create object to hold arguments for the JavaCall, and associate it with
1319   // the jni parser
1320   ResourceMark rm(THREAD);
1321   int number_of_parameters = method->size_of_parameters();
1322   JavaCallArguments java_args(number_of_parameters);
1323   args->set_java_argument_object(&java_args);
1324 
1325   assert(method->is_static(), "method should be static");
1326 
1327   // Fill out JavaCallArguments object
1328   args->iterate( Fingerprinter(method).fingerprint() );
1329   // Initialize result type
1330   result->set_type(args->get_ret_type());
1331 
1332   // Invoke the method. Result is returned as oop.
1333   JavaCalls::call(result, method, &java_args, CHECK);
1334 
1335   // Convert result
1336   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
1337     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1338   }
1339 }
1340 
1341 
1342 static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {
1343   oop recv = JNIHandles::resolve(receiver);
1344   if (recv == NULL) {
1345     THROW(vmSymbols::java_lang_NullPointerException());
1346   }
1347   Handle h_recv(THREAD, recv);
1348 
1349   int number_of_parameters;
1350   methodOop selected_method;
1351   {
1352     methodOop m = JNIHandles::resolve_jmethod_id(method_id);
1353     number_of_parameters = m->size_of_parameters();
1354     klassOop holder = m->method_holder();
1355     if (!(Klass::cast(holder))->is_interface()) {
1356       // non-interface call -- for that little speed boost, don't handlize
1357       debug_only(No_Safepoint_Verifier nosafepoint;)
1358       if (call_type == JNI_VIRTUAL) {
1359         // jni_GetMethodID makes sure class is linked and initialized
1360         // so m should have a valid vtable index.
1361         int vtbl_index = m->vtable_index();
1362         if (vtbl_index != methodOopDesc::nonvirtual_vtable_index) {
1363           klassOop k = h_recv->klass();
1364           // k might be an arrayKlassOop but all vtables start at
1365           // the same place. The cast is to avoid virtual call and assertion.
1366           instanceKlass *ik = (instanceKlass*)k->klass_part();
1367           selected_method = ik->method_at_vtable(vtbl_index);
1368         } else {
1369           // final method
1370           selected_method = m;
1371         }
1372       } else {
1373         // JNI_NONVIRTUAL call
1374         selected_method = m;
1375       }
1376     } else {
1377       // interface call
1378       KlassHandle h_holder(THREAD, holder);
1379 
1380       int itbl_index = m->cached_itable_index();
1381       if (itbl_index == -1) {
1382         itbl_index = klassItable::compute_itable_index(m);
1383         m->set_cached_itable_index(itbl_index);
1384         // the above may have grabbed a lock, 'm' and anything non-handlized can't be used again
1385       }
1386       klassOop k = h_recv->klass();
1387       selected_method = instanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);
1388     }
1389   }
1390 
1391   methodHandle method(THREAD, selected_method);
1392 
1393   // Create object to hold arguments for the JavaCall, and associate it with
1394   // the jni parser
1395   ResourceMark rm(THREAD);
1396   JavaCallArguments java_args(number_of_parameters);
1397   args->set_java_argument_object(&java_args);
1398 
1399   // handle arguments
1400   assert(!method->is_static(), "method should not be static");
1401   args->push_receiver(h_recv); // Push jobject handle
1402 
1403   // Fill out JavaCallArguments object
1404   args->iterate( Fingerprinter(method).fingerprint() );
1405   // Initialize result type
1406   result->set_type(args->get_ret_type());
1407 
1408   // Invoke the method. Result is returned as oop.
1409   JavaCalls::call(result, method, &java_args, CHECK);
1410 
1411   // Convert result
1412   if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {
1413     result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));
1414   }
1415 }
1416 
1417 
1418 static instanceOop alloc_object(jclass clazz, TRAPS) {
1419   KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
1420   Klass::cast(k())->check_valid_for_instantiation(false, CHECK_NULL);
1421   instanceKlass::cast(k())->initialize(CHECK_NULL);
1422   instanceOop ih = instanceKlass::cast(k())->allocate_instance(THREAD);
1423   return ih;
1424 }
1425 
1426 #ifndef USDT2
1427 DT_RETURN_MARK_DECL(AllocObject, jobject);
1428 #else /* USDT2 */
1429 DT_RETURN_MARK_DECL(AllocObject, jobject
1430                     , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1431 #endif /* USDT2 */
1432 
1433 JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))
1434   JNIWrapper("AllocObject");
1435 
1436 #ifndef USDT2
1437   DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz);
1438 #else /* USDT2 */
1439   HOTSPOT_JNI_ALLOCOBJECT_ENTRY(
1440                                 env, clazz);
1441 #endif /* USDT2 */
1442   jobject ret = NULL;
1443   DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);
1444 
1445   instanceOop i = alloc_object(clazz, CHECK_NULL);
1446   ret = JNIHandles::make_local(env, i);
1447   return ret;
1448 JNI_END
1449 
1450 #ifndef USDT2
1451 DT_RETURN_MARK_DECL(NewObjectA, jobject);
1452 #else /* USDT2 */
1453 DT_RETURN_MARK_DECL(NewObjectA, jobject
1454                     , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
1455 #endif /* USDT2 */
1456 
1457 JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))
1458   JNIWrapper("NewObjectA");
1459 #ifndef USDT2
1460   DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID);
1461 #else /* USDT2 */
1462   HOTSPOT_JNI_NEWOBJECTA_ENTRY(
1463                                env, clazz, (uintptr_t) methodID);
1464 #endif /* USDT2 */
1465   jobject obj = NULL;
1466   DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);
1467 
1468   instanceOop i = alloc_object(clazz, CHECK_NULL);
1469   obj = JNIHandles::make_local(env, i);
1470   JavaValue jvalue(T_VOID);
1471   JNI_ArgumentPusherArray ap(methodID, args);
1472   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1473   return obj;
1474 JNI_END
1475 
1476 #ifndef USDT2
1477 DT_RETURN_MARK_DECL(NewObjectV, jobject);
1478 #else /* USDT2 */
1479 DT_RETURN_MARK_DECL(NewObjectV, jobject
1480                     , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1481 #endif /* USDT2 */
1482 
1483 JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))
1484   JNIWrapper("NewObjectV");
1485 #ifndef USDT2
1486   DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID);
1487 #else /* USDT2 */
1488   HOTSPOT_JNI_NEWOBJECTV_ENTRY(
1489                                env, clazz, (uintptr_t) methodID);
1490 #endif /* USDT2 */
1491   jobject obj = NULL;
1492   DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);
1493 
1494   instanceOop i = alloc_object(clazz, CHECK_NULL);
1495   obj = JNIHandles::make_local(env, i);
1496   JavaValue jvalue(T_VOID);
1497   JNI_ArgumentPusherVaArg ap(methodID, args);
1498   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1499   return obj;
1500 JNI_END
1501 
1502 #ifndef USDT2
1503 DT_RETURN_MARK_DECL(NewObject, jobject);
1504 #else /* USDT2 */
1505 DT_RETURN_MARK_DECL(NewObject, jobject
1506                     , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1507 #endif /* USDT2 */
1508 
1509 JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))
1510   JNIWrapper("NewObject");
1511 #ifndef USDT2
1512   DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID);
1513 #else /* USDT2 */
1514   HOTSPOT_JNI_NEWOBJECT_ENTRY(
1515                               env, clazz, (uintptr_t) methodID);
1516 #endif /* USDT2 */
1517   jobject obj = NULL;
1518   DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);
1519 
1520   instanceOop i = alloc_object(clazz, CHECK_NULL);
1521   obj = JNIHandles::make_local(env, i);
1522   va_list args;
1523   va_start(args, methodID);
1524   JavaValue jvalue(T_VOID);
1525   JNI_ArgumentPusherVaArg ap(methodID, args);
1526   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);
1527   va_end(args);
1528   return obj;
1529 JNI_END
1530 
1531 
1532 JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))
1533   JNIWrapper("GetObjectClass");
1534 #ifndef USDT2
1535   DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj);
1536 #else /* USDT2 */
1537   HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(
1538                                    env, obj);
1539 #endif /* USDT2 */
1540   klassOop k = JNIHandles::resolve_non_null(obj)->klass();
1541   jclass ret =
1542     (jclass) JNIHandles::make_local(env, Klass::cast(k)->java_mirror());
1543 #ifndef USDT2
1544   DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);
1545 #else /* USDT2 */
1546   HOTSPOT_JNI_GETOBJECTCLASS_RETURN(
1547                                     ret);
1548 #endif /* USDT2 */
1549   return ret;
1550 JNI_END
1551 
1552 JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))
1553   JNIWrapper("IsInstanceOf");
1554 #ifndef USDT2
1555   DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz);
1556 #else /* USDT2 */
1557   HOTSPOT_JNI_ISINSTANCEOF_ENTRY(
1558                                  env, obj, clazz);
1559 #endif /* USDT2 */
1560   jboolean ret = JNI_TRUE;
1561   if (obj != NULL) {
1562     ret = JNI_FALSE;
1563     klassOop k = java_lang_Class::as_klassOop(
1564       JNIHandles::resolve_non_null(clazz));
1565     if (k != NULL) {
1566       ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;
1567     }
1568   }
1569 #ifndef USDT2
1570   DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret);
1571 #else /* USDT2 */
1572   HOTSPOT_JNI_ISINSTANCEOF_RETURN(
1573                                   ret);
1574 #endif /* USDT2 */
1575   return ret;
1576 JNI_END
1577 
1578 
1579 static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
1580                                const char *sig, bool is_static, TRAPS) {
1581   // %%%% This code should probably just call into a method in the LinkResolver
1582   //
1583   // The class should have been loaded (we have an instance of the class
1584   // passed in) so the method and signature should already be in the symbol
1585   // table.  If they're not there, the method doesn't exist.
1586   const char *name_to_probe = (name_str == NULL)
1587                         ? vmSymbols::object_initializer_name()->as_C_string()
1588                         : name_str;
1589   TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe));
1590   TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig));
1591 
1592   if (name == NULL || signature == NULL) {
1593     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1594   }
1595 
1596   // Throw a NoSuchMethodError exception if we have an instance of a
1597   // primitive java.lang.Class
1598   if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
1599     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1600   }
1601 
1602   KlassHandle klass(THREAD,
1603                java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
1604 
1605   // Make sure class is linked and initialized before handing id's out to
1606   // methodOops.
1607   Klass::cast(klass())->initialize(CHECK_NULL);
1608 
1609   methodOop m;
1610   if (name == vmSymbols::object_initializer_name() ||
1611       name == vmSymbols::class_initializer_name()) {
1612     // Never search superclasses for constructors
1613     if (klass->oop_is_instance()) {
1614       m = instanceKlass::cast(klass())->find_method(name, signature);
1615     } else {
1616       m = NULL;
1617     }
1618   } else {
1619     m = klass->lookup_method(name, signature);
1620     // Look up interfaces
1621     if (m == NULL && klass->oop_is_instance()) {
1622       m = instanceKlass::cast(klass())->lookup_method_in_all_interfaces(name,
1623                                                                    signature);
1624     }
1625   }
1626   if (m == NULL || (m->is_static() != is_static)) {
1627     THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
1628   }
1629   return m->jmethod_id();
1630 }
1631 
1632 
1633 JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,
1634           const char *name, const char *sig))
1635   JNIWrapper("GetMethodID");
1636 #ifndef USDT2
1637   DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig);
1638 #else /* USDT2 */
1639   HOTSPOT_JNI_GETMETHODID_ENTRY(
1640                                 env, clazz, (char *) name, (char *) sig);
1641 #endif /* USDT2 */
1642   jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);
1643 #ifndef USDT2
1644   DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret);
1645 #else /* USDT2 */
1646   HOTSPOT_JNI_GETMETHODID_RETURN(
1647                                  (uintptr_t) ret);
1648 #endif /* USDT2 */
1649   return ret;
1650 JNI_END
1651 
1652 
1653 JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,
1654           const char *name, const char *sig))
1655   JNIWrapper("GetStaticMethodID");
1656 #ifndef USDT2
1657   DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig);
1658 #else /* USDT2 */
1659   HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(
1660                                       env, (char *) clazz, (char *) name, (char *)sig);
1661 #endif /* USDT2 */
1662   jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);
1663 #ifndef USDT2
1664   DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret);
1665 #else /* USDT2 */
1666   HOTSPOT_JNI_GETSTATICMETHODID_RETURN(
1667                                        (uintptr_t) ret);
1668 #endif /* USDT2 */
1669   return ret;
1670 JNI_END
1671 
1672 
1673 
1674 //
1675 // Calling Methods
1676 //
1677 
1678 #ifndef USDT2
1679 #define DEFINE_CALLMETHOD(ResultType, Result, Tag) \
1680 \
1681   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\
1682   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType);\
1683   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType);\
1684 \
1685 JNI_ENTRY(ResultType, \
1686           jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
1687   JNIWrapper("Call" XSTR(Result) "Method"); \
1688 \
1689   DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID); \
1690   ResultType ret = 0;\
1691   DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
1692                      (const ResultType&)ret);\
1693 \
1694   va_list args; \
1695   va_start(args, methodID); \
1696   JavaValue jvalue(Tag); \
1697   JNI_ArgumentPusherVaArg ap(methodID, args); \
1698   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1699   va_end(args); \
1700   ret = jvalue.get_##ResultType(); \
1701   return ret;\
1702 JNI_END \
1703 \
1704 \
1705 JNI_ENTRY(ResultType, \
1706           jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
1707   JNIWrapper("Call" XSTR(Result) "MethodV"); \
1708 \
1709   DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID); \
1710   ResultType ret = 0;\
1711   DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
1712                      (const ResultType&)ret);\
1713 \
1714   JavaValue jvalue(Tag); \
1715   JNI_ArgumentPusherVaArg ap(methodID, args); \
1716   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1717   ret = jvalue.get_##ResultType(); \
1718   return ret;\
1719 JNI_END \
1720 \
1721 \
1722 JNI_ENTRY(ResultType, \
1723           jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
1724   JNIWrapper("Call" XSTR(Result) "MethodA"); \
1725   DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID); \
1726   ResultType ret = 0;\
1727   DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
1728                      (const ResultType&)ret);\
1729 \
1730   JavaValue jvalue(Tag); \
1731   JNI_ArgumentPusherArray ap(methodID, args); \
1732   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1733   ret = jvalue.get_##ResultType(); \
1734   return ret;\
1735 JNI_END
1736 
1737 // the runtime type of subword integral basic types is integer
1738 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN)
1739 DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE)
1740 DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR)
1741 DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT)
1742 
1743 DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT)
1744 DEFINE_CALLMETHOD(jint,     Int,     T_INT)
1745 DEFINE_CALLMETHOD(jlong,    Long,    T_LONG)
1746 DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT)
1747 DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE)
1748 
1749 DT_VOID_RETURN_MARK_DECL(CallVoidMethod);
1750 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV);
1751 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA);
1752 
1753 #else /* USDT2 */
1754 
1755 #define DEFINE_CALLMETHOD(ResultType, Result, Tag \
1756                           , EntryProbe, ReturnProbe)    \
1757 \
1758   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \
1759                           , ReturnProbe);                          \
1760 \
1761 JNI_ENTRY(ResultType, \
1762           jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \
1763   JNIWrapper("Call" XSTR(Result) "Method"); \
1764 \
1765   EntryProbe; \
1766   ResultType ret = 0;\
1767   DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \
1768                      (const ResultType&)ret);\
1769 \
1770   va_list args; \
1771   va_start(args, methodID); \
1772   JavaValue jvalue(Tag); \
1773   JNI_ArgumentPusherVaArg ap(methodID, args); \
1774   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1775   va_end(args); \
1776   ret = jvalue.get_##ResultType(); \
1777   return ret;\
1778 JNI_END
1779 
1780 // the runtime type of subword integral basic types is integer
1781 DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN
1782                   , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1783                   HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1784 DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE
1785                   , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1786                   HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1787 DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR
1788                   , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1789                   HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1790 DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT
1791                   , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1792                   HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1793 
1794 DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT
1795                   , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1796                   HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1797 DEFINE_CALLMETHOD(jint,     Int,     T_INT,
1798                   HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1799                   HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1800 DEFINE_CALLMETHOD(jlong,    Long,    T_LONG
1801                   , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1802                   HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
1803 // Float and double probes don't return value because dtrace doesn't currently support it
1804 DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT
1805                   , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1806                   HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1807 DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE
1808                   , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1809                   HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
1810 
1811 #define DEFINE_CALLMETHODV(ResultType, Result, Tag \
1812                           , EntryProbe, ReturnProbe)    \
1813 \
1814   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \
1815                           , ReturnProbe);                          \
1816 \
1817 JNI_ENTRY(ResultType, \
1818           jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \
1819   JNIWrapper("Call" XSTR(Result) "MethodV"); \
1820 \
1821   EntryProbe;\
1822   ResultType ret = 0;\
1823   DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \
1824                      (const ResultType&)ret);\
1825 \
1826   JavaValue jvalue(Tag); \
1827   JNI_ArgumentPusherVaArg ap(methodID, args); \
1828   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1829   ret = jvalue.get_##ResultType(); \
1830   return ret;\
1831 JNI_END
1832 
1833 // the runtime type of subword integral basic types is integer
1834 DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
1835                   , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1836                   HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1837 DEFINE_CALLMETHODV(jbyte,    Byte,    T_BYTE
1838                   , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1839                   HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1840 DEFINE_CALLMETHODV(jchar,    Char,    T_CHAR
1841                   , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1842                   HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1843 DEFINE_CALLMETHODV(jshort,   Short,   T_SHORT
1844                   , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1845                   HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1846 
1847 DEFINE_CALLMETHODV(jobject,  Object,  T_OBJECT
1848                   , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1849                   HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1850 DEFINE_CALLMETHODV(jint,     Int,     T_INT,
1851                   HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1852                   HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1853 DEFINE_CALLMETHODV(jlong,    Long,    T_LONG
1854                   , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1855                   HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
1856 // Float and double probes don't return value because dtrace doesn't currently support it
1857 DEFINE_CALLMETHODV(jfloat,   Float,   T_FLOAT
1858                   , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1859                   HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1860 DEFINE_CALLMETHODV(jdouble,  Double,  T_DOUBLE
1861                   , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1862                   HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
1863 
1864 #define DEFINE_CALLMETHODA(ResultType, Result, Tag \
1865                           , EntryProbe, ReturnProbe)    \
1866 \
1867   DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \
1868                           , ReturnProbe);                          \
1869 \
1870 JNI_ENTRY(ResultType, \
1871           jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \
1872   JNIWrapper("Call" XSTR(Result) "MethodA"); \
1873   EntryProbe; \
1874   ResultType ret = 0;\
1875   DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \
1876                      (const ResultType&)ret);\
1877 \
1878   JavaValue jvalue(Tag); \
1879   JNI_ArgumentPusherArray ap(methodID, args); \
1880   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \
1881   ret = jvalue.get_##ResultType(); \
1882   return ret;\
1883 JNI_END
1884 
1885 // the runtime type of subword integral basic types is integer
1886 DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
1887                   , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1888                   HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1889 DEFINE_CALLMETHODA(jbyte,    Byte,    T_BYTE
1890                   , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1891                   HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1892 DEFINE_CALLMETHODA(jchar,    Char,    T_CHAR
1893                   , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1894                   HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1895 DEFINE_CALLMETHODA(jshort,   Short,   T_SHORT
1896                   , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1897                   HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1898 
1899 DEFINE_CALLMETHODA(jobject,  Object,  T_OBJECT
1900                   , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1901                   HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1902 DEFINE_CALLMETHODA(jint,     Int,     T_INT,
1903                   HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1904                   HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1905 DEFINE_CALLMETHODA(jlong,    Long,    T_LONG
1906                   , HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1907                   HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))
1908 // Float and double probes don't return value because dtrace doesn't currently support it
1909 DEFINE_CALLMETHODA(jfloat,   Float,   T_FLOAT
1910                   , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1911                   HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1912 DEFINE_CALLMETHODA(jdouble,  Double,  T_DOUBLE
1913                   , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1914                   HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
1915 
1916 DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
1917 DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
1918 DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
1919 
1920 #endif /* USDT2 */
1921 
1922 JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))
1923   JNIWrapper("CallVoidMethod");
1924 #ifndef USDT2
1925   DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID);
1926 #else /* USDT2 */
1927   HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(
1928                                    env, obj, (uintptr_t) methodID);
1929 #endif /* USDT2 */
1930   DT_VOID_RETURN_MARK(CallVoidMethod);
1931 
1932   va_list args;
1933   va_start(args, methodID);
1934   JavaValue jvalue(T_VOID);
1935   JNI_ArgumentPusherVaArg ap(methodID, args);
1936   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1937   va_end(args);
1938 JNI_END
1939 
1940 
1941 JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))
1942   JNIWrapper("CallVoidMethodV");
1943 #ifndef USDT2
1944   DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID);
1945 #else /* USDT2 */
1946   HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(
1947                                     env, obj, (uintptr_t) methodID);
1948 #endif /* USDT2 */
1949   DT_VOID_RETURN_MARK(CallVoidMethodV);
1950 
1951   JavaValue jvalue(T_VOID);
1952   JNI_ArgumentPusherVaArg ap(methodID, args);
1953   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1954 JNI_END
1955 
1956 
1957 JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))
1958   JNIWrapper("CallVoidMethodA");
1959 #ifndef USDT2
1960   DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID);
1961 #else /* USDT2 */
1962   HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(
1963                                     env, obj, (uintptr_t) methodID);
1964 #endif /* USDT2 */
1965   DT_VOID_RETURN_MARK(CallVoidMethodA);
1966 
1967   JavaValue jvalue(T_VOID);
1968   JNI_ArgumentPusherArray ap(methodID, args);
1969   jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);
1970 JNI_END
1971 
1972 
1973 #ifndef USDT2
1974 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \
1975 \
1976   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\
1977   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType);\
1978   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType);\
1979 \
1980 JNI_ENTRY(ResultType, \
1981           jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
1982   JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
1983 \
1984   DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##Method__entry, env, obj, cls, methodID);\
1985   ResultType ret;\
1986   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
1987                      (const ResultType&)ret);\
1988 \
1989   va_list args; \
1990   va_start(args, methodID); \
1991   JavaValue jvalue(Tag); \
1992   JNI_ArgumentPusherVaArg ap(methodID, args); \
1993   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
1994   va_end(args); \
1995   ret = jvalue.get_##ResultType(); \
1996   return ret;\
1997 JNI_END \
1998 \
1999 JNI_ENTRY(ResultType, \
2000           jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
2001   JNIWrapper("CallNonvitual" XSTR(Result) "#MethodV"); \
2002   DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodV__entry, env, obj, cls, methodID);\
2003   ResultType ret;\
2004   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
2005                      (const ResultType&)ret);\
2006 \
2007   JavaValue jvalue(Tag); \
2008   JNI_ArgumentPusherVaArg ap(methodID, args); \
2009   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
2010   ret = jvalue.get_##ResultType(); \
2011   return ret;\
2012 JNI_END \
2013 \
2014 JNI_ENTRY(ResultType, \
2015           jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
2016   JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
2017   DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodA__entry, env, obj, cls, methodID);\
2018   ResultType ret;\
2019   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
2020                      (const ResultType&)ret);\
2021 \
2022   JavaValue jvalue(Tag); \
2023   JNI_ArgumentPusherArray ap(methodID, args); \
2024   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
2025   ret = jvalue.get_##ResultType(); \
2026   return ret;\
2027 JNI_END
2028 
2029 // the runtime type of subword integral basic types is integer
2030 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN)
2031 DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE)
2032 DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR)
2033 DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT)
2034 
2035 DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT)
2036 DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT)
2037 DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG)
2038 DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT)
2039 DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE)
2040 
2041 
2042 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod);
2043 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV);
2044 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA);
2045 
2046 #else /* USDT2 */
2047 
2048 #define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \
2049                                     , EntryProbe, ReturnProbe)      \
2050 \
2051   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \
2052                           , ReturnProbe);\
2053 \
2054 JNI_ENTRY(ResultType, \
2055           jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \
2056   JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \
2057 \
2058   EntryProbe;\
2059   ResultType ret;\
2060   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \
2061                      (const ResultType&)ret);\
2062 \
2063   va_list args; \
2064   va_start(args, methodID); \
2065   JavaValue jvalue(Tag); \
2066   JNI_ArgumentPusherVaArg ap(methodID, args); \
2067   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
2068   va_end(args); \
2069   ret = jvalue.get_##ResultType(); \
2070   return ret;\
2071 JNI_END
2072 
2073 // the runtime type of subword integral basic types is integer
2074 DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN
2075                             , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2076                             HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))
2077 DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE
2078                             , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2079                             HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))
2080 DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR
2081                             , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2082                             HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))
2083 DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT
2084                             , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2085                             HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))
2086 
2087 DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT
2088                             , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2089                             HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))
2090 DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT
2091                             , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2092                             HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))
2093 DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG
2094                             , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2095 // Float and double probes don't return value because dtrace doesn't currently support it
2096                             HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref))
2097 DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT
2098                             , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2099                             HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())
2100 DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE
2101                             , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2102                             HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN())
2103 
2104 #define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \
2105                                     , EntryProbe, ReturnProbe)      \
2106 \
2107   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \
2108                           , ReturnProbe);\
2109 \
2110 JNI_ENTRY(ResultType, \
2111           jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \
2112   JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \
2113 \
2114   EntryProbe;\
2115   ResultType ret;\
2116   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \
2117                      (const ResultType&)ret);\
2118 \
2119   JavaValue jvalue(Tag); \
2120   JNI_ArgumentPusherVaArg ap(methodID, args); \
2121   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
2122   ret = jvalue.get_##ResultType(); \
2123   return ret;\
2124 JNI_END
2125 
2126 // the runtime type of subword integral basic types is integer
2127 DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN
2128                             , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2129                             HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))
2130 DEFINE_CALLNONVIRTUALMETHODV(jbyte,    Byte,    T_BYTE
2131                             , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2132                             HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))
2133 DEFINE_CALLNONVIRTUALMETHODV(jchar,    Char,    T_CHAR
2134                             , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2135                             HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))
2136 DEFINE_CALLNONVIRTUALMETHODV(jshort,   Short,   T_SHORT
2137                             , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2138                             HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))
2139 
2140 DEFINE_CALLNONVIRTUALMETHODV(jobject,  Object,  T_OBJECT
2141                             , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2142                             HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))
2143 DEFINE_CALLNONVIRTUALMETHODV(jint,     Int,     T_INT
2144                             , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2145                             HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))
2146 DEFINE_CALLNONVIRTUALMETHODV(jlong,    Long,    T_LONG
2147                             , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2148 // Float and double probes don't return value because dtrace doesn't currently support it
2149                             HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref))
2150 DEFINE_CALLNONVIRTUALMETHODV(jfloat,   Float,   T_FLOAT
2151                             , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2152                             HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())
2153 DEFINE_CALLNONVIRTUALMETHODV(jdouble,  Double,  T_DOUBLE
2154                             , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2155                             HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN())
2156 
2157 #define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \
2158                                     , EntryProbe, ReturnProbe)      \
2159 \
2160   DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \
2161                           , ReturnProbe);\
2162 \
2163 JNI_ENTRY(ResultType, \
2164           jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \
2165   JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \
2166 \
2167   EntryProbe;\
2168   ResultType ret;\
2169   DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \
2170                      (const ResultType&)ret);\
2171 \
2172   JavaValue jvalue(Tag); \
2173   JNI_ArgumentPusherArray ap(methodID, args); \
2174   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \
2175   ret = jvalue.get_##ResultType(); \
2176   return ret;\
2177 JNI_END
2178 
2179 // the runtime type of subword integral basic types is integer
2180 DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN
2181                             , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2182                             HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))
2183 DEFINE_CALLNONVIRTUALMETHODA(jbyte,    Byte,    T_BYTE
2184                             , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2185                             HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))
2186 DEFINE_CALLNONVIRTUALMETHODA(jchar,    Char,    T_CHAR
2187                             , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2188                             HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))
2189 DEFINE_CALLNONVIRTUALMETHODA(jshort,   Short,   T_SHORT
2190                             , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2191                             HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))
2192 
2193 DEFINE_CALLNONVIRTUALMETHODA(jobject,  Object,  T_OBJECT
2194                             , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2195                             HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))
2196 DEFINE_CALLNONVIRTUALMETHODA(jint,     Int,     T_INT
2197                             , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2198                             HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))
2199 DEFINE_CALLNONVIRTUALMETHODA(jlong,    Long,    T_LONG
2200                             , HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2201 // Float and double probes don't return value because dtrace doesn't currently support it
2202                             HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref))
2203 DEFINE_CALLNONVIRTUALMETHODA(jfloat,   Float,   T_FLOAT
2204                             , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2205                             HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
2206 DEFINE_CALLNONVIRTUALMETHODA(jdouble,  Double,  T_DOUBLE
2207                             , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2208                             HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
2209 
2210 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
2211                          , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
2212 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
2213                          , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
2214 DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
2215                          , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
2216 #endif /* USDT2 */
2217 
2218 JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))
2219   JNIWrapper("CallNonvirtualVoidMethod");
2220 
2221 #ifndef USDT2
2222   DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry,
2223                env, obj, cls, methodID);
2224 #else /* USDT2 */
2225   HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(
2226                env, obj, cls, (uintptr_t) methodID);
2227 #endif /* USDT2 */
2228   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);
2229 
2230   va_list args;
2231   va_start(args, methodID);
2232   JavaValue jvalue(T_VOID);
2233   JNI_ArgumentPusherVaArg ap(methodID, args);
2234   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
2235   va_end(args);
2236 JNI_END
2237 
2238 
2239 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))
2240   JNIWrapper("CallNonvirtualVoidMethodV");
2241 
2242 #ifndef USDT2
2243   DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry,
2244                env, obj, cls, methodID);
2245 #else /* USDT2 */
2246   HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(
2247                env, obj, cls, (uintptr_t) methodID);
2248 #endif /* USDT2 */
2249   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);
2250 
2251   JavaValue jvalue(T_VOID);
2252   JNI_ArgumentPusherVaArg ap(methodID, args);
2253   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
2254 JNI_END
2255 
2256 
2257 JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))
2258   JNIWrapper("CallNonvirtualVoidMethodA");
2259 #ifndef USDT2
2260   DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodA__entry,
2261                 env, obj, cls, methodID);
2262 #else /* USDT2 */
2263   HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(
2264                 env, obj, cls, (uintptr_t) methodID);
2265 #endif /* USDT2 */
2266   DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);
2267   JavaValue jvalue(T_VOID);
2268   JNI_ArgumentPusherArray ap(methodID, args);
2269   jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);
2270 JNI_END
2271 
2272 
2273 #ifndef USDT2
2274 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag) \
2275 \
2276   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType);\
2277   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType);\
2278   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType);\
2279 \
2280 JNI_ENTRY(ResultType, \
2281           jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
2282   JNIWrapper("CallStatic" XSTR(Result) "Method"); \
2283 \
2284   DTRACE_PROBE3(hotspot_jni, CallStatic##Result##Method__entry, env, cls, methodID);\
2285   ResultType ret = 0;\
2286   DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
2287                      (const ResultType&)ret);\
2288 \
2289   va_list args; \
2290   va_start(args, methodID); \
2291   JavaValue jvalue(Tag); \
2292   JNI_ArgumentPusherVaArg ap(methodID, args); \
2293   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
2294   va_end(args); \
2295   ret = jvalue.get_##ResultType(); \
2296   return ret;\
2297 JNI_END \
2298 \
2299 JNI_ENTRY(ResultType, \
2300           jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
2301   JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
2302   DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodV__entry, env, cls, methodID);\
2303   ResultType ret = 0;\
2304   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
2305                      (const ResultType&)ret);\
2306 \
2307   JavaValue jvalue(Tag); \
2308   JNI_ArgumentPusherVaArg ap(methodID, args); \
2309   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
2310   ret = jvalue.get_##ResultType(); \
2311   return ret;\
2312 JNI_END \
2313 \
2314 JNI_ENTRY(ResultType, \
2315           jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
2316   JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
2317   DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodA__entry, env, cls, methodID);\
2318   ResultType ret = 0;\
2319   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
2320                      (const ResultType&)ret);\
2321 \
2322   JavaValue jvalue(Tag); \
2323   JNI_ArgumentPusherArray ap(methodID, args); \
2324   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
2325   ret = jvalue.get_##ResultType(); \
2326   return ret;\
2327 JNI_END
2328 
2329 // the runtime type of subword integral basic types is integer
2330 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN)
2331 DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE)
2332 DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR)
2333 DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT)
2334 
2335 DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT)
2336 DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT)
2337 DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG)
2338 DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT)
2339 DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE)
2340 
2341 
2342 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod);
2343 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV);
2344 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA);
2345 
2346 #else /* USDT2 */
2347 
2348 #define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \
2349                                 , EntryProbe, ResultProbe) \
2350 \
2351   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \
2352                           , ResultProbe);                               \
2353 \
2354 JNI_ENTRY(ResultType, \
2355           jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \
2356   JNIWrapper("CallStatic" XSTR(Result) "Method"); \
2357 \
2358   EntryProbe; \
2359   ResultType ret = 0;\
2360   DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \
2361                      (const ResultType&)ret);\
2362 \
2363   va_list args; \
2364   va_start(args, methodID); \
2365   JavaValue jvalue(Tag); \
2366   JNI_ArgumentPusherVaArg ap(methodID, args); \
2367   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
2368   va_end(args); \
2369   ret = jvalue.get_##ResultType(); \
2370   return ret;\
2371 JNI_END
2372 
2373 // the runtime type of subword integral basic types is integer
2374 DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN
2375                         , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2376                         HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));
2377 DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE
2378                         , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2379                         HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));
2380 DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR
2381                         , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2382                         HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));
2383 DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT
2384                         , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2385                         HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));
2386 
2387 DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT
2388                         , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2389                         HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));
2390 DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT
2391                         , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2392                         HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));
2393 DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG
2394                         , HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2395                         HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref));
2396 // Float and double probes don't return value because dtrace doesn't currently support it
2397 DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT
2398                         , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2399                         HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());
2400 DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE
2401                         , HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2402                         HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN());
2403 
2404 #define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \
2405                                 , EntryProbe, ResultProbe) \
2406 \
2407   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \
2408                           , ResultProbe);                               \
2409 \
2410 JNI_ENTRY(ResultType, \
2411           jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \
2412   JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \
2413 \
2414   EntryProbe; \
2415   ResultType ret = 0;\
2416   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \
2417                      (const ResultType&)ret);\
2418 \
2419   JavaValue jvalue(Tag); \
2420   JNI_ArgumentPusherVaArg ap(methodID, args); \
2421   /* Make sure class is initialized before trying to invoke its method */ \
2422   KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls))); \
2423   Klass::cast(k())->initialize(CHECK_0); \
2424   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
2425   va_end(args); \
2426   ret = jvalue.get_##ResultType(); \
2427   return ret;\
2428 JNI_END
2429 
2430 // the runtime type of subword integral basic types is integer
2431 DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN
2432                         , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2433                         HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));
2434 DEFINE_CALLSTATICMETHODV(jbyte,    Byte,    T_BYTE
2435                         , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2436                         HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));
2437 DEFINE_CALLSTATICMETHODV(jchar,    Char,    T_CHAR
2438                         , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2439                         HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));
2440 DEFINE_CALLSTATICMETHODV(jshort,   Short,   T_SHORT
2441                         , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2442                         HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));
2443 
2444 DEFINE_CALLSTATICMETHODV(jobject,  Object,  T_OBJECT
2445                         , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2446                         HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));
2447 DEFINE_CALLSTATICMETHODV(jint,     Int,     T_INT
2448                         , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2449                         HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));
2450 DEFINE_CALLSTATICMETHODV(jlong,    Long,    T_LONG
2451                         , HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2452                         HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref));
2453 // Float and double probes don't return value because dtrace doesn't currently support it
2454 DEFINE_CALLSTATICMETHODV(jfloat,   Float,   T_FLOAT
2455                         , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2456                         HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());
2457 DEFINE_CALLSTATICMETHODV(jdouble,  Double,  T_DOUBLE
2458                         , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2459                         HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN());
2460 
2461 #define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \
2462                                 , EntryProbe, ResultProbe) \
2463 \
2464   DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \
2465                           , ResultProbe);                               \
2466 \
2467 JNI_ENTRY(ResultType, \
2468           jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \
2469   JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \
2470 \
2471   EntryProbe; \
2472   ResultType ret = 0;\
2473   DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \
2474                      (const ResultType&)ret);\
2475 \
2476   JavaValue jvalue(Tag); \
2477   JNI_ArgumentPusherArray ap(methodID, args); \
2478   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \
2479   ret = jvalue.get_##ResultType(); \
2480   return ret;\
2481 JNI_END
2482 
2483 // the runtime type of subword integral basic types is integer
2484 DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN
2485                         , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2486                         HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));
2487 DEFINE_CALLSTATICMETHODA(jbyte,    Byte,    T_BYTE
2488                         , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2489                         HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));
2490 DEFINE_CALLSTATICMETHODA(jchar,    Char,    T_CHAR
2491                         , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2492                         HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));
2493 DEFINE_CALLSTATICMETHODA(jshort,   Short,   T_SHORT
2494                         , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2495                         HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));
2496 
2497 DEFINE_CALLSTATICMETHODA(jobject,  Object,  T_OBJECT
2498                         , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2499                         HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));
2500 DEFINE_CALLSTATICMETHODA(jint,     Int,     T_INT
2501                         , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2502                         HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));
2503 DEFINE_CALLSTATICMETHODA(jlong,    Long,    T_LONG
2504                         , HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2505                         HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref));
2506 // Float and double probes don't return value because dtrace doesn't currently support it
2507 DEFINE_CALLSTATICMETHODA(jfloat,   Float,   T_FLOAT
2508                         , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2509                         HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
2510 DEFINE_CALLSTATICMETHODA(jdouble,  Double,  T_DOUBLE
2511                         , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2512                         HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
2513 
2514 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
2515                          , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
2516 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
2517                          , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
2518 DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
2519                          , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
2520 #endif /* USDT2 */
2521 
2522 JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))
2523   JNIWrapper("CallStaticVoidMethod");
2524 #ifndef USDT2
2525   DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID);
2526 #else /* USDT2 */
2527   HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(
2528                                          env, cls, (uintptr_t) methodID);
2529 #endif /* USDT2 */
2530   DT_VOID_RETURN_MARK(CallStaticVoidMethod);
2531 
2532   va_list args;
2533   va_start(args, methodID);
2534   JavaValue jvalue(T_VOID);
2535   JNI_ArgumentPusherVaArg ap(methodID, args);
2536   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2537   va_end(args);
2538 JNI_END
2539 
2540 
2541 JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))
2542   JNIWrapper("CallStaticVoidMethodV");
2543 #ifndef USDT2
2544   DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID);
2545 #else /* USDT2 */
2546   HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(
2547                                           env, cls, (uintptr_t) methodID);
2548 #endif /* USDT2 */
2549   DT_VOID_RETURN_MARK(CallStaticVoidMethodV);
2550 
2551   JavaValue jvalue(T_VOID);
2552   JNI_ArgumentPusherVaArg ap(methodID, args);
2553   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2554 JNI_END
2555 
2556 
2557 JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))
2558   JNIWrapper("CallStaticVoidMethodA");
2559 #ifndef USDT2
2560   DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID);
2561 #else /* USDT2 */
2562   HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(
2563                                           env, cls, (uintptr_t) methodID);
2564 #endif /* USDT2 */
2565   DT_VOID_RETURN_MARK(CallStaticVoidMethodA);
2566 
2567   JavaValue jvalue(T_VOID);
2568   JNI_ArgumentPusherArray ap(methodID, args);
2569   jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);
2570 JNI_END
2571 
2572 
2573 //
2574 // Accessing Fields
2575 //
2576 
2577 
2578 #ifndef USDT2
2579 DT_RETURN_MARK_DECL(GetFieldID, jfieldID);
2580 #else /* USDT2 */
2581 DT_RETURN_MARK_DECL(GetFieldID, jfieldID
2582                     , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
2583 #endif /* USDT2 */
2584 
2585 JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
2586           const char *name, const char *sig))
2587   JNIWrapper("GetFieldID");
2588 #ifndef USDT2
2589   DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig);
2590 #else /* USDT2 */
2591   HOTSPOT_JNI_GETFIELDID_ENTRY(
2592                                env, clazz, (char *) name, (char *) sig);
2593 #endif /* USDT2 */
2594   jfieldID ret = 0;
2595   DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
2596 
2597   // The class should have been loaded (we have an instance of the class
2598   // passed in) so the field and signature should already be in the symbol
2599   // table.  If they're not there, the field doesn't exist.
2600   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2601   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2602   if (fieldname == NULL || signame == NULL) {
2603     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2604   }
2605   KlassHandle k(THREAD,
2606                 java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
2607   // Make sure class is initialized before handing id's out to fields
2608   Klass::cast(k())->initialize(CHECK_NULL);
2609 
2610   fieldDescriptor fd;
2611   if (!Klass::cast(k())->oop_is_instance() ||
2612       !instanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {
2613     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2614   }
2615 
2616   // A jfieldID for a non-static field is simply the offset of the field within the instanceOop
2617   // It may also have hash bits for k, if VerifyJNIFields is turned on.
2618   ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());
2619   return ret;
2620 JNI_END
2621 
2622 
2623 JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))
2624   JNIWrapper("GetObjectField");
2625 #ifndef USDT2
2626   DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);
2627 #else /* USDT2 */
2628   HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(
2629                                    env, obj, (uintptr_t) fieldID);
2630 #endif /* USDT2 */
2631   oop o = JNIHandles::resolve_non_null(obj);
2632   klassOop k = o->klass();
2633   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2634   // Keep JVMTI addition small and only check enabled flag here.
2635   // jni_GetField_probe() assumes that is okay to create handles.
2636   if (JvmtiExport::should_post_field_access()) {
2637     o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);
2638   }
2639   jobject ret = JNIHandles::make_local(env, o->obj_field(offset));
2640 #ifndef SERIALGC
2641   // If G1 is enabled and we are accessing the value of the referent
2642   // field in a reference object then we need to register a non-null
2643   // referent with the SATB barrier.
2644   if (UseG1GC) {
2645     bool needs_barrier = false;
2646 
2647     if (ret != NULL &&
2648         offset == java_lang_ref_Reference::referent_offset &&
2649         instanceKlass::cast(k)->reference_type() != REF_NONE) {
2650       assert(instanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");
2651       needs_barrier = true;
2652     }
2653 
2654     if (needs_barrier) {
2655       oop referent = JNIHandles::resolve(ret);
2656       G1SATBCardTableModRefBS::enqueue(referent);
2657     }
2658   }
2659 #endif // SERIALGC
2660 #ifndef USDT2
2661   DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);
2662 #else /* USDT2 */
2663 HOTSPOT_JNI_GETOBJECTFIELD_RETURN(
2664                                   ret);
2665 #endif /* USDT2 */
2666   return ret;
2667 JNI_END
2668 
2669 
2670 #ifndef USDT2
2671 #define DEFINE_GETFIELD(Return,Fieldname,Result) \
2672 \
2673   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\
2674 \
2675 JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
2676   JNIWrapper("Get" XSTR(Result) "Field"); \
2677 \
2678   DTRACE_PROBE3(hotspot_jni, Get##Result##Field__entry, env, obj, fieldID);\
2679   Return ret = 0;\
2680   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
2681 \
2682   oop o = JNIHandles::resolve_non_null(obj); \
2683   klassOop k = o->klass(); \
2684   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2685   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2686   /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
2687   /* and creates a ResetNoHandleMark.                                   */ \
2688   if (JvmtiExport::should_post_field_access()) { \
2689     o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
2690   } \
2691   ret = o->Fieldname##_field(offset); \
2692   return ret; \
2693 JNI_END
2694 
2695 DEFINE_GETFIELD(jboolean, bool,   Boolean)
2696 DEFINE_GETFIELD(jbyte,    byte,   Byte)
2697 DEFINE_GETFIELD(jchar,    char,   Char)
2698 DEFINE_GETFIELD(jshort,   short,  Short)
2699 DEFINE_GETFIELD(jint,     int,    Int)
2700 DEFINE_GETFIELD(jlong,    long,   Long)
2701 DEFINE_GETFIELD(jfloat,   float,  Float)
2702 DEFINE_GETFIELD(jdouble,  double, Double)
2703 
2704 #else /* USDT2 */
2705 
2706 #define DEFINE_GETFIELD(Return,Fieldname,Result \
2707   , EntryProbe, ReturnProbe) \
2708 \
2709   DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \
2710   , ReturnProbe); \
2711 \
2712 JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \
2713   JNIWrapper("Get" XSTR(Result) "Field"); \
2714 \
2715   EntryProbe; \
2716   Return ret = 0;\
2717   DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\
2718 \
2719   oop o = JNIHandles::resolve_non_null(obj); \
2720   klassOop k = o->klass(); \
2721   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2722   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2723   /* jni_GetField_probe_nh() assumes that is not okay to create handles */ \
2724   /* and creates a ResetNoHandleMark.                                   */ \
2725   if (JvmtiExport::should_post_field_access()) { \
2726     o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \
2727   } \
2728   ret = o->Fieldname##_field(offset); \
2729   return ret; \
2730 JNI_END
2731 
2732 DEFINE_GETFIELD(jboolean, bool,   Boolean
2733                 , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2734                 HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))
2735 DEFINE_GETFIELD(jbyte,    byte,   Byte
2736                 , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2737                 HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))
2738 DEFINE_GETFIELD(jchar,    char,   Char
2739                 , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2740                 HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))
2741 DEFINE_GETFIELD(jshort,   short,  Short
2742                 , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2743                 HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))
2744 DEFINE_GETFIELD(jint,     int,    Int
2745                 , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2746                 HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))
2747 DEFINE_GETFIELD(jlong,    long,   Long
2748                 , HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2749                 HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref))
2750 // Float and double probes don't return value because dtrace doesn't currently support it
2751 DEFINE_GETFIELD(jfloat,   float,  Float
2752                 , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2753                 HOTSPOT_JNI_GETFLOATFIELD_RETURN())
2754 DEFINE_GETFIELD(jdouble,  double, Double
2755                 , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2756                 HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())
2757 #endif /* USDT2 */
2758 
2759 address jni_GetBooleanField_addr() {
2760   return (address)jni_GetBooleanField;
2761 }
2762 address jni_GetByteField_addr() {
2763   return (address)jni_GetByteField;
2764 }
2765 address jni_GetCharField_addr() {
2766   return (address)jni_GetCharField;
2767 }
2768 address jni_GetShortField_addr() {
2769   return (address)jni_GetShortField;
2770 }
2771 address jni_GetIntField_addr() {
2772   return (address)jni_GetIntField;
2773 }
2774 address jni_GetLongField_addr() {
2775   return (address)jni_GetLongField;
2776 }
2777 address jni_GetFloatField_addr() {
2778   return (address)jni_GetFloatField;
2779 }
2780 address jni_GetDoubleField_addr() {
2781   return (address)jni_GetDoubleField;
2782 }
2783 
2784 JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))
2785   JNIWrapper("SetObjectField");
2786 #ifndef USDT2
2787   DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value);
2788 #else /* USDT2 */
2789   HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(
2790                                    env, obj, (uintptr_t) fieldID, value);
2791 #endif /* USDT2 */
2792   oop o = JNIHandles::resolve_non_null(obj);
2793   klassOop k = o->klass();
2794   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2795   // Keep JVMTI addition small and only check enabled flag here.
2796   // jni_SetField_probe_nh() assumes that is not okay to create handles
2797   // and creates a ResetNoHandleMark.
2798   if (JvmtiExport::should_post_field_modification()) {
2799     jvalue field_value;
2800     field_value.l = value;
2801     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);
2802   }
2803   o->obj_field_put(offset, JNIHandles::resolve(value));
2804 #ifndef USDT2
2805   DTRACE_PROBE(hotspot_jni, SetObjectField__return);
2806 #else /* USDT2 */
2807   HOTSPOT_JNI_SETOBJECTFIELD_RETURN(
2808 );
2809 #endif /* USDT2 */
2810 JNI_END
2811 
2812 #ifndef USDT2
2813 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \
2814 \
2815 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2816   JNIWrapper("Set" XSTR(Result) "Field"); \
2817 \
2818   HS_DTRACE_PROBE_CDECL_N(hotspot_jni, Set##Result##Field__entry, \
2819     ( JNIEnv*, jobject, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \
2820   HS_DTRACE_PROBE_N(hotspot_jni, Set##Result##Field__entry, \
2821     ( env, obj, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \
2822 \
2823   oop o = JNIHandles::resolve_non_null(obj); \
2824   klassOop k = o->klass(); \
2825   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2826   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2827   /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2828   /* and creates a ResetNoHandleMark.                                   */ \
2829   if (JvmtiExport::should_post_field_modification()) { \
2830     jvalue field_value; \
2831     field_value.unionType = value; \
2832     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2833   } \
2834   o->Fieldname##_field_put(offset, value); \
2835   DTRACE_PROBE(hotspot_jni, Set##Result##Field__return);\
2836 JNI_END
2837 
2838 DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z)
2839 DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b)
2840 DEFINE_SETFIELD(jchar,    char,   Char,    'C', c)
2841 DEFINE_SETFIELD(jshort,   short,  Short,   'S', s)
2842 DEFINE_SETFIELD(jint,     int,    Int,     'I', i)
2843 DEFINE_SETFIELD(jlong,    long,   Long,    'J', j)
2844 DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f)
2845 DEFINE_SETFIELD(jdouble,  double, Double,  'D', d)
2846 
2847 #else /* USDT2 */
2848 
2849 #define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2850                         , EntryProbe, ReturnProbe) \
2851 \
2852 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
2853   JNIWrapper("Set" XSTR(Result) "Field"); \
2854 \
2855   EntryProbe; \
2856 \
2857   oop o = JNIHandles::resolve_non_null(obj); \
2858   klassOop k = o->klass(); \
2859   int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);  \
2860   /* Keep JVMTI addition small and only check enabled flag here.       */ \
2861   /* jni_SetField_probe_nh() assumes that is not okay to create handles */ \
2862   /* and creates a ResetNoHandleMark.                                   */ \
2863   if (JvmtiExport::should_post_field_modification()) { \
2864     jvalue field_value; \
2865     field_value.unionType = value; \
2866     o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \
2867   } \
2868   o->Fieldname##_field_put(offset, value); \
2869   ReturnProbe; \
2870 JNI_END
2871 
2872 DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z
2873                 , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2874                 HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
2875 DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b
2876                 , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2877                 HOTSPOT_JNI_SETBYTEFIELD_RETURN())
2878 DEFINE_SETFIELD(jchar,    char,   Char,    'C', c
2879                 , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2880                 HOTSPOT_JNI_SETCHARFIELD_RETURN())
2881 DEFINE_SETFIELD(jshort,   short,  Short,   'S', s
2882                 , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2883                 HOTSPOT_JNI_SETSHORTFIELD_RETURN())
2884 DEFINE_SETFIELD(jint,     int,    Int,     'I', i
2885                 , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2886                 HOTSPOT_JNI_SETINTFIELD_RETURN())
2887 DEFINE_SETFIELD(jlong,    long,   Long,    'J', j
2888                 , HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2889                 HOTSPOT_JNI_SETLONGFIELD_RETURN())
2890 // Float and double probes don't return value because dtrace doesn't currently support it
2891 DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f
2892                 , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2893                 HOTSPOT_JNI_SETFLOATFIELD_RETURN())
2894 DEFINE_SETFIELD(jdouble,  double, Double,  'D', d
2895                 , HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2896                 HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())
2897 #endif /* USDT2 */
2898 
2899 #ifndef USDT2
2900 DT_RETURN_MARK_DECL(ToReflectedField, jobject);
2901 #else /* USDT2 */
2902 DT_RETURN_MARK_DECL(ToReflectedField, jobject
2903                     , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
2904 #endif /* USDT2 */
2905 
2906 JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))
2907   JNIWrapper("ToReflectedField");
2908 #ifndef USDT2
2909   DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry,
2910                 env, cls, fieldID, isStatic);
2911 #else /* USDT2 */
2912   HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(
2913                 env, cls, (uintptr_t) fieldID, isStatic);
2914 #endif /* USDT2 */
2915   jobject ret = NULL;
2916   DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);
2917 
2918   fieldDescriptor fd;
2919   bool found = false;
2920   klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
2921 
2922   assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");
2923 
2924   if (isStatic) {
2925     // Static field. The fieldID a JNIid specifying the field holder and the offset within the klassOop.
2926     JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
2927     assert(id->is_static_field_id(), "invalid static field id");
2928     found = id->find_local_field(&fd);
2929   } else {
2930     // Non-static field. The fieldID is really the offset of the field within the instanceOop.
2931     int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);
2932     found = instanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);
2933   }
2934   assert(found, "bad fieldID passed into jni_ToReflectedField");
2935   oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);
2936   ret = JNIHandles::make_local(env, reflected);
2937   return ret;
2938 JNI_END
2939 
2940 
2941 //
2942 // Accessing Static Fields
2943 //
2944 #ifndef USDT2
2945 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);
2946 #else /* USDT2 */
2947 DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
2948                     , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
2949 #endif /* USDT2 */
2950 
2951 JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,
2952           const char *name, const char *sig))
2953   JNIWrapper("GetStaticFieldID");
2954 #ifndef USDT2
2955   DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig);
2956 #else /* USDT2 */
2957   HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(
2958                                      env, clazz, (char *) name, (char *) sig);
2959 #endif /* USDT2 */
2960   jfieldID ret = NULL;
2961   DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);
2962 
2963   // The class should have been loaded (we have an instance of the class
2964   // passed in) so the field and signature should already be in the symbol
2965   // table.  If they're not there, the field doesn't exist.
2966   TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
2967   TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
2968   if (fieldname == NULL || signame == NULL) {
2969     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2970   }
2971   KlassHandle k(THREAD,
2972                 java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
2973   // Make sure class is initialized before handing id's out to static fields
2974   Klass::cast(k())->initialize(CHECK_NULL);
2975 
2976   fieldDescriptor fd;
2977   if (!Klass::cast(k())->oop_is_instance() ||
2978       !instanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {
2979     THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
2980   }
2981 
2982   // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the klassOop
2983   JNIid* id = instanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset());
2984   debug_only(id->set_is_static_field_id();)
2985 
2986   debug_only(id->verify(fd.field_holder()));
2987 
2988   ret = jfieldIDWorkaround::to_static_jfieldID(id);
2989   return ret;
2990 JNI_END
2991 
2992 
2993 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
2994   JNIWrapper("GetStaticObjectField");
2995 #ifndef USDT2
2996   DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
2997 #else /* USDT2 */
2998   HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(
2999                                          env, clazz, (uintptr_t) fieldID);
3000 #endif /* USDT2 */
3001 #ifndef JNICHECK_KERNEL
3002   DEBUG_ONLY(klassOop param_k = jniCheck::validate_class(thread, clazz);)
3003 #endif // JNICHECK_KERNEL
3004   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
3005   assert(id->is_static_field_id(), "invalid static field id");
3006   // Keep JVMTI addition small and only check enabled flag here.
3007   // jni_GetField_probe() assumes that is okay to create handles.
3008   if (JvmtiExport::should_post_field_access()) {
3009     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
3010   }
3011   jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
3012 #ifndef USDT2
3013   DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
3014 #else /* USDT2 */
3015   HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(
3016                                           ret);
3017 #endif /* USDT2 */
3018   return ret;
3019 JNI_END
3020 
3021 #ifndef USDT2
3022 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
3023 \
3024   DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\
3025 \
3026 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
3027   JNIWrapper("GetStatic" XSTR(Result) "Field"); \
3028   DTRACE_PROBE3(hotspot_jni, GetStatic##Result##Field__entry, env, clazz, fieldID);\
3029   Return ret = 0;\
3030   DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
3031                      (const Return&)ret);\
3032   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
3033   assert(id->is_static_field_id(), "invalid static field id"); \
3034   /* Keep JVMTI addition small and only check enabled flag here. */ \
3035   /* jni_GetField_probe() assumes that is okay to create handles. */ \
3036   if (JvmtiExport::should_post_field_access()) { \
3037     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
3038   } \
3039   ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
3040   return ret;\
3041 JNI_END
3042 
3043 DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean)
3044 DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte)
3045 DEFINE_GETSTATICFIELD(jchar,    char,   Char)
3046 DEFINE_GETSTATICFIELD(jshort,   short,  Short)
3047 DEFINE_GETSTATICFIELD(jint,     int,    Int)
3048 DEFINE_GETSTATICFIELD(jlong,    long,   Long)
3049 DEFINE_GETSTATICFIELD(jfloat,   float,  Float)
3050 DEFINE_GETSTATICFIELD(jdouble,  double, Double)
3051 
3052 #else /* USDT2 */
3053 
3054 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \
3055                               , EntryProbe, ReturnProbe) \
3056 \
3057   DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \
3058                           , ReturnProbe);                                          \
3059 \
3060 JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \
3061   JNIWrapper("GetStatic" XSTR(Result) "Field"); \
3062   EntryProbe; \
3063   Return ret = 0;\
3064   DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \
3065                      (const Return&)ret);\
3066   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
3067   assert(id->is_static_field_id(), "invalid static field id"); \
3068   /* Keep JVMTI addition small and only check enabled flag here. */ \
3069   /* jni_GetField_probe() assumes that is okay to create handles. */ \
3070   if (JvmtiExport::should_post_field_access()) { \
3071     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \
3072   } \
3073   ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \
3074   return ret;\
3075 JNI_END
3076 
3077 DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean
3078                       , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))
3079 DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte
3080                       , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref)   )
3081 DEFINE_GETSTATICFIELD(jchar,    char,   Char
3082                       , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref)   )
3083 DEFINE_GETSTATICFIELD(jshort,   short,  Short
3084                       , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref)  )
3085 DEFINE_GETSTATICFIELD(jint,     int,    Int
3086                       , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),     HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref)    )
3087 DEFINE_GETSTATICFIELD(jlong,    long,   Long
3088                       , HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref)   )
3089 // Float and double probes don't return value because dtrace doesn't currently support it
3090 DEFINE_GETSTATICFIELD(jfloat,   float,  Float
3091                       , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN()          )
3092 DEFINE_GETSTATICFIELD(jdouble,  double, Double
3093                       , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),  HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN()         )
3094 #endif /* USDT2 */
3095 
3096 JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))
3097   JNIWrapper("SetStaticObjectField");
3098 #ifndef USDT2
3099   DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value);
3100 #else /* USDT2 */
3101  HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(
3102                                         env, clazz, (uintptr_t) fieldID, value);
3103 #endif /* USDT2 */
3104   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
3105   assert(id->is_static_field_id(), "invalid static field id");
3106   // Keep JVMTI addition small and only check enabled flag here.
3107   // jni_SetField_probe() assumes that is okay to create handles.
3108   if (JvmtiExport::should_post_field_modification()) {
3109     jvalue field_value;
3110     field_value.l = value;
3111     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);
3112   }
3113   id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));
3114 #ifndef USDT2
3115   DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);
3116 #else /* USDT2 */
3117   HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN(
3118                                           );
3119 #endif /* USDT2 */
3120 JNI_END
3121 
3122 
3123 #ifndef USDT2
3124 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \
3125 \
3126 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
3127   JNIWrapper("SetStatic" XSTR(Result) "Field"); \
3128   HS_DTRACE_PROBE_CDECL_N(hotspot_jni, SetStatic##Result##Field__entry,\
3129     ( JNIEnv*, jclass, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \
3130   HS_DTRACE_PROBE_N(hotspot_jni, SetStatic##Result##Field__entry, \
3131     ( env, clazz, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \
3132 \
3133   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
3134   assert(id->is_static_field_id(), "invalid static field id"); \
3135   /* Keep JVMTI addition small and only check enabled flag here. */ \
3136   /* jni_SetField_probe() assumes that is okay to create handles. */ \
3137   if (JvmtiExport::should_post_field_modification()) { \
3138     jvalue field_value; \
3139     field_value.unionType = value; \
3140     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
3141   } \
3142   id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
3143   DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\
3144 JNI_END
3145 
3146 DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z)
3147 DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b)
3148 DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c)
3149 DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s)
3150 DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i)
3151 DEFINE_SETSTATICFIELD(jlong,    long,   Long,    'J', j)
3152 DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f)
3153 DEFINE_SETSTATICFIELD(jdouble,  double, Double,  'D', d)
3154 
3155 #else /* USDT2 */
3156 
3157 #define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \
3158                               , EntryProbe, ReturnProbe) \
3159 \
3160 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
3161   JNIWrapper("SetStatic" XSTR(Result) "Field"); \
3162   EntryProbe; \
3163 \
3164   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
3165   assert(id->is_static_field_id(), "invalid static field id"); \
3166   /* Keep JVMTI addition small and only check enabled flag here. */ \
3167   /* jni_SetField_probe() assumes that is okay to create handles. */ \
3168   if (JvmtiExport::should_post_field_modification()) { \
3169     jvalue field_value; \
3170     field_value.unionType = value; \
3171     JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \
3172   } \
3173   id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \
3174   ReturnProbe;\
3175 JNI_END
3176 
3177 DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z
3178                       , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
3179                       HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
3180 DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b
3181                       , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3182                       HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())
3183 DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c
3184                       , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3185                       HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())
3186 DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s
3187                       , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3188                       HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())
3189 DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i
3190                       , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3191                       HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())
3192 DEFINE_SETSTATICFIELD(jlong,    long,   Long,    'J', j
3193                       , HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3194                       HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN())
3195 // Float and double probes don't return value because dtrace doesn't currently support it
3196 DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f
3197                       , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
3198                       HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())
3199 DEFINE_SETSTATICFIELD(jdouble,  double, Double,  'D', d
3200                       , HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
3201                       HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN())
3202 #endif /* USDT2 */
3203 
3204 //
3205 // String Operations
3206 //
3207 
3208 // Unicode Interface
3209 
3210 #ifndef USDT2
3211 DT_RETURN_MARK_DECL(NewString, jstring);
3212 #else /* USDT2 */
3213 DT_RETURN_MARK_DECL(NewString, jstring
3214                     , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
3215 #endif /* USDT2 */
3216 
3217 JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))
3218   JNIWrapper("NewString");
3219 #ifndef USDT2
3220   DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len);
3221 #else /* USDT2 */
3222  HOTSPOT_JNI_NEWSTRING_ENTRY(
3223                              env, (uint16_t *) unicodeChars, len);
3224 #endif /* USDT2 */
3225   jstring ret = NULL;
3226   DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);
3227   oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);
3228   ret = (jstring) JNIHandles::make_local(env, string);
3229   return ret;
3230 JNI_END
3231 
3232 
3233 JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))
3234   JNIWrapper("GetStringLength");
3235 #ifndef USDT2
3236   DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string);
3237 #else /* USDT2 */
3238   HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(
3239                                     env, string);
3240 #endif /* USDT2 */
3241   jsize ret = java_lang_String::length(JNIHandles::resolve_non_null(string));
3242 #ifndef USDT2
3243   DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);
3244 #else /* USDT2 */
3245  HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(
3246                                     ret);
3247 #endif /* USDT2 */
3248   return ret;
3249 JNI_END
3250 
3251 
3252 JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(
3253   JNIEnv *env, jstring string, jboolean *isCopy))
3254   JNIWrapper("GetStringChars");
3255 #ifndef USDT2
3256   DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy);
3257 #else /* USDT2 */
3258  HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(
3259                                   env, string, (uintptr_t *) isCopy);
3260 #endif /* USDT2 */
3261   //%note jni_5
3262   if (isCopy != NULL) {
3263     *isCopy = JNI_TRUE;
3264   }
3265   oop s = JNIHandles::resolve_non_null(string);
3266   int s_len = java_lang_String::length(s);
3267   typeArrayOop s_value = java_lang_String::value(s);
3268   int s_offset = java_lang_String::offset(s);
3269   jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1);  // add one for zero termination
3270   if (s_len > 0) {
3271     memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
3272   }
3273   buf[s_len] = 0;
3274 #ifndef USDT2
3275   DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);
3276 #else /* USDT2 */
3277   HOTSPOT_JNI_GETSTRINGCHARS_RETURN(
3278                                     buf);
3279 #endif /* USDT2 */
3280   return buf;
3281 JNI_END
3282 
3283 
3284 JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))
3285   JNIWrapper("ReleaseStringChars");
3286 #ifndef USDT2
3287   DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars);
3288 #else /* USDT2 */
3289   HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(
3290                                        env, str, (uint16_t *) chars);
3291 #endif /* USDT2 */
3292   //%note jni_6
3293   if (chars != NULL) {
3294     // Since String objects are supposed to be immutable, don't copy any
3295     // new data back.  A bad user will have to go after the char array.
3296     FreeHeap((void*) chars);
3297   }
3298 #ifndef USDT2
3299   DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return);
3300 #else /* USDT2 */
3301   HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN(
3302 );
3303 #endif /* USDT2 */
3304 JNI_END
3305 
3306 
3307 // UTF Interface
3308 
3309 #ifndef USDT2
3310 DT_RETURN_MARK_DECL(NewStringUTF, jstring);
3311 #else /* USDT2 */
3312 DT_RETURN_MARK_DECL(NewStringUTF, jstring
3313                     , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
3314 #endif /* USDT2 */
3315 
3316 JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))
3317   JNIWrapper("NewStringUTF");
3318 #ifndef USDT2
3319   DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes);
3320 #else /* USDT2 */
3321   HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(
3322                                  env, (char *) bytes);
3323 #endif /* USDT2 */
3324   jstring ret;
3325   DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);
3326 
3327   oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);
3328   ret = (jstring) JNIHandles::make_local(env, result);
3329   return ret;
3330 JNI_END
3331 
3332 
3333 JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))
3334   JNIWrapper("GetStringUTFLength");
3335 #ifndef USDT2
3336   DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string);
3337 #else /* USDT2 */
3338  HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(
3339                                       env, string);
3340 #endif /* USDT2 */
3341   jsize ret = java_lang_String::utf8_length(JNIHandles::resolve_non_null(string));
3342 #ifndef USDT2
3343   DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);
3344 #else /* USDT2 */
3345   HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(
3346                                         ret);
3347 #endif /* USDT2 */
3348   return ret;
3349 JNI_END
3350 
3351 
3352 JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))
3353   JNIWrapper("GetStringUTFChars");
3354 #ifndef USDT2
3355   DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy);
3356 #else /* USDT2 */
3357  HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(
3358                                      env, string, (uintptr_t *) isCopy);
3359 #endif /* USDT2 */
3360   oop java_string = JNIHandles::resolve_non_null(string);
3361   size_t length = java_lang_String::utf8_length(java_string);
3362   char* result = AllocateHeap(length + 1, "GetStringUTFChars");
3363   java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
3364   if (isCopy != NULL) *isCopy = JNI_TRUE;
3365 #ifndef USDT2
3366   DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);
3367 #else /* USDT2 */
3368  HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(
3369                                       result);
3370 #endif /* USDT2 */
3371   return result;
3372 JNI_END
3373 
3374 
3375 JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))
3376   JNIWrapper("ReleaseStringUTFChars");
3377 #ifndef USDT2
3378   DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars);
3379 #else /* USDT2 */
3380  HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(
3381                                          env, str, (char *) chars);
3382 #endif /* USDT2 */
3383   if (chars != NULL) {
3384     FreeHeap((char*) chars);
3385   }
3386 #ifndef USDT2
3387   DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return);
3388 #else /* USDT2 */
3389 HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN(
3390 );
3391 #endif /* USDT2 */
3392 JNI_END
3393 
3394 
3395 JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))
3396   JNIWrapper("GetArrayLength");
3397 #ifndef USDT2
3398   DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array);
3399 #else /* USDT2 */
3400  HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(
3401                                   env, array);
3402 #endif /* USDT2 */
3403   arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));
3404   assert(a->is_array(), "must be array");
3405   jsize ret = a->length();
3406 #ifndef USDT2
3407   DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret);
3408 #else /* USDT2 */
3409  HOTSPOT_JNI_GETARRAYLENGTH_RETURN(
3410                                    ret);
3411 #endif /* USDT2 */
3412   return ret;
3413 JNI_END
3414 
3415 
3416 //
3417 // Object Array Operations
3418 //
3419 
3420 #ifndef USDT2
3421 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);
3422 #else /* USDT2 */
3423 DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
3424                     , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
3425 #endif /* USDT2 */
3426 
3427 JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))
3428   JNIWrapper("NewObjectArray");
3429 #ifndef USDT2
3430   DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement);
3431 #else /* USDT2 */
3432  HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(
3433                                   env, length, elementClass, initialElement);
3434 #endif /* USDT2 */
3435   jobjectArray ret = NULL;
3436   DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);
3437   KlassHandle ek(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(elementClass)));
3438   klassOop ako = Klass::cast(ek())->array_klass(CHECK_NULL);
3439   KlassHandle ak = KlassHandle(THREAD, ako);
3440   objArrayKlass::cast(ak())->initialize(CHECK_NULL);
3441   objArrayOop result = objArrayKlass::cast(ak())->allocate(length, CHECK_NULL);
3442   oop initial_value = JNIHandles::resolve(initialElement);
3443   if (initial_value != NULL) {  // array already initialized with NULL
3444     for (int index = 0; index < length; index++) {
3445       result->obj_at_put(index, initial_value);
3446     }
3447   }
3448   ret = (jobjectArray) JNIHandles::make_local(env, result);
3449   return ret;
3450 JNI_END
3451 
3452 #ifndef USDT2
3453 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);
3454 #else /* USDT2 */
3455 DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
3456                     , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
3457 #endif /* USDT2 */
3458 
3459 JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))
3460   JNIWrapper("GetObjectArrayElement");
3461 #ifndef USDT2
3462   DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index);
3463 #else /* USDT2 */
3464  HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(
3465                                          env, array, index);
3466 #endif /* USDT2 */
3467   jobject ret = NULL;
3468   DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);
3469   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
3470   if (a->is_within_bounds(index)) {
3471     ret = JNIHandles::make_local(env, a->obj_at(index));
3472     return ret;
3473   } else {
3474     char buf[jintAsStringSize];
3475     sprintf(buf, "%d", index);
3476     THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
3477   }
3478 JNI_END
3479 
3480 #ifndef USDT2
3481 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);
3482 #else /* USDT2 */
3483 DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
3484                          , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
3485 #endif /* USDT2 */
3486 
3487 JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))
3488   JNIWrapper("SetObjectArrayElement");
3489 #ifndef USDT2
3490   DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value);
3491 #else /* USDT2 */
3492  HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(
3493                                          env, array, index, value);
3494 #endif /* USDT2 */
3495   DT_VOID_RETURN_MARK(SetObjectArrayElement);
3496 
3497   objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));
3498   oop v = JNIHandles::resolve(value);
3499   if (a->is_within_bounds(index)) {
3500     if (v == NULL || v->is_a(objArrayKlass::cast(a->klass())->element_klass())) {
3501       a->obj_at_put(index, v);
3502     } else {
3503       THROW(vmSymbols::java_lang_ArrayStoreException());
3504     }
3505   } else {
3506     char buf[jintAsStringSize];
3507     sprintf(buf, "%d", index);
3508     THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);
3509   }
3510 JNI_END
3511 
3512 
3513 #ifndef USDT2
3514 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \
3515 \
3516   DT_RETURN_MARK_DECL(New##Result##Array, Return); \
3517 \
3518 JNI_ENTRY(Return, \
3519           jni_New##Result##Array(JNIEnv *env, jsize len)) \
3520   JNIWrapper("New" XSTR(Result) "Array"); \
3521   DTRACE_PROBE2(hotspot_jni, New##Result##Array__entry, env, len);\
3522   Return ret = NULL;\
3523   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
3524 \
3525   oop obj= oopFactory::Allocator(len, CHECK_0); \
3526   ret = (Return) JNIHandles::make_local(env, obj); \
3527   return ret;\
3528 JNI_END
3529 
3530 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean)
3531 DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte)
3532 DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short)
3533 DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char)
3534 DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int)
3535 DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long)
3536 DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float)
3537 DEFINE_NEWSCALARARRAY(jdoubleArray,  new_doubleArray, Double)
3538 
3539 #else /* USDT2 */
3540 
3541 #define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \
3542                               ,EntryProbe,ReturnProbe)  \
3543 \
3544   DT_RETURN_MARK_DECL(New##Result##Array, Return \
3545                       , ReturnProbe); \
3546 \
3547 JNI_ENTRY(Return, \
3548           jni_New##Result##Array(JNIEnv *env, jsize len)) \
3549   JNIWrapper("New" XSTR(Result) "Array"); \
3550   EntryProbe; \
3551   Return ret = NULL;\
3552   DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\
3553 \
3554   oop obj= oopFactory::Allocator(len, CHECK_0); \
3555   ret = (Return) JNIHandles::make_local(env, obj); \
3556   return ret;\
3557 JNI_END
3558 
3559 DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean,
3560                       HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),
3561                       HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))
3562 DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte,
3563                       HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),
3564                       HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))
3565 DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short,
3566                       HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),
3567                       HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))
3568 DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char,
3569                       HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),
3570                       HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))
3571 DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int,
3572                       HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),
3573                       HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))
3574 DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long,
3575                       HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),
3576                       HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))
3577 DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float,
3578                       HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),
3579                       HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))
3580 DEFINE_NEWSCALARARRAY(jdoubleArray,  new_doubleArray, Double,
3581                       HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len),
3582                       HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref))
3583 #endif /* USDT2 */
3584 
3585 // Return an address which will fault if the caller writes to it.
3586 
3587 static char* get_bad_address() {
3588   static char* bad_address = NULL;
3589   if (bad_address == NULL) {
3590     size_t size = os::vm_allocation_granularity();
3591     bad_address = os::reserve_memory(size);
3592     if (bad_address != NULL) {
3593       os::protect_memory(bad_address, size, os::MEM_PROT_READ,
3594                          /*is_committed*/false);
3595     }
3596   }
3597   return bad_address;
3598 }
3599 
3600 
3601 #ifndef USDT2
3602 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag) \
3603 \
3604 JNI_QUICK_ENTRY(ElementType*, \
3605           jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
3606   JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
3607   DTRACE_PROBE3(hotspot_jni, Get##Result##ArrayElements__entry, env, array, isCopy);\
3608   /* allocate an chunk of memory in c land */ \
3609   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3610   ElementType* result; \
3611   int len = a->length(); \
3612   if (len == 0) { \
3613     /* Empty array: legal but useless, can't return NULL. \
3614      * Return a pointer to something useless. \
3615      * Avoid asserts in typeArrayOop. */ \
3616     result = (ElementType*)get_bad_address(); \
3617   } else { \
3618     result = NEW_C_HEAP_ARRAY(ElementType, len); \
3619     /* copy the array to the c chunk */ \
3620     memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
3621   } \
3622   if (isCopy) *isCopy = JNI_TRUE; \
3623   DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\
3624   return result; \
3625 JNI_END
3626 
3627 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
3628 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
3629 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
3630 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
3631 DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
3632 DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
3633 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
3634 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
3635 
3636 #else /* USDT2 */
3637 
3638 #define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
3639                                       , EntryProbe, ReturnProbe) \
3640 \
3641 JNI_QUICK_ENTRY(ElementType*, \
3642           jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \
3643   JNIWrapper("Get" XSTR(Result) "ArrayElements"); \
3644   EntryProbe; \
3645   /* allocate an chunk of memory in c land */ \
3646   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3647   ElementType* result; \
3648   int len = a->length(); \
3649   if (len == 0) { \
3650     /* Empty array: legal but useless, can't return NULL. \
3651      * Return a pointer to something useless. \
3652      * Avoid asserts in typeArrayOop. */ \
3653     result = (ElementType*)get_bad_address(); \
3654   } else { \
3655     result = NEW_C_HEAP_ARRAY(ElementType, len); \
3656     /* copy the array to the c chunk */ \
3657     memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
3658   } \
3659   if (isCopy) *isCopy = JNI_TRUE; \
3660   ReturnProbe; \
3661   return result; \
3662 JNI_END
3663 
3664 DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
3665                               , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3666                               HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))
3667 DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
3668                               , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3669                               HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))
3670 DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
3671                               , HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
3672                               HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result))
3673 DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
3674                               , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
3675                               HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))
3676 DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
3677                               , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3678                               HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))
3679 DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
3680                               , HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3681                               HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))
3682 // Float and double probes don't return value because dtrace doesn't currently support it
3683 DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
3684                               , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3685                               HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
3686 DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double
3687                               , HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3688                               HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))
3689 #endif /* USDT2 */
3690 
3691 #ifndef USDT2
3692 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag) \
3693 \
3694 JNI_QUICK_ENTRY(void, \
3695           jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
3696                                              ElementType *buf, jint mode)) \
3697   JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
3698   DTRACE_PROBE4(hotspot_jni, Release##Result##ArrayElements__entry, env, array, buf, mode);\
3699   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3700   int len = a->length(); \
3701   if (len != 0) {   /* Empty array:  nothing to free or copy. */  \
3702     if ((mode == 0) || (mode == JNI_COMMIT)) { \
3703       memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
3704     } \
3705     if ((mode == 0) || (mode == JNI_ABORT)) { \
3706       FreeHeap(buf); \
3707     } \
3708   } \
3709   DTRACE_PROBE(hotspot_jni, Release##Result##ArrayElements__return);\
3710 JNI_END
3711 
3712 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
3713 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
3714 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
3715 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
3716 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
3717 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
3718 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
3719 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
3720 
3721 #else /* USDT2 */
3722 
3723 #define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
3724                                           , EntryProbe, ReturnProbe);\
3725 \
3726 JNI_QUICK_ENTRY(void, \
3727           jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \
3728                                              ElementType *buf, jint mode)) \
3729   JNIWrapper("Release" XSTR(Result) "ArrayElements"); \
3730   EntryProbe; \
3731   typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3732   int len = a->length(); \
3733   if (len != 0) {   /* Empty array:  nothing to free or copy. */  \
3734     if ((mode == 0) || (mode == JNI_COMMIT)) { \
3735       memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \
3736     } \
3737     if ((mode == 0) || (mode == JNI_ABORT)) { \
3738       FreeHeap(buf); \
3739     } \
3740   } \
3741   ReturnProbe; \
3742 JNI_END
3743 
3744 DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
3745                                   , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
3746                                   HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
3747 DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
3748                                   , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
3749                                   HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
3750 DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
3751                                   ,  HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
3752                                   HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())
3753 DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
3754                                   ,  HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
3755                                   HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())
3756 DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
3757                                   , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),
3758                                   HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())
3759 DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
3760                                   , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
3761                                   HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())
3762 DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
3763                                   , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
3764                                   HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
3765 DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double
3766                                   , HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),
3767                                   HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())
3768 #endif /* USDT2 */
3769 
3770 #ifndef USDT2
3771 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
3772   DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion);\
3773 \
3774 JNI_ENTRY(void, \
3775 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
3776              jsize len, ElementType *buf)) \
3777   JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
3778   DTRACE_PROBE5(hotspot_jni, Get##Result##ArrayRegion__entry, env, array, start, len, buf);\
3779   DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
3780   typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3781   if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
3782     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
3783   } else { \
3784     if (len > 0) { \
3785       int sc = typeArrayKlass::cast(src->klass())->log2_element_size(); \
3786       memcpy((u_char*) buf, \
3787              (u_char*) src->Tag##_at_addr(start), \
3788              len << sc);                          \
3789     } \
3790   } \
3791 JNI_END
3792 
3793 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool)
3794 DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte)
3795 DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short)
3796 DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char)
3797 DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int)
3798 DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long)
3799 DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float)
3800 DEFINE_GETSCALARARRAYREGION(T_DOUBLE,  jdouble, Double,  double)
3801 
3802 #else /* USDT2 */
3803 
3804 #define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
3805                                     , EntryProbe, ReturnProbe); \
3806   DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \
3807                            , ReturnProbe); \
3808 \
3809 JNI_ENTRY(void, \
3810 jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
3811              jsize len, ElementType *buf)) \
3812   JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \
3813   EntryProbe; \
3814   DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \
3815   typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3816   if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \
3817     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
3818   } else { \
3819     if (len > 0) { \
3820       int sc = typeArrayKlass::cast(src->klass())->log2_element_size(); \
3821       memcpy((u_char*) buf, \
3822              (u_char*) src->Tag##_at_addr(start), \
3823              len << sc);                          \
3824     } \
3825   } \
3826 JNI_END
3827 
3828 DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
3829                             , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3830                             HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
3831 DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte
3832                             ,  HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
3833                             HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
3834 DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short
3835                             , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3836                             HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());
3837 DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char
3838                             ,  HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),
3839                             HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());
3840 DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int
3841                             , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),
3842                             HOTSPOT_JNI_GETINTARRAYREGION_RETURN());
3843 DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long
3844                             ,  HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3845                             HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());
3846 DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float
3847                             , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3848                             HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
3849 DEFINE_GETSCALARARRAYREGION(T_DOUBLE,  jdouble, Double,  double
3850                             , HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
3851                             HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());
3852 #endif /* USDT2 */
3853 
3854 #ifndef USDT2
3855 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \
3856   DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion);\
3857 \
3858 JNI_ENTRY(void, \
3859 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
3860              jsize len, const ElementType *buf)) \
3861   JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
3862   DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\
3863   DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
3864   typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3865   if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
3866     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
3867   } else { \
3868     if (len > 0) { \
3869       int sc = typeArrayKlass::cast(dst->klass())->log2_element_size(); \
3870       memcpy((u_char*) dst->Tag##_at_addr(start), \
3871              (u_char*) buf, \
3872              len << sc);    \
3873     } \
3874   } \
3875 JNI_END
3876 
3877 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool)
3878 DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte)
3879 DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short)
3880 DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char)
3881 DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int)
3882 DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long)
3883 DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float)
3884 DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double)
3885 
3886 #else /* USDT2 */
3887 
3888 #define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \
3889                                     , EntryProbe, ReturnProbe); \
3890   DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \
3891                            ,ReturnProbe);           \
3892 \
3893 JNI_ENTRY(void, \
3894 jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \
3895              jsize len, const ElementType *buf)) \
3896   JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \
3897   EntryProbe; \
3898   DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \
3899   typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \
3900   if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \
3901     THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \
3902   } else { \
3903     if (len > 0) { \
3904       int sc = typeArrayKlass::cast(dst->klass())->log2_element_size(); \
3905       memcpy((u_char*) dst->Tag##_at_addr(start), \
3906              (u_char*) buf, \
3907              len << sc);    \
3908     } \
3909   } \
3910 JNI_END
3911 
3912 DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
3913                             , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
3914                             HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
3915 DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte
3916                             , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
3917                             HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
3918 DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short
3919                             , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3920                             HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())
3921 DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char
3922                             , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3923                             HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())
3924 DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int
3925                             , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),
3926                             HOTSPOT_JNI_SETINTARRAYREGION_RETURN())
3927 DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long
3928                             , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3929                             HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
3930 DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float
3931                             , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3932                             HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
3933 DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double
3934                             , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
3935                             HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
3936 #endif /* USDT2 */
3937 
3938 
3939 //
3940 // Interception of natives
3941 //
3942 
3943 // The RegisterNatives call being attempted tried to register with a method that
3944 // is not native.  Ask JVM TI what prefixes have been specified.  Then check
3945 // to see if the native method is now wrapped with the prefixes.  See the
3946 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
3947 static methodOop find_prefixed_native(KlassHandle k,
3948                                       Symbol* name, Symbol* signature, TRAPS) {
3949   ResourceMark rm(THREAD);
3950   methodOop method;
3951   int name_len = name->utf8_length();
3952   char* name_str = name->as_utf8();
3953   int prefix_count;
3954   char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
3955   for (int i = 0; i < prefix_count; i++) {
3956     char* prefix = prefixes[i];
3957     int prefix_len = (int)strlen(prefix);
3958 
3959     // try adding this prefix to the method name and see if it matches another method name
3960     int trial_len = name_len + prefix_len;
3961     char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
3962     strcpy(trial_name_str, prefix);
3963     strcat(trial_name_str, name_str);
3964     TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
3965     if (trial_name == NULL) {
3966       continue; // no such symbol, so this prefix wasn't used, try the next prefix
3967     }
3968     method = Klass::cast(k())->lookup_method(trial_name, signature);
3969     if (method == NULL) {
3970       continue; // signature doesn't match, try the next prefix
3971     }
3972     if (method->is_native()) {
3973       method->set_is_prefixed_native();
3974       return method; // wahoo, we found a prefixed version of the method, return it
3975     }
3976     // found as non-native, so prefix is good, add it, probably just need more prefixes
3977     name_len = trial_len;
3978     name_str = trial_name_str;
3979   }
3980   return NULL; // not found
3981 }
3982 
3983 static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
3984   methodOop method = Klass::cast(k())->lookup_method(name, signature);
3985   if (method == NULL) {
3986     ResourceMark rm;
3987     stringStream st;
3988     st.print("Method %s name or signature does not match",
3989              methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name, signature));
3990     THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
3991   }
3992   if (!method->is_native()) {
3993     // trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
3994     method = find_prefixed_native(k, name, signature, THREAD);
3995     if (method == NULL) {
3996       ResourceMark rm;
3997       stringStream st;
3998       st.print("Method %s is not declared as native",
3999                methodOopDesc::name_and_sig_as_C_string(Klass::cast(k()), name, signature));
4000       THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
4001     }
4002   }
4003 
4004   if (entry != NULL) {
4005     method->set_native_function(entry,
4006       methodOopDesc::native_bind_event_is_interesting);
4007   } else {
4008     method->clear_native_function();
4009   }
4010   if (PrintJNIResolving) {
4011     ResourceMark rm(THREAD);
4012     tty->print_cr("[Registering JNI native method %s.%s]",
4013       Klass::cast(method->method_holder())->external_name(),
4014       method->name()->as_C_string());
4015   }
4016   return true;
4017 }
4018 
4019 #ifndef USDT2
4020 DT_RETURN_MARK_DECL(RegisterNatives, jint);
4021 #else /* USDT2 */
4022 DT_RETURN_MARK_DECL(RegisterNatives, jint
4023                     , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
4024 #endif /* USDT2 */
4025 
4026 JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,
4027                                     const JNINativeMethod *methods,
4028                                     jint nMethods))
4029   JNIWrapper("RegisterNatives");
4030 #ifndef USDT2
4031   DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);
4032 #else /* USDT2 */
4033   HOTSPOT_JNI_REGISTERNATIVES_ENTRY(
4034                                     env, clazz, (void *) methods, nMethods);
4035 #endif /* USDT2 */
4036   jint ret = 0;
4037   DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);
4038 
4039   KlassHandle h_k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz)));
4040 
4041   for (int index = 0; index < nMethods; index++) {
4042     const char* meth_name = methods[index].name;
4043     const char* meth_sig = methods[index].signature;
4044     int meth_name_len = (int)strlen(meth_name);
4045 
4046     // The class should have been loaded (we have an instance of the class
4047     // passed in) so the method and signature should already be in the symbol
4048     // table.  If they're not there, the method doesn't exist.
4049     TempNewSymbol  name = SymbolTable::probe(meth_name, meth_name_len);
4050     TempNewSymbol  signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));
4051 
4052     if (name == NULL || signature == NULL) {
4053       ResourceMark rm;
4054       stringStream st;
4055       st.print("Method %s.%s%s not found", Klass::cast(h_k())->external_name(), meth_name, meth_sig);
4056       // Must return negative value on failure
4057       THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);
4058     }
4059 
4060     bool res = register_native(h_k, name, signature,
4061                                (address) methods[index].fnPtr, THREAD);
4062     if (!res) {
4063       ret = -1;
4064       break;
4065     }
4066   }
4067   return ret;
4068 JNI_END
4069 
4070 
4071 JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))
4072   JNIWrapper("UnregisterNatives");
4073 #ifndef USDT2
4074   DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz);
4075 #else /* USDT2 */
4076  HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(
4077                                      env, clazz);
4078 #endif /* USDT2 */
4079   klassOop k   = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz));
4080   //%note jni_2
4081   if (Klass::cast(k)->oop_is_instance()) {
4082     for (int index = 0; index < instanceKlass::cast(k)->methods()->length(); index++) {
4083       methodOop m = methodOop(instanceKlass::cast(k)->methods()->obj_at(index));
4084       if (m->is_native()) {
4085         m->clear_native_function();
4086         m->set_signature_handler(NULL);
4087       }
4088     }
4089   }
4090 #ifndef USDT2
4091   DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0);
4092 #else /* USDT2 */
4093  HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(
4094                                       0);
4095 #endif /* USDT2 */
4096   return 0;
4097 JNI_END
4098 
4099 //
4100 // Monitor functions
4101 //
4102 
4103 #ifndef USDT2
4104 DT_RETURN_MARK_DECL(MonitorEnter, jint);
4105 #else /* USDT2 */
4106 DT_RETURN_MARK_DECL(MonitorEnter, jint
4107                     , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
4108 #endif /* USDT2 */
4109 
4110 JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))
4111 #ifndef USDT2
4112   DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj);
4113 #else /* USDT2 */
4114  HOTSPOT_JNI_MONITORENTER_ENTRY(
4115                                 env, jobj);
4116 #endif /* USDT2 */
4117   jint ret = JNI_ERR;
4118   DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);
4119 
4120   // If the object is null, we can't do anything with it
4121   if (jobj == NULL) {
4122     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
4123   }
4124 
4125   Handle obj(thread, JNIHandles::resolve_non_null(jobj));
4126   ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));
4127   ret = JNI_OK;
4128   return ret;
4129 JNI_END
4130 
4131 #ifndef USDT2
4132 DT_RETURN_MARK_DECL(MonitorExit, jint);
4133 #else /* USDT2 */
4134 DT_RETURN_MARK_DECL(MonitorExit, jint
4135                     , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
4136 #endif /* USDT2 */
4137 
4138 JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))
4139 #ifndef USDT2
4140   DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj);
4141 #else /* USDT2 */
4142  HOTSPOT_JNI_MONITOREXIT_ENTRY(
4143                                env, jobj);
4144 #endif /* USDT2 */
4145   jint ret = JNI_ERR;
4146   DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);
4147 
4148   // Don't do anything with a null object
4149   if (jobj == NULL) {
4150     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);
4151   }
4152 
4153   Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));
4154   ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));
4155 
4156   ret = JNI_OK;
4157   return ret;
4158 JNI_END
4159 
4160 //
4161 // Extensions
4162 //
4163 
4164 #ifndef USDT2
4165 DT_VOID_RETURN_MARK_DECL(GetStringRegion);
4166 #else /* USDT2 */
4167 DT_VOID_RETURN_MARK_DECL(GetStringRegion
4168                          , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
4169 #endif /* USDT2 */
4170 
4171 JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))
4172   JNIWrapper("GetStringRegion");
4173 #ifndef USDT2
4174   DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf);
4175 #else /* USDT2 */
4176  HOTSPOT_JNI_GETSTRINGREGION_ENTRY(
4177                                    env, string, start, len, buf);
4178 #endif /* USDT2 */
4179   DT_VOID_RETURN_MARK(GetStringRegion);
4180   oop s = JNIHandles::resolve_non_null(string);
4181   int s_len = java_lang_String::length(s);
4182   if (start < 0 || len < 0 || start + len > s_len) {
4183     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
4184   } else {
4185     if (len > 0) {
4186       int s_offset = java_lang_String::offset(s);
4187       typeArrayOop s_value = java_lang_String::value(s);
4188       memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);
4189     }
4190   }
4191 JNI_END
4192 
4193 #ifndef USDT2
4194 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);
4195 #else /* USDT2 */
4196 DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
4197                          , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
4198 #endif /* USDT2 */
4199 
4200 JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))
4201   JNIWrapper("GetStringUTFRegion");
4202 #ifndef USDT2
4203   DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf);
4204 #else /* USDT2 */
4205  HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(
4206                                       env, string, start, len, buf);
4207 #endif /* USDT2 */
4208   DT_VOID_RETURN_MARK(GetStringUTFRegion);
4209   oop s = JNIHandles::resolve_non_null(string);
4210   int s_len = java_lang_String::length(s);
4211   if (start < 0 || len < 0 || start + len > s_len) {
4212     THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());
4213   } else {
4214     //%note jni_7
4215     if (len > 0) {
4216       ResourceMark rm(THREAD);
4217       char *utf_region = java_lang_String::as_utf8_string(s, start, len);
4218       int utf_len = (int)strlen(utf_region);
4219       memcpy(buf, utf_region, utf_len);
4220       buf[utf_len] = 0;
4221     } else {
4222       // JDK null-terminates the buffer even in len is zero
4223       if (buf != NULL) {
4224         buf[0] = 0;
4225       }
4226     }
4227   }
4228 JNI_END
4229 
4230 
4231 JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))
4232   JNIWrapper("GetPrimitiveArrayCritical");
4233 #ifndef USDT2
4234   DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);
4235 #else /* USDT2 */
4236  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(
4237                                              env, array, (uintptr_t *) isCopy);
4238 #endif /* USDT2 */
4239   GC_locker::lock_critical(thread);
4240   if (isCopy != NULL) {
4241     *isCopy = JNI_FALSE;
4242   }
4243   oop a = JNIHandles::resolve_non_null(array);
4244   assert(a->is_array(), "just checking");
4245   BasicType type;
4246   if (a->is_objArray()) {
4247     type = T_OBJECT;
4248   } else {
4249     type = typeArrayKlass::cast(a->klass())->element_type();
4250   }
4251   void* ret = arrayOop(a)->base(type);
4252 #ifndef USDT2
4253   DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);
4254 #else /* USDT2 */
4255  HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(
4256                                               ret);
4257 #endif /* USDT2 */
4258   return ret;
4259 JNI_END
4260 
4261 
4262 JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))
4263   JNIWrapper("ReleasePrimitiveArrayCritical");
4264 #ifndef USDT2
4265   DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);
4266 #else /* USDT2 */
4267   HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(
4268                                                   env, array, carray, mode);
4269 #endif /* USDT2 */
4270   // The array, carray and mode arguments are ignored
4271   GC_locker::unlock_critical(thread);
4272 #ifndef USDT2
4273   DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);
4274 #else /* USDT2 */
4275 HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(
4276 );
4277 #endif /* USDT2 */
4278 JNI_END
4279 
4280 
4281 JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))
4282   JNIWrapper("GetStringCritical");
4283 #ifndef USDT2
4284   DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);
4285 #else /* USDT2 */
4286   HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(
4287                                       env, string, (uintptr_t *) isCopy);
4288 #endif /* USDT2 */
4289   GC_locker::lock_critical(thread);
4290   if (isCopy != NULL) {
4291     *isCopy = JNI_FALSE;
4292   }
4293   oop s = JNIHandles::resolve_non_null(string);
4294   int s_len = java_lang_String::length(s);
4295   typeArrayOop s_value = java_lang_String::value(s);
4296   int s_offset = java_lang_String::offset(s);
4297   const jchar* ret;
4298   if (s_len > 0) {
4299     ret = s_value->char_at_addr(s_offset);
4300   } else {
4301     ret = (jchar*) s_value->base(T_CHAR);
4302   }
4303 #ifndef USDT2
4304   DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);
4305 #else /* USDT2 */
4306  HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(
4307                                       (uint16_t *) ret);
4308 #endif /* USDT2 */
4309   return ret;
4310 JNI_END
4311 
4312 
4313 JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))
4314   JNIWrapper("ReleaseStringCritical");
4315 #ifndef USDT2
4316   DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);
4317 #else /* USDT2 */
4318   HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(
4319                                           env, str, (uint16_t *) chars);
4320 #endif /* USDT2 */
4321   // The str and chars arguments are ignored
4322   GC_locker::unlock_critical(thread);
4323 #ifndef USDT2
4324   DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);
4325 #else /* USDT2 */
4326 HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(
4327 );
4328 #endif /* USDT2 */
4329 JNI_END
4330 
4331 
4332 JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))
4333   JNIWrapper("jni_NewWeakGlobalRef");
4334 #ifndef USDT2
4335   DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);
4336 #else /* USDT2 */
4337  HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(
4338                                     env, ref);
4339 #endif /* USDT2 */
4340   Handle ref_handle(thread, JNIHandles::resolve(ref));
4341   jweak ret = JNIHandles::make_weak_global(ref_handle);
4342 #ifndef USDT2
4343   DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret);
4344 #else /* USDT2 */
4345  HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(
4346                                      ret);
4347 #endif /* USDT2 */
4348   return ret;
4349 JNI_END
4350 
4351 // Must be JNI_ENTRY (with HandleMark)
4352 JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))
4353   JNIWrapper("jni_DeleteWeakGlobalRef");
4354 #ifndef USDT2
4355   DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref);
4356 #else /* USDT2 */
4357   HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(
4358                                         env, ref);
4359 #endif /* USDT2 */
4360   JNIHandles::destroy_weak_global(ref);
4361 #ifndef USDT2
4362   DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return);
4363 #else /* USDT2 */
4364   HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN(
4365                                          );
4366 #endif /* USDT2 */
4367 JNI_END
4368 
4369 
4370 JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))
4371   JNIWrapper("jni_ExceptionCheck");
4372 #ifndef USDT2
4373   DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env);
4374 #else /* USDT2 */
4375  HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(
4376                                   env);
4377 #endif /* USDT2 */
4378   jni_check_async_exceptions(thread);
4379   jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;
4380 #ifndef USDT2
4381   DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret);
4382 #else /* USDT2 */
4383  HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(
4384                                    ret);
4385 #endif /* USDT2 */
4386   return ret;
4387 JNI_END
4388 
4389 
4390 // Initialization state for three routines below relating to
4391 // java.nio.DirectBuffers
4392 static          jint directBufferSupportInitializeStarted = 0;
4393 static volatile jint directBufferSupportInitializeEnded   = 0;
4394 static volatile jint directBufferSupportInitializeFailed  = 0;
4395 static jclass    bufferClass                 = NULL;
4396 static jclass    directBufferClass           = NULL;
4397 static jclass    directByteBufferClass       = NULL;
4398 static jmethodID directByteBufferConstructor = NULL;
4399 static jfieldID  directBufferAddressField    = NULL;
4400 static jfieldID  bufferCapacityField         = NULL;
4401 
4402 static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {
4403   Handle loader;            // null (bootstrap) loader
4404   Handle protection_domain; // null protection domain
4405 
4406   TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
4407   jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
4408 
4409   if (TraceClassResolution && result != NULL) {
4410     trace_class_resolution(java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(result)));
4411   }
4412   return result;
4413 }
4414 
4415 // These lookups are done with the NULL (bootstrap) ClassLoader to
4416 // circumvent any security checks that would be done by jni_FindClass.
4417 JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env))
4418 {
4419   if ((bufferClass           = lookupOne(env, "java/nio/Buffer", thread))           == NULL) { return false; }
4420   if ((directBufferClass     = lookupOne(env, "sun/nio/ch/DirectBuffer", thread))   == NULL) { return false; }
4421   if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; }
4422   return true;
4423 }
4424 JNI_END
4425 
4426 
4427 static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {
4428   if (directBufferSupportInitializeFailed) {
4429     return false;
4430   }
4431 
4432   if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) {
4433     if (!lookupDirectBufferClasses(env)) {
4434       directBufferSupportInitializeFailed = 1;
4435       return false;
4436     }
4437 
4438     // Make global references for these
4439     bufferClass           = (jclass) env->NewGlobalRef(bufferClass);
4440     directBufferClass     = (jclass) env->NewGlobalRef(directBufferClass);
4441     directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);
4442 
4443     // Get needed field and method IDs
4444     directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");
4445     directBufferAddressField    = env->GetFieldID(bufferClass, "address", "J");
4446     bufferCapacityField         = env->GetFieldID(bufferClass, "capacity", "I");
4447 
4448     if ((directByteBufferConstructor == NULL) ||
4449         (directBufferAddressField    == NULL) ||
4450         (bufferCapacityField         == NULL)) {
4451       directBufferSupportInitializeFailed = 1;
4452       return false;
4453     }
4454 
4455     directBufferSupportInitializeEnded = 1;
4456   } else {
4457     while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {
4458       // Set state as yield_all can call os:sleep. On Solaris, yield_all calls
4459       // os::sleep which requires the VM state transition. On other platforms, it
4460       // is not necessary. The following call to change the VM state is purposely
4461       // put inside the loop to avoid potential deadlock when multiple threads
4462       // try to call this method. See 6791815 for more details.
4463       ThreadInVMfromNative tivn(thread);
4464       os::yield_all();
4465     }
4466   }
4467 
4468   return !directBufferSupportInitializeFailed;
4469 }
4470 
4471 extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)
4472 {
4473   // thread_from_jni_environment() will block if VM is gone.
4474   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
4475 
4476   JNIWrapper("jni_NewDirectByteBuffer");
4477 #ifndef USDT2
4478   DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity);
4479 #else /* USDT2 */
4480  HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(
4481                                        env, address, capacity);
4482 #endif /* USDT2 */
4483 
4484   if (!directBufferSupportInitializeEnded) {
4485     if (!initializeDirectBufferSupport(env, thread)) {
4486 #ifndef USDT2
4487       DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, NULL);
4488 #else /* USDT2 */
4489       HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(
4490                                              NULL);
4491 #endif /* USDT2 */
4492       return NULL;
4493     }
4494   }
4495 
4496   // Being paranoid about accidental sign extension on address
4497   jlong addr = (jlong) ((uintptr_t) address);
4498   // NOTE that package-private DirectByteBuffer constructor currently
4499   // takes int capacity
4500   jint  cap  = (jint)  capacity;
4501   jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);
4502 #ifndef USDT2
4503   DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret);
4504 #else /* USDT2 */
4505   HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(
4506                                          ret);
4507 #endif /* USDT2 */
4508   return ret;
4509 }
4510 
4511 #ifndef USDT2
4512 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);
4513 #else /* USDT2 */
4514 DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
4515                     , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
4516 #endif /* USDT2 */
4517 
4518 extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)
4519 {
4520   // thread_from_jni_environment() will block if VM is gone.
4521   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
4522 
4523   JNIWrapper("jni_GetDirectBufferAddress");
4524 #ifndef USDT2
4525   DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf);
4526 #else /* USDT2 */
4527   HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(
4528                                            env, buf);
4529 #endif /* USDT2 */
4530   void* ret = NULL;
4531   DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);
4532 
4533   if (!directBufferSupportInitializeEnded) {
4534     if (!initializeDirectBufferSupport(env, thread)) {
4535       return 0;
4536     }
4537   }
4538 
4539   if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {
4540     return 0;
4541   }
4542 
4543   ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);
4544   return ret;
4545 }
4546 
4547 #ifndef USDT2
4548 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);
4549 #else /* USDT2 */
4550 DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
4551                     , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
4552 #endif /* USDT2 */
4553 
4554 extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)
4555 {
4556   // thread_from_jni_environment() will block if VM is gone.
4557   JavaThread* thread = JavaThread::thread_from_jni_environment(env);
4558 
4559   JNIWrapper("jni_GetDirectBufferCapacity");
4560 #ifndef USDT2
4561   DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf);
4562 #else /* USDT2 */
4563   HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(
4564                                             env, buf);
4565 #endif /* USDT2 */
4566   jlong ret = -1;
4567   DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);
4568 
4569   if (!directBufferSupportInitializeEnded) {
4570     if (!initializeDirectBufferSupport(env, thread)) {
4571       ret = 0;
4572       return ret;
4573     }
4574   }
4575 
4576   if (buf == NULL) {
4577     return -1;
4578   }
4579 
4580   if (!env->IsInstanceOf(buf, directBufferClass)) {
4581     return -1;
4582   }
4583 
4584   // NOTE that capacity is currently an int in the implementation
4585   ret = env->GetIntField(buf, bufferCapacityField);
4586   return ret;
4587 }
4588 
4589 
4590 JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))
4591   JNIWrapper("GetVersion");
4592 #ifndef USDT2
4593   DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env);
4594 #else /* USDT2 */
4595   HOTSPOT_JNI_GETVERSION_ENTRY(
4596                                env);
4597 #endif /* USDT2 */
4598 #ifndef USDT2
4599   DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion);
4600 #else /* USDT2 */
4601   HOTSPOT_JNI_GETVERSION_RETURN(
4602                                 CurrentVersion);
4603 #endif /* USDT2 */
4604   return CurrentVersion;
4605 JNI_END
4606 
4607 extern struct JavaVM_ main_vm;
4608 
4609 JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))
4610   JNIWrapper("jni_GetJavaVM");
4611 #ifndef USDT2
4612   DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm);
4613 #else /* USDT2 */
4614   HOTSPOT_JNI_GETJAVAVM_ENTRY(
4615                               env, (void **) vm);
4616 #endif /* USDT2 */
4617   *vm  = (JavaVM *)(&main_vm);
4618 #ifndef USDT2
4619   DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK);
4620 #else /* USDT2 */
4621   HOTSPOT_JNI_GETJAVAVM_RETURN(
4622                                JNI_OK);
4623 #endif /* USDT2 */
4624   return JNI_OK;
4625 JNI_END
4626 
4627 // Structure containing all jni functions
4628 struct JNINativeInterface_ jni_NativeInterface = {
4629     NULL,
4630     NULL,
4631     NULL,
4632 
4633     NULL,
4634 
4635     jni_GetVersion,
4636 
4637     jni_DefineClass,
4638     jni_FindClass,
4639 
4640     jni_FromReflectedMethod,
4641     jni_FromReflectedField,
4642 
4643     jni_ToReflectedMethod,
4644 
4645     jni_GetSuperclass,
4646     jni_IsAssignableFrom,
4647 
4648     jni_ToReflectedField,
4649 
4650     jni_Throw,
4651     jni_ThrowNew,
4652     jni_ExceptionOccurred,
4653     jni_ExceptionDescribe,
4654     jni_ExceptionClear,
4655     jni_FatalError,
4656 
4657     jni_PushLocalFrame,
4658     jni_PopLocalFrame,
4659 
4660     jni_NewGlobalRef,
4661     jni_DeleteGlobalRef,
4662     jni_DeleteLocalRef,
4663     jni_IsSameObject,
4664 
4665     jni_NewLocalRef,
4666     jni_EnsureLocalCapacity,
4667 
4668     jni_AllocObject,
4669     jni_NewObject,
4670     jni_NewObjectV,
4671     jni_NewObjectA,
4672 
4673     jni_GetObjectClass,
4674     jni_IsInstanceOf,
4675 
4676     jni_GetMethodID,
4677 
4678     jni_CallObjectMethod,
4679     jni_CallObjectMethodV,
4680     jni_CallObjectMethodA,
4681     jni_CallBooleanMethod,
4682     jni_CallBooleanMethodV,
4683     jni_CallBooleanMethodA,
4684     jni_CallByteMethod,
4685     jni_CallByteMethodV,
4686     jni_CallByteMethodA,
4687     jni_CallCharMethod,
4688     jni_CallCharMethodV,
4689     jni_CallCharMethodA,
4690     jni_CallShortMethod,
4691     jni_CallShortMethodV,
4692     jni_CallShortMethodA,
4693     jni_CallIntMethod,
4694     jni_CallIntMethodV,
4695     jni_CallIntMethodA,
4696     jni_CallLongMethod,
4697     jni_CallLongMethodV,
4698     jni_CallLongMethodA,
4699     jni_CallFloatMethod,
4700     jni_CallFloatMethodV,
4701     jni_CallFloatMethodA,
4702     jni_CallDoubleMethod,
4703     jni_CallDoubleMethodV,
4704     jni_CallDoubleMethodA,
4705     jni_CallVoidMethod,
4706     jni_CallVoidMethodV,
4707     jni_CallVoidMethodA,
4708 
4709     jni_CallNonvirtualObjectMethod,
4710     jni_CallNonvirtualObjectMethodV,
4711     jni_CallNonvirtualObjectMethodA,
4712     jni_CallNonvirtualBooleanMethod,
4713     jni_CallNonvirtualBooleanMethodV,
4714     jni_CallNonvirtualBooleanMethodA,
4715     jni_CallNonvirtualByteMethod,
4716     jni_CallNonvirtualByteMethodV,
4717     jni_CallNonvirtualByteMethodA,
4718     jni_CallNonvirtualCharMethod,
4719     jni_CallNonvirtualCharMethodV,
4720     jni_CallNonvirtualCharMethodA,
4721     jni_CallNonvirtualShortMethod,
4722     jni_CallNonvirtualShortMethodV,
4723     jni_CallNonvirtualShortMethodA,
4724     jni_CallNonvirtualIntMethod,
4725     jni_CallNonvirtualIntMethodV,
4726     jni_CallNonvirtualIntMethodA,
4727     jni_CallNonvirtualLongMethod,
4728     jni_CallNonvirtualLongMethodV,
4729     jni_CallNonvirtualLongMethodA,
4730     jni_CallNonvirtualFloatMethod,
4731     jni_CallNonvirtualFloatMethodV,
4732     jni_CallNonvirtualFloatMethodA,
4733     jni_CallNonvirtualDoubleMethod,
4734     jni_CallNonvirtualDoubleMethodV,
4735     jni_CallNonvirtualDoubleMethodA,
4736     jni_CallNonvirtualVoidMethod,
4737     jni_CallNonvirtualVoidMethodV,
4738     jni_CallNonvirtualVoidMethodA,
4739 
4740     jni_GetFieldID,
4741 
4742     jni_GetObjectField,
4743     jni_GetBooleanField,
4744     jni_GetByteField,
4745     jni_GetCharField,
4746     jni_GetShortField,
4747     jni_GetIntField,
4748     jni_GetLongField,
4749     jni_GetFloatField,
4750     jni_GetDoubleField,
4751 
4752     jni_SetObjectField,
4753     jni_SetBooleanField,
4754     jni_SetByteField,
4755     jni_SetCharField,
4756     jni_SetShortField,
4757     jni_SetIntField,
4758     jni_SetLongField,
4759     jni_SetFloatField,
4760     jni_SetDoubleField,
4761 
4762     jni_GetStaticMethodID,
4763 
4764     jni_CallStaticObjectMethod,
4765     jni_CallStaticObjectMethodV,
4766     jni_CallStaticObjectMethodA,
4767     jni_CallStaticBooleanMethod,
4768     jni_CallStaticBooleanMethodV,
4769     jni_CallStaticBooleanMethodA,
4770     jni_CallStaticByteMethod,
4771     jni_CallStaticByteMethodV,
4772     jni_CallStaticByteMethodA,
4773     jni_CallStaticCharMethod,
4774     jni_CallStaticCharMethodV,
4775     jni_CallStaticCharMethodA,
4776     jni_CallStaticShortMethod,
4777     jni_CallStaticShortMethodV,
4778     jni_CallStaticShortMethodA,
4779     jni_CallStaticIntMethod,
4780     jni_CallStaticIntMethodV,
4781     jni_CallStaticIntMethodA,
4782     jni_CallStaticLongMethod,
4783     jni_CallStaticLongMethodV,
4784     jni_CallStaticLongMethodA,
4785     jni_CallStaticFloatMethod,
4786     jni_CallStaticFloatMethodV,
4787     jni_CallStaticFloatMethodA,
4788     jni_CallStaticDoubleMethod,
4789     jni_CallStaticDoubleMethodV,
4790     jni_CallStaticDoubleMethodA,
4791     jni_CallStaticVoidMethod,
4792     jni_CallStaticVoidMethodV,
4793     jni_CallStaticVoidMethodA,
4794 
4795     jni_GetStaticFieldID,
4796 
4797     jni_GetStaticObjectField,
4798     jni_GetStaticBooleanField,
4799     jni_GetStaticByteField,
4800     jni_GetStaticCharField,
4801     jni_GetStaticShortField,
4802     jni_GetStaticIntField,
4803     jni_GetStaticLongField,
4804     jni_GetStaticFloatField,
4805     jni_GetStaticDoubleField,
4806 
4807     jni_SetStaticObjectField,
4808     jni_SetStaticBooleanField,
4809     jni_SetStaticByteField,
4810     jni_SetStaticCharField,
4811     jni_SetStaticShortField,
4812     jni_SetStaticIntField,
4813     jni_SetStaticLongField,
4814     jni_SetStaticFloatField,
4815     jni_SetStaticDoubleField,
4816 
4817     jni_NewString,
4818     jni_GetStringLength,
4819     jni_GetStringChars,
4820     jni_ReleaseStringChars,
4821 
4822     jni_NewStringUTF,
4823     jni_GetStringUTFLength,
4824     jni_GetStringUTFChars,
4825     jni_ReleaseStringUTFChars,
4826 
4827     jni_GetArrayLength,
4828 
4829     jni_NewObjectArray,
4830     jni_GetObjectArrayElement,
4831     jni_SetObjectArrayElement,
4832 
4833     jni_NewBooleanArray,
4834     jni_NewByteArray,
4835     jni_NewCharArray,
4836     jni_NewShortArray,
4837     jni_NewIntArray,
4838     jni_NewLongArray,
4839     jni_NewFloatArray,
4840     jni_NewDoubleArray,
4841 
4842     jni_GetBooleanArrayElements,
4843     jni_GetByteArrayElements,
4844     jni_GetCharArrayElements,
4845     jni_GetShortArrayElements,
4846     jni_GetIntArrayElements,
4847     jni_GetLongArrayElements,
4848     jni_GetFloatArrayElements,
4849     jni_GetDoubleArrayElements,
4850 
4851     jni_ReleaseBooleanArrayElements,
4852     jni_ReleaseByteArrayElements,
4853     jni_ReleaseCharArrayElements,
4854     jni_ReleaseShortArrayElements,
4855     jni_ReleaseIntArrayElements,
4856     jni_ReleaseLongArrayElements,
4857     jni_ReleaseFloatArrayElements,
4858     jni_ReleaseDoubleArrayElements,
4859 
4860     jni_GetBooleanArrayRegion,
4861     jni_GetByteArrayRegion,
4862     jni_GetCharArrayRegion,
4863     jni_GetShortArrayRegion,
4864     jni_GetIntArrayRegion,
4865     jni_GetLongArrayRegion,
4866     jni_GetFloatArrayRegion,
4867     jni_GetDoubleArrayRegion,
4868 
4869     jni_SetBooleanArrayRegion,
4870     jni_SetByteArrayRegion,
4871     jni_SetCharArrayRegion,
4872     jni_SetShortArrayRegion,
4873     jni_SetIntArrayRegion,
4874     jni_SetLongArrayRegion,
4875     jni_SetFloatArrayRegion,
4876     jni_SetDoubleArrayRegion,
4877 
4878     jni_RegisterNatives,
4879     jni_UnregisterNatives,
4880 
4881     jni_MonitorEnter,
4882     jni_MonitorExit,
4883 
4884     jni_GetJavaVM,
4885 
4886     jni_GetStringRegion,
4887     jni_GetStringUTFRegion,
4888 
4889     jni_GetPrimitiveArrayCritical,
4890     jni_ReleasePrimitiveArrayCritical,
4891 
4892     jni_GetStringCritical,
4893     jni_ReleaseStringCritical,
4894 
4895     jni_NewWeakGlobalRef,
4896     jni_DeleteWeakGlobalRef,
4897 
4898     jni_ExceptionCheck,
4899 
4900     jni_NewDirectByteBuffer,
4901     jni_GetDirectBufferAddress,
4902     jni_GetDirectBufferCapacity,
4903 
4904     // New 1_6 features
4905 
4906     jni_GetObjectRefType
4907 };
4908 
4909 
4910 // For jvmti use to modify jni function table.
4911 // Java threads in native contiues to run until it is transitioned
4912 // to VM at safepoint. Before the transition or before it is blocked
4913 // for safepoint it may access jni function table. VM could crash if
4914 // any java thread access the jni function table in the middle of memcpy.
4915 // To avoid this each function pointers are copied automically.
4916 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
4917   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
4918   intptr_t *a = (intptr_t *) jni_functions();
4919   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
4920   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
4921     Atomic::store_ptr(*b++, a++);
4922   }
4923 }
4924 
4925 void quicken_jni_functions() {
4926   // Replace Get<Primitive>Field with fast versions
4927   if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access()
4928       && !VerifyJNIFields && !TraceJNICalls && !CountJNICalls && !CheckJNICalls
4929 #if defined(_WINDOWS) && defined(IA32) && defined(COMPILER2)
4930       // windows x86 currently needs SEH wrapper and the gain of the fast
4931       // versions currently isn't certain for server vm on uniprocessor.
4932       && os::is_MP()
4933 #endif
4934   ) {
4935     address func;
4936     func = JNI_FastGetField::generate_fast_get_boolean_field();
4937     if (func != (address)-1) {
4938       jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
4939     }
4940     func = JNI_FastGetField::generate_fast_get_byte_field();
4941     if (func != (address)-1) {
4942       jni_NativeInterface.GetByteField = (GetByteField_t)func;
4943     }
4944     func = JNI_FastGetField::generate_fast_get_char_field();
4945     if (func != (address)-1) {
4946       jni_NativeInterface.GetCharField = (GetCharField_t)func;
4947     }
4948     func = JNI_FastGetField::generate_fast_get_short_field();
4949     if (func != (address)-1) {
4950       jni_NativeInterface.GetShortField = (GetShortField_t)func;
4951     }
4952     func = JNI_FastGetField::generate_fast_get_int_field();
4953     if (func != (address)-1) {
4954       jni_NativeInterface.GetIntField = (GetIntField_t)func;
4955     }
4956     func = JNI_FastGetField::generate_fast_get_long_field();
4957     if (func != (address)-1) {
4958       jni_NativeInterface.GetLongField = (GetLongField_t)func;
4959     }
4960     func = JNI_FastGetField::generate_fast_get_float_field();
4961     if (func != (address)-1) {
4962       jni_NativeInterface.GetFloatField = (GetFloatField_t)func;
4963     }
4964     func = JNI_FastGetField::generate_fast_get_double_field();
4965     if (func != (address)-1) {
4966       jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;
4967     }
4968   }
4969 }
4970 
4971 // Returns the function structure
4972 struct JNINativeInterface_* jni_functions() {
4973 #ifndef JNICHECK_KERNEL
4974   if (CheckJNICalls) return jni_functions_check();
4975 #else  // JNICHECK_KERNEL
4976   if (CheckJNICalls) warning("-Xcheck:jni is not supported in kernel vm.");
4977 #endif // JNICHECK_KERNEL
4978   return &jni_NativeInterface;
4979 }
4980 
4981 // Returns the function structure
4982 struct JNINativeInterface_* jni_functions_nocheck() {
4983   return &jni_NativeInterface;
4984 }
4985 
4986 
4987 // Invocation API
4988 
4989 
4990 // Forward declaration
4991 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
4992 
4993 // Global invocation API vars
4994 volatile jint vm_created = 0;
4995 // Indicate whether it is safe to recreate VM
4996 volatile jint safe_to_recreate_vm = 1;
4997 struct JavaVM_ main_vm = {&jni_InvokeInterface};
4998 
4999 
5000 #define JAVASTACKSIZE (400 * 1024)    /* Default size of a thread java stack */
5001 enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
5002 
5003 #ifndef USDT2
5004 HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*);
5005 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint);
5006 #else /* USDT2 */
5007 DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint
5008                     , HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));
5009 #endif /* USDT2 */
5010 
5011 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {
5012 #ifndef USDT2
5013   HS_DTRACE_PROBE1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, args_);
5014 #else /* USDT2 */
5015   HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(
5016                                              args_);
5017 #endif /* USDT2 */
5018   JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;
5019   jint ret = JNI_ERR;
5020   DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);
5021 
5022   if (Threads::is_supported_jni_version(args->version)) {
5023     ret = JNI_OK;
5024   }
5025   // 1.1 style no longer supported in hotspot.
5026   // According the JNI spec, we should update args->version on return.
5027   // We also use the structure to communicate with launcher about default
5028   // stack size.
5029   if (args->version == JNI_VERSION_1_1) {
5030     args->version = JNI_VERSION_1_2;
5031     // javaStackSize is int in arguments structure
5032     assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow");
5033     args->javaStackSize = (jint)(ThreadStackSize * K);
5034   }
5035   return ret;
5036 }
5037 
5038 #ifndef PRODUCT
5039 
5040 #include "utilities/quickSort.hpp"
5041 
5042 void execute_internal_vm_tests() {
5043   if (ExecuteInternalVMTests) {
5044     assert(QuickSort::test_quick_sort(), "test_quick_sort failed");
5045     tty->print_cr("All tests passed");
5046   }
5047 }
5048 
5049 #endif
5050 
5051 #ifndef USDT2
5052 HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
5053 DT_RETURN_MARK_DECL(CreateJavaVM, jint);
5054 #else /* USDT2 */
5055 DT_RETURN_MARK_DECL(CreateJavaVM, jint
5056                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
5057 #endif /* USDT2 */
5058 
5059 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {
5060 #ifndef USDT2
5061   HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
5062 #else /* USDT2 */
5063   HOTSPOT_JNI_CREATEJAVAVM_ENTRY(
5064                                  (void **) vm, penv, args);
5065 #endif /* USDT2 */
5066 
5067   jint result = JNI_ERR;
5068   DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
5069 
5070   // We're about to use Atomic::xchg for synchronization.  Some Zero
5071   // platforms use the GCC builtin __sync_lock_test_and_set for this,
5072   // but __sync_lock_test_and_set is not guaranteed to do what we want
5073   // on all architectures.  So we check it works before relying on it.
5074 #if defined(ZERO) && defined(ASSERT)
5075   {
5076     jint a = 0xcafebabe;
5077     jint b = Atomic::xchg(0xdeadbeef, &a);
5078     void *c = &a;
5079     void *d = Atomic::xchg_ptr(&b, &c);
5080     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
5081     assert(c == &b && d == &a, "Atomic::xchg_ptr() works");
5082   }
5083 #endif // ZERO && ASSERT
5084 
5085   // At the moment it's only possible to have one Java VM,
5086   // since some of the runtime state is in global variables.
5087 
5088   // We cannot use our mutex locks here, since they only work on
5089   // Threads. We do an atomic compare and exchange to ensure only
5090   // one thread can call this method at a time
5091 
5092   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
5093   // the add/dec implementations are dependent on whether we are running
5094   // on a multiprocessor, and at this stage of initialization the os::is_MP
5095   // function used to determine this will always return false. Atomic::xchg
5096   // does not have this problem.
5097   if (Atomic::xchg(1, &vm_created) == 1) {
5098     return JNI_ERR;   // already created, or create attempt in progress
5099   }
5100   if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
5101     return JNI_ERR;  // someone tried and failed and retry not allowed.
5102   }
5103 
5104   assert(vm_created == 1, "vm_created is true during the creation");
5105 
5106   /**
5107    * Certain errors during initialization are recoverable and do not
5108    * prevent this method from being called again at a later time
5109    * (perhaps with different arguments).  However, at a certain
5110    * point during initialization if an error occurs we cannot allow
5111    * this function to be called again (or it will crash).  In those
5112    * situations, the 'canTryAgain' flag is set to false, which atomically
5113    * sets safe_to_recreate_vm to 1, such that any new call to
5114    * JNI_CreateJavaVM will immediately fail using the above logic.
5115    */
5116   bool can_try_again = true;
5117 
5118   result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
5119   if (result == JNI_OK) {
5120     JavaThread *thread = JavaThread::current();
5121     /* thread is thread_in_vm here */
5122     *vm = (JavaVM *)(&main_vm);
5123     *(JNIEnv**)penv = thread->jni_environment();
5124 
5125     // Tracks the time application was running before GC
5126     RuntimeService::record_application_start();
5127 
5128     // Notify JVMTI
5129     if (JvmtiExport::should_post_thread_life()) {
5130        JvmtiExport::post_thread_start(thread);
5131     }
5132     // Check if we should compile all classes on bootclasspath
5133     NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
5134     // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
5135     ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
5136   } else {
5137     if (can_try_again) {
5138       // reset safe_to_recreate_vm to 1 so that retrial would be possible
5139       safe_to_recreate_vm = 1;
5140     }
5141 
5142     // Creation failed. We must reset vm_created
5143     *vm = 0;
5144     *(JNIEnv**)penv = 0;
5145     // reset vm_created last to avoid race condition. Use OrderAccess to
5146     // control both compiler and architectural-based reordering.
5147     OrderAccess::release_store(&vm_created, 0);
5148   }
5149 
5150   NOT_PRODUCT(test_error_handler(ErrorHandlerTest));
5151   NOT_PRODUCT(execute_internal_vm_tests());
5152   return result;
5153 }
5154 
5155 #ifndef USDT2
5156 HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \
5157   JavaVM**, jsize, jsize*);
5158 HS_DTRACE_PROBE_DECL1(hotspot_jni, GetCreatedJavaVMs__return, jint);
5159 #endif /* !USDT2 */
5160 
5161 _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
5162   // See bug 4367188, the wrapper can sometimes cause VM crashes
5163   // JNIWrapper("GetCreatedJavaVMs");
5164 #ifndef USDT2
5165   HS_DTRACE_PROBE3(hotspot_jni, GetCreatedJavaVMs__entry, \
5166     vm_buf, bufLen, numVMs);
5167 #else /* USDT2 */
5168   HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY(
5169                                       (void **) vm_buf, bufLen, (uintptr_t *) numVMs);
5170 #endif /* USDT2 */
5171   if (vm_created) {
5172     if (numVMs != NULL) *numVMs = 1;
5173     if (bufLen > 0)     *vm_buf = (JavaVM *)(&main_vm);
5174   } else {
5175     if (numVMs != NULL) *numVMs = 0;
5176   }
5177 #ifndef USDT2
5178   HS_DTRACE_PROBE1(hotspot_jni, GetCreatedJavaVMs__return, JNI_OK);
5179 #else /* USDT2 */
5180   HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(
5181                                     JNI_OK);
5182 #endif /* USDT2 */
5183   return JNI_OK;
5184 }
5185 
5186 extern "C" {
5187 
5188 #ifndef USDT2
5189 DT_RETURN_MARK_DECL(DestroyJavaVM, jint);
5190 #else /* USDT2 */
5191 DT_RETURN_MARK_DECL(DestroyJavaVM, jint
5192                     , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
5193 #endif /* USDT2 */
5194 
5195 jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {
5196 #ifndef USDT2
5197   DTRACE_PROBE1(hotspot_jni, DestroyJavaVM__entry, vm);
5198 #else /* USDT2 */
5199   HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(
5200                                   vm);
5201 #endif /* USDT2 */
5202   jint res = JNI_ERR;
5203   DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);
5204 
5205   if (!vm_created) {
5206     res = JNI_ERR;
5207     return res;
5208   }
5209 
5210   JNIWrapper("DestroyJavaVM");
5211   JNIEnv *env;
5212   JavaVMAttachArgs destroyargs;
5213   destroyargs.version = CurrentVersion;
5214   destroyargs.name = (char *)"DestroyJavaVM";
5215   destroyargs.group = NULL;
5216   res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);
5217   if (res != JNI_OK) {
5218     return res;
5219   }
5220 
5221   // Since this is not a JVM_ENTRY we have to set the thread state manually before entering.
5222   JavaThread* thread = JavaThread::current();
5223   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
5224   if (Threads::destroy_vm()) {
5225     // Should not change thread state, VM is gone
5226     vm_created = false;
5227     res = JNI_OK;
5228     return res;
5229   } else {
5230     ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
5231     res = JNI_ERR;
5232     return res;
5233   }
5234 }
5235 
5236 
5237 static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) {
5238   JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args;
5239 
5240   // Check below commented out from JDK1.2fcs as well
5241   /*
5242   if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) {
5243     return JNI_EVERSION;
5244   }
5245   */
5246 
5247   Thread* t = ThreadLocalStorage::get_thread_slow();
5248   if (t != NULL) {
5249     // If the thread has been attached this operation is a no-op
5250     *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();
5251     return JNI_OK;
5252   }
5253 
5254   // Create a thread and mark it as attaching so it will be skipped by the
5255   // ThreadsListEnumerator - see CR 6404306
5256   JavaThread* thread = new JavaThread(true);
5257 
5258   // Set correct safepoint info. The thread is going to call into Java when
5259   // initializing the Java level thread object. Hence, the correct state must
5260   // be set in order for the Safepoint code to deal with it correctly.
5261   thread->set_thread_state(_thread_in_vm);
5262   // Must do this before initialize_thread_local_storage
5263   thread->record_stack_base_and_size();
5264 
5265   thread->initialize_thread_local_storage();
5266 
5267   if (!os::create_attached_thread(thread)) {
5268     delete thread;
5269     return JNI_ERR;
5270   }
5271   // Enable stack overflow checks
5272   thread->create_stack_guard_pages();
5273 
5274   thread->initialize_tlab();
5275 
5276   thread->cache_global_variables();
5277 
5278   // Crucial that we do not have a safepoint check for this thread, since it has
5279   // not been added to the Thread list yet.
5280   { Threads_lock->lock_without_safepoint_check();
5281     // This must be inside this lock in order to get FullGCALot to work properly, i.e., to
5282     // avoid this thread trying to do a GC before it is added to the thread-list
5283     thread->set_active_handles(JNIHandleBlock::allocate_block());
5284     Threads::add(thread, daemon);
5285     Threads_lock->unlock();
5286   }
5287   // Create thread group and name info from attach arguments
5288   oop group = NULL;
5289   char* thread_name = NULL;
5290   if (args != NULL && Threads::is_supported_jni_version(args->version)) {
5291     group = JNIHandles::resolve(args->group);
5292     thread_name = args->name; // may be NULL
5293   }
5294   if (group == NULL) group = Universe::main_thread_group();
5295 
5296   // Create Java level thread object and attach it to this thread
5297   bool attach_failed = false;
5298   {
5299     EXCEPTION_MARK;
5300     HandleMark hm(THREAD);
5301     Handle thread_group(THREAD, group);
5302     thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD);
5303     if (HAS_PENDING_EXCEPTION) {
5304       CLEAR_PENDING_EXCEPTION;
5305       // cleanup outside the handle mark.
5306       attach_failed = true;
5307     }
5308   }
5309 
5310   if (attach_failed) {
5311     // Added missing cleanup
5312     thread->cleanup_failed_attach_current_thread();
5313     return JNI_ERR;
5314   }
5315 
5316   // mark the thread as no longer attaching
5317   // this uses a fence to push the change through so we don't have
5318   // to regrab the threads_lock
5319   thread->set_done_attaching_via_jni();
5320 
5321   // Set java thread status.
5322   java_lang_Thread::set_thread_status(thread->threadObj(),
5323               java_lang_Thread::RUNNABLE);
5324 
5325   // Notify the debugger
5326   if (JvmtiExport::should_post_thread_life()) {
5327     JvmtiExport::post_thread_start(thread);
5328   }
5329 
5330   *(JNIEnv**)penv = thread->jni_environment();
5331 
5332   // Now leaving the VM, so change thread_state. This is normally automatically taken care
5333   // of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by
5334   // using ThreadStateTransition::transition, we do a callback to the safepoint code if
5335   // needed.
5336 
5337   ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
5338 
5339   // Perform any platform dependent FPU setup
5340   os::setup_fpu();
5341 
5342   return JNI_OK;
5343 }
5344 
5345 
5346 jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
5347 #ifndef USDT2
5348   DTRACE_PROBE3(hotspot_jni, AttachCurrentThread__entry, vm, penv, _args);
5349 #else /* USDT2 */
5350   HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(
5351                                         vm, penv, _args);
5352 #endif /* USDT2 */
5353   if (!vm_created) {
5354 #ifndef USDT2
5355     DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, JNI_ERR);
5356 #else /* USDT2 */
5357   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(
5358                                          (uint32_t) JNI_ERR);
5359 #endif /* USDT2 */
5360     return JNI_ERR;
5361   }
5362 
5363   JNIWrapper("AttachCurrentThread");
5364   jint ret = attach_current_thread(vm, penv, _args, false);
5365 #ifndef USDT2
5366   DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, ret);
5367 #else /* USDT2 */
5368   HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(
5369                                          ret);
5370 #endif /* USDT2 */
5371   return ret;
5372 }
5373 
5374 
5375 jint JNICALL jni_DetachCurrentThread(JavaVM *vm)  {
5376 #ifndef USDT2
5377   DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__entry, vm);
5378 #else /* USDT2 */
5379   HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(
5380                                         vm);
5381 #endif /* USDT2 */
5382   VM_Exit::block_if_vm_exited();
5383 
5384   JNIWrapper("DetachCurrentThread");
5385 
5386   // If the thread has been deattacted the operations is a no-op
5387   if (ThreadLocalStorage::thread() == NULL) {
5388 #ifndef USDT2
5389     DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
5390 #else /* USDT2 */
5391   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
5392                                          JNI_OK);
5393 #endif /* USDT2 */
5394     return JNI_OK;
5395   }
5396 
5397   JavaThread* thread = JavaThread::current();
5398   if (thread->has_last_Java_frame()) {
5399 #ifndef USDT2
5400     DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_ERR);
5401 #else /* USDT2 */
5402   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
5403                                          (uint32_t) JNI_ERR);
5404 #endif /* USDT2 */
5405     // Can't detach a thread that's running java, that can't work.
5406     return JNI_ERR;
5407   }
5408 
5409   // Safepoint support. Have to do call-back to safepoint code, if in the
5410   // middel of a safepoint operation
5411   ThreadStateTransition::transition_from_native(thread, _thread_in_vm);
5412 
5413   // XXX: Note that JavaThread::exit() call below removes the guards on the
5414   // stack pages set up via enable_stack_{red,yellow}_zone() calls
5415   // above in jni_AttachCurrentThread. Unfortunately, while the setting
5416   // of the guards is visible in jni_AttachCurrentThread above,
5417   // the removal of the guards is buried below in JavaThread::exit()
5418   // here. The abstraction should be more symmetrically either exposed
5419   // or hidden (e.g. it could probably be hidden in the same
5420   // (platform-dependent) methods where we do alternate stack
5421   // maintenance work?)
5422   thread->exit(false, JavaThread::jni_detach);
5423   delete thread;
5424 
5425 #ifndef USDT2
5426   DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);
5427 #else /* USDT2 */
5428   HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(
5429                                          JNI_OK);
5430 #endif /* USDT2 */
5431   return JNI_OK;
5432 }
5433 
5434 #ifndef USDT2
5435 DT_RETURN_MARK_DECL(GetEnv, jint);
5436 #else /* USDT2 */
5437 DT_RETURN_MARK_DECL(GetEnv, jint
5438                     , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
5439 #endif /* USDT2 */
5440 
5441 jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
5442 #ifndef USDT2
5443   DTRACE_PROBE3(hotspot_jni, GetEnv__entry, vm, penv, version);
5444 #else /* USDT2 */
5445   HOTSPOT_JNI_GETENV_ENTRY(
5446                            vm, penv, version);
5447 #endif /* USDT2 */
5448   jint ret = JNI_ERR;
5449   DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);
5450 
5451   if (!vm_created) {
5452     *penv = NULL;
5453     ret = JNI_EDETACHED;
5454     return ret;
5455   }
5456 
5457   if (JvmtiExport::is_jvmti_version(version)) {
5458     ret = JvmtiExport::get_jvmti_interface(vm, penv, version);
5459     return ret;
5460   }
5461 
5462 #ifndef JVMPI_VERSION_1
5463 // need these in order to be polite about older agents
5464 #define JVMPI_VERSION_1   ((jint)0x10000001)
5465 #define JVMPI_VERSION_1_1 ((jint)0x10000002)
5466 #define JVMPI_VERSION_1_2 ((jint)0x10000003)
5467 #endif // !JVMPI_VERSION_1
5468 
5469   Thread* thread = ThreadLocalStorage::thread();
5470   if (thread != NULL && thread->is_Java_thread()) {
5471     if (Threads::is_supported_jni_version_including_1_1(version)) {
5472       *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
5473       ret = JNI_OK;
5474       return ret;
5475 
5476     } else if (version == JVMPI_VERSION_1 ||
5477                version == JVMPI_VERSION_1_1 ||
5478                version == JVMPI_VERSION_1_2) {
5479       tty->print_cr("ERROR: JVMPI, an experimental interface, is no longer supported.");
5480       tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
5481       ret = JNI_EVERSION;
5482       return ret;
5483     } else if (JvmtiExport::is_jvmdi_version(version)) {
5484       tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");
5485       tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");
5486       ret = JNI_EVERSION;
5487       return ret;
5488     } else {
5489       *penv = NULL;
5490       ret = JNI_EVERSION;
5491       return ret;
5492     }
5493   } else {
5494     *penv = NULL;
5495     ret = JNI_EDETACHED;
5496     return ret;
5497   }
5498 }
5499 
5500 
5501 jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {
5502 #ifndef USDT2
5503   DTRACE_PROBE3(hotspot_jni, AttachCurrentThreadAsDaemon__entry, vm, penv, _args);
5504 #else /* USDT2 */
5505   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(
5506                                                 vm, penv, _args);
5507 #endif /* USDT2 */
5508   if (!vm_created) {
5509 #ifndef USDT2
5510     DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, JNI_ERR);
5511 #else /* USDT2 */
5512   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(
5513                                                  (uint32_t) JNI_ERR);
5514 #endif /* USDT2 */
5515     return JNI_ERR;
5516   }
5517 
5518   JNIWrapper("AttachCurrentThreadAsDaemon");
5519   jint ret = attach_current_thread(vm, penv, _args, true);
5520 #ifndef USDT2
5521   DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, ret);
5522 #else /* USDT2 */
5523   HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(
5524                                                  ret);
5525 #endif /* USDT2 */
5526   return ret;
5527 }
5528 
5529 
5530 } // End extern "C"
5531 
5532 const struct JNIInvokeInterface_ jni_InvokeInterface = {
5533     NULL,
5534     NULL,
5535     NULL,
5536 
5537     jni_DestroyJavaVM,
5538     jni_AttachCurrentThread,
5539     jni_DetachCurrentThread,
5540     jni_GetEnv,
5541     jni_AttachCurrentThreadAsDaemon
5542 };