jni.cpp revision 2767:436b4a3231bf
150472Speter/*
21664Sphk * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
369040Sben * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
469040Sben *
569040Sben * This code is free software; you can redistribute it and/or modify it
669040Sben * under the terms of the GNU General Public License version 2 only, as
782604Salex * published by the Free Software Foundation.
882604Salex *
982604Salex * This code is distributed in the hope that it will be useful, but WITHOUT
1082604Salex * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111664Sphk * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
123023Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
133023Srgrimes * accompanied this code).
1482604Salex *
1582604Salex * You should have received a copy of the GNU General Public License version
1682604Salex * 2 along with this work; if not, write to the Free Software Foundation,
171664Sphk * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1872679Skris *
1999260Sjohan * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2072878Skris * or visit www.oracle.com if you need additional information or have any
2172878Skris * questions.
2272878Skris *
2372878Skris */
2472878Skris
2599260Sjohan#include "precompiled.hpp"
2673145Skris#include "classfile/classLoader.hpp"
2773145Skris#include "classfile/javaClasses.hpp"
2873145Skris#include "classfile/symbolTable.hpp"
2972878Skris#include "classfile/systemDictionary.hpp"
3072878Skris#include "classfile/vmSymbols.hpp"
3172679Skris#include "interpreter/linkResolver.hpp"
32101232Sru#ifndef SERIALGC
33101232Sru#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
34101232Sru#endif // SERIALGC
3572878Skris#include "memory/allocation.inline.hpp"
3674146Skris#include "memory/gcLocker.inline.hpp"
3772878Skris#include "memory/oopFactory.hpp"
3858648Skris#include "memory/universe.inline.hpp"
3968917Sdougb#include "oops/instanceKlass.hpp"
4058648Skris#include "oops/instanceOop.hpp"
4168917Sdougb#include "oops/markOop.hpp"
4258648Skris#include "oops/methodOop.hpp"
4358648Skris#include "oops/objArrayKlass.hpp"
4458648Skris#include "oops/objArrayOop.hpp"
451664Sphk#include "oops/oop.inline.hpp"
4629281Sjkh#include "oops/symbol.hpp"
471664Sphk#include "oops/typeArrayKlass.hpp"
4859006Sobrien#include "oops/typeArrayOop.hpp"
4959006Sobrien#include "prims/jni.h"
5059006Sobrien#include "prims/jniCheck.hpp"
5159006Sobrien#include "prims/jniFastGetField.hpp"
521664Sphk#include "prims/jvm.h"
5359006Sobrien#include "prims/jvm_misc.hpp"
5459006Sobrien#include "prims/jvmtiExport.hpp"
5562136Sobrien#include "prims/jvmtiThreadState.hpp"
5662136Sobrien#include "runtime/compilationPolicy.hpp"
5780452Speter#include "runtime/fieldDescriptor.hpp"
5899260Sjohan#include "runtime/fprofiler.hpp"
5962136Sobrien#include "runtime/handles.inline.hpp"
6082604Salex#include "runtime/interfaceSupport.hpp"
6182604Salex#include "runtime/java.hpp"
6282604Salex#include "runtime/javaCalls.hpp"
6382604Salex#include "runtime/jfieldIDWorkaround.hpp"
6462136Sobrien#include "runtime/reflection.hpp"
6568917Sdougb#include "runtime/sharedRuntime.hpp"
6668263Sobrien#include "runtime/signature.hpp"
6768263Sobrien#include "runtime/vm_operations.hpp"
6868263Sobrien#include "services/runtimeService.hpp"
6965380Sobrien#include "utilities/defaultStream.hpp"
7065380Sobrien#include "utilities/dtrace.hpp"
7165380Sobrien#include "utilities/events.hpp"
7281749Sobrien#include "utilities/histogram.hpp"
7381749Sobrien#ifdef TARGET_OS_FAMILY_linux
7481749Sobrien# include "os_linux.inline.hpp"
7581749Sobrien# include "thread_linux.inline.hpp"
7681749Sobrien#endif
7781749Sobrien#ifdef TARGET_OS_FAMILY_solaris
7842325Sobrien# include "os_solaris.inline.hpp"
79100870Sru# include "thread_solaris.inline.hpp"
8035222Sache#endif
8165884Sache#ifdef TARGET_OS_FAMILY_windows
8265957Sache# include "os_windows.inline.hpp"
8365884Sache# include "thread_windows.inline.hpp"
8464803Sbrian#endif
8564803Sbrian#ifdef TARGET_OS_FAMILY_bsd
8664803Sbrian# include "os_bsd.inline.hpp"
8768705Sgreen# include "thread_bsd.inline.hpp"
8868705Sgreen#endif
8968705Sgreen
9097387Stjrstatic jint CurrentVersion = JNI_VERSION_1_6;
9197387Stjr
9297387Stjr
9397387Stjr// The DT_RETURN_MARK macros create a scoped object to fire the dtrace
9451299Speter// '-return' probe regardless of the return path is taken out of the function.
9557542Skris// Methods that have multiple return paths use this to avoid having to
9690522Sobrien// instrument each return path.  Methods that use CHECK or THROW must use this
9759124Sasmodai// since those macros can cause an immedate uninstrumented return.
9857542Skris//
9990522Sobrien// In order to get the return value, a reference to the variable containing
10077041Sru// the return value must be passed to the contructor of the object, and
10192868Sru// the return value must be set before return (since the mark object has
10261139Shoek// a reference to it).
10358859Ssheldonh//
10459884Schuckr// Example:
10557764Skris// DT_RETURN_MARK_DECL(SomeFunc, int);
10657542Skris// JNI_ENTRY(int, SomeFunc, ...)
10757542Skris//   int return_value = 0;
10898064Sdougb//   DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);
10957542Skris//   foo(CHECK_0)
11058418Sobrien//   return_value = 5;
11159338Sobrien//   return return_value;
11258280Skris// JNI_END
11357553Skris#ifndef USDT2
11457542Skris#define DT_RETURN_MARK_DECL(name, type)                                    \
11557542Skris  HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type);                \
11657542Skris  DTRACE_ONLY(                                                             \
11765381Sobrien    class DTraceReturnProbeMark_##name {                                   \
11857553Skris     public:                                                               \
11957542Skris      const type& _ret_ref;                                                \
12035206Sphk      DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
12173043Skris      ~DTraceReturnProbeMark_##name() {                                    \
12273043Skris        HS_DTRACE_PROBE1(hotspot_jni, name##__return, _ret_ref);           \
12373043Skris      }                                                                    \
12473043Skris    }                                                                      \
12573043Skris  )
12673043Skris// Void functions are simpler since there's no return value
12773043Skris#define DT_VOID_RETURN_MARK_DECL(name)                                     \
12861744Sobrien  HS_DTRACE_PROBE_DECL0(hotspot_jni, name##__return);                      \
12961744Sobrien  DTRACE_ONLY(                                                             \
13061744Sobrien    class DTraceReturnProbeMark_##name {                                   \
13188461Sru     public:                                                               \
13288461Sru      ~DTraceReturnProbeMark_##name() {                                    \
13357458Smarkm        HS_DTRACE_PROBE0(hotspot_jni, name##__return);                     \
13473401Skris      }                                                                    \
13573401Skris    }                                                                      \
13673401Skris  )
13773401Skris
13862482Speter#else /* USDT2 */
13973401Skris
14073401Skris#define DT_RETURN_MARK_DECL(name, type, probe)                             \
14199260Sjohan  DTRACE_ONLY(                                                             \
14273401Skris    class DTraceReturnProbeMark_##name {                                   \
14363123Speter     public:                                                               \
14462482Speter      const type& _ret_ref;                                                \
14574990Sasmodai      DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {}         \
14674990Sasmodai      ~DTraceReturnProbeMark_##name() {                                    \
14774990Sasmodai        probe;                                                             \
14874990Sasmodai      }                                                                    \
14974990Sasmodai    }                                                                      \
15057071Srwatson  )
1511684Scsgr// Void functions are simpler since there's no return value
1521684Scsgr#define DT_VOID_RETURN_MARK_DECL(name, probe)                              \
1531684Scsgr  DTRACE_ONLY(                                                             \
1549509Srgrimes    class DTraceReturnProbeMark_##name {                                   \
1551697Sache     public:                                                               \
1561697Sache      ~DTraceReturnProbeMark_##name() {                                    \
15720847Speter        probe;                                                             \
15820847Speter      }                                                                    \
15920847Speter    }                                                                      \
16020847Speter  )
16120847Speter#endif /* USDT2 */
16220847Speter
16347318Sobrien// Place these macros in the function to mark the return.  Non-void
16447430Sobrien// functions need the type and address of the return value.
16574247Smurray#define DT_RETURN_MARK(name, type, ref) \
16620847Speter  DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )
16720847Speter#define DT_VOID_RETURN_MARK(name) \
1681697Sache  DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )
1691697Sache
1701697Sache
17125424Sandreas// Use these to select distinct code for floating-point vs. non-floating point
1721733Sadam// situations.  Used from within common macros where we need slightly
1731733Sadam// different behavior for Float/Double
17414102Sadam#define FP_SELECT_Boolean(intcode, fpcode) intcode
17514102Sadam#define FP_SELECT_Byte(intcode, fpcode)    intcode
17614102Sadam#define FP_SELECT_Char(intcode, fpcode)    intcode
17714102Sadam#define FP_SELECT_Short(intcode, fpcode)   intcode
1781733Sadam#define FP_SELECT_Object(intcode, fpcode)  intcode
1791740Sadam#define FP_SELECT_Int(intcode, fpcode)     intcode
1803023Srgrimes#define FP_SELECT_Long(intcode, fpcode)    intcode
1811733Sadam#define FP_SELECT_Float(intcode, fpcode)   fpcode
18218927Spst#define FP_SELECT_Double(intcode, fpcode)  fpcode
18326522Sbde#define FP_SELECT(TypeName, intcode, fpcode) \
18426522Sbde  FP_SELECT_##TypeName(intcode, fpcode)
1851733Sadam
18618927Spst#define COMMA ,
18749190Snik
18818927Spst// Choose DT_RETURN_MARK macros  based on the type: float/double -> void
18949190Snik// (dtrace doesn't do FP yet)
19049190Snik#ifndef USDT2
19118928Spst#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \
19218927Spst  FP_SELECT(TypeName, \
19326522Sbde    DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) )
19426522Sbde#else /* USDT2 */
19518927Spst#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe)    \
19626522Sbde  FP_SELECT(TypeName, \
19718927Spst    DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )
19868310Sps#endif /* USDT2 */
19968310Sps#define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \
20068310Sps  FP_SELECT(TypeName, \
20199260Sjohan    DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )
20218927Spst
20368310Sps
20468310Sps// out-of-line helpers for class jfieldIDWorkaround:
20575982Sjim
2063241Scsgrbool jfieldIDWorkaround::is_valid_jfieldID(klassOop k, jfieldID id) {
20729931Smarkm  if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {
2083241Scsgr    uintptr_t as_uint = (uintptr_t) id;
20929931Smarkm    intptr_t offset = raw_instance_offset(id);
21010758Sache    if (is_checked_jfieldID(id)) {
21110758Sache      if (!klass_hash_ok(k, id)) {
21256553Smarkm        return false;
21376518Sassar      }
21456553Smarkm    }
21556553Smarkm    return instanceKlass::cast(k)->contains_field_offset(offset);
21656553Smarkm  } else {
21796436Snectar    JNIid* result = (JNIid*) id;
21896436Snectar#ifdef ASSERT
21996436Snectar    return result != NULL && result->is_static_field_id();
22096436Snectar#else
22156553Smarkm    return result != NULL;
22296436Snectar#endif
22338003Sdima  }
22456553Smarkm}
22556553Smarkm
22638003Sdima
22756553Smarkmintptr_t jfieldIDWorkaround::encode_klass_hash(klassOop k, intptr_t offset) {
22838003Sdima  if (offset <= small_offset_mask) {
22938003Sdima    klassOop field_klass = k;
23037162Sjkh    klassOop super_klass = Klass::cast(field_klass)->super();
23137162Sjkh    // With compressed oops the most super class with nonstatic fields would
23237162Sjkh    // be the owner of fields embedded in the header.
23310758Sache    while (instanceKlass::cast(super_klass)->has_nonstatic_fields() &&
23410758Sache           instanceKlass::cast(super_klass)->contains_field_offset(offset)) {
23518716Sache      field_klass = super_klass;   // super contains the field also
23620545Sache      super_klass = Klass::cast(field_klass)->super();
23749777Ssheldonh    }
23864605Sjoe    debug_only(No_Safepoint_Verifier nosafepoint;)
23918716Sache    uintptr_t klass_hash = field_klass->identity_hash();
24047651Sbillf    return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;
24154670Sbillf  } else {
24224225Sjoerg#if 0
24324225Sjoerg    #ifndef PRODUCT
24424225Sjoerg    {
24524225Sjoerg      ResourceMark rm;
24624225Sjoerg      warning("VerifyJNIFields: long offset %d in %s", offset, Klass::cast(k)->external_name());
24724225Sjoerg    }
24824225Sjoerg    #endif
24958449Snik#endif
25058449Snik    return 0;
25158449Snik  }
25258449Snik}
25358449Snik
25478035Sachebool jfieldIDWorkaround::klass_hash_ok(klassOop k, jfieldID id) {
25565970Sgshapiro  uintptr_t as_uint = (uintptr_t) id;
25665970Sgshapiro  intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;
25765970Sgshapiro  do {
25872846Sgshapiro    debug_only(No_Safepoint_Verifier nosafepoint;)
25972846Sgshapiro    // Could use a non-blocking query for identity_hash here...
26072846Sgshapiro    if ((k->identity_hash() & klass_mask) == klass_hash)
26172846Sgshapiro      return true;
26272916Sgshapiro    k = Klass::cast(k)->super();
26398462Sgshapiro  } while (k != NULL);
26498462Sgshapiro  return false;
26598462Sgshapiro}
26672846Sgshapiro
26773836Sgshapirovoid jfieldIDWorkaround::verify_instance_jfieldID(klassOop k, jfieldID id) {
26872846Sgshapiro  guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );
26994676Sgshapiro  uintptr_t as_uint = (uintptr_t) id;
27094676Sgshapiro  intptr_t offset = raw_instance_offset(id);
27194676Sgshapiro  if (VerifyJNIFields) {
27294676Sgshapiro    if (is_checked_jfieldID(id)) {
27398462Sgshapiro      guarantee(klass_hash_ok(k, id),
27498462Sgshapiro    "Bug in native code: jfieldID class must match object");
27598462Sgshapiro    } else {
27694676Sgshapiro#if 0
27794676Sgshapiro      #ifndef PRODUCT
27894676Sgshapiro      if (Verbose) {
27972918Sgshapiro  ResourceMark rm;
28072918Sgshapiro  warning("VerifyJNIFields: unverified offset %d for %s", offset, Klass::cast(k)->external_name());
28198462Sgshapiro      }
28298462Sgshapiro      #endif
28398462Sgshapiro#endif
28472918Sgshapiro    }
28572918Sgshapiro  }
28672918Sgshapiro  guarantee(instanceKlass::cast(k)->contains_field_offset(offset),
28780175Sgshapiro      "Bug in native code: jfieldID offset must address interior of object");
28880175Sgshapiro}
28980175Sgshapiro
29080175Sgshapiro// Pick a reasonable higher bound for local capacity requested
29180175Sgshapiro// for EnsureLocalCapacity and PushLocalFrame.  We don't want it too
29280175Sgshapiro// high because a test (or very unusual application) may try to allocate
29378862Sgshapiro// that many handles and run out of swap space.  An implementation is
29465970Sgshapiro// permitted to allocate more handles than the ensured capacity, so this
29565970Sgshapiro// value is set high enough to prevent compatibility problems.
29665970Sgshapiroconst int MAX_REASONABLE_LOCAL_CAPACITY = 4*K;
297101065Sume
29865970Sgshapiro
29965970Sgshapiro// Wrapper to trace JNI functions
30065970Sgshapiro
30169380Sgshapiro#ifdef ASSERT
30293449Sume  Histogram* JNIHistogram;
30393449Sume  static volatile jint JNIHistogram_lock = 0;
30469380Sgshapiro
30593446Sume  class JNITraceWrapper : public StackObj {
30669380Sgshapiro   public:
30765970Sgshapiro    JNITraceWrapper(const char* format, ...) {
30865970Sgshapiro      if (TraceJNICalls) {
30965970Sgshapiro        va_list ap;
31065970Sgshapiro        va_start(ap, format);
31190803Sgshapiro        tty->print("JNI ");
31290803Sgshapiro        tty->vprint_cr(format, ap);
31390803Sgshapiro        va_end(ap);
31490803Sgshapiro      }
31590803Sgshapiro    }
31690803Sgshapiro  };
31790803Sgshapiro
31890803Sgshapiro  class JNIHistogramElement : public HistogramElement {
31997200Sgshapiro    public:
32097200Sgshapiro     JNIHistogramElement(const char* name);
32197200Sgshapiro  };
32297200Sgshapiro
32397200Sgshapiro  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
358DT_RETURN_MARK_DECL(DefineClass, jclass);
359#else /* USDT2 */
360DT_RETURN_MARK_DECL(DefineClass, jclass
361                    , HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));
362#endif /* USDT2 */
363
364JNI_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;
414JNI_END
415
416
417
418static bool first_time_FindClass = true;
419
420#ifndef USDT2
421DT_RETURN_MARK_DECL(FindClass, jclass);
422#else /* USDT2 */
423DT_RETURN_MARK_DECL(FindClass, jclass
424                    , HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));
425#endif /* USDT2 */
426
427JNI_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;
496JNI_END
497
498#ifndef USDT2
499DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);
500#else /* USDT2 */
501DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID
502                    , HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));
503#endif /* USDT2 */
504
505JNI_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;
537JNI_END
538
539#ifndef USDT2
540DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);
541#else /* USDT2 */
542DT_RETURN_MARK_DECL(FromReflectedField, jfieldID
543                    , HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));
544#endif /* USDT2 */
545
546JNI_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;
586JNI_END
587
588#ifndef USDT2
589DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);
590#else /* USDT2 */
591DT_RETURN_MARK_DECL(ToReflectedMethod, jobject
592                    , HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));
593#endif /* USDT2 */
594
595JNI_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;
616JNI_END
617
618#ifndef USDT2
619DT_RETURN_MARK_DECL(GetSuperclass, jclass);
620#else /* USDT2 */
621DT_RETURN_MARK_DECL(GetSuperclass, jclass
622                    , HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));
623#endif /* USDT2 */
624
625JNI_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;
657JNI_END
658
659JNI_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;
692JNI_END
693
694#ifndef USDT2
695DT_RETURN_MARK_DECL(Throw, jint);
696#else /* USDT2 */
697DT_RETURN_MARK_DECL(Throw, jint
698                    , HOTSPOT_JNI_THROW_RETURN(_ret_ref));
699#endif /* USDT2 */
700
701JNI_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();
714JNI_END
715
716#ifndef USDT2
717DT_RETURN_MARK_DECL(ThrowNew, jint);
718#else /* USDT2 */
719DT_RETURN_MARK_DECL(ThrowNew, jint
720                    , HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));
721#endif /* USDT2 */
722
723JNI_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();
740JNI_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
752static void jni_check_async_exceptions(JavaThread *thread) {
753  assert(thread == Thread::current(), "must be itself");
754  thread->check_and_handle_async_exceptions();
755}
756
757JNI_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;
775JNI_END
776
777
778JNI_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 */
827JNI_END
828
829
830JNI_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 */
852JNI_END
853
854
855JNI_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
866JNI_END
867
868
869JNI_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;
900JNI_END
901
902
903JNI_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;
932JNI_END
933
934
935JNI_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;
952JNI_END
953
954// Must be JNI_ENTRY (with HandleMark)
955JNI_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 */
970JNI_END
971
972JNI_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 */
987JNI_END
988
989JNI_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;
1007JNI_END
1008
1009
1010JNI_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;
1026JNI_END
1027
1028JNI_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;
1049JNI_END
1050
1051// Return the Handle Type
1052JNI_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;
1077JNI_END
1078
1079
1080class 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
1121class 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
1203class 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
1281enum JNICallType {
1282  JNI_STATIC,
1283  JNI_VIRTUAL,
1284  JNI_NONVIRTUAL
1285};
1286
1287static 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
1300static 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
1315static 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
1342static 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
1418static 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
1427DT_RETURN_MARK_DECL(AllocObject, jobject);
1428#else /* USDT2 */
1429DT_RETURN_MARK_DECL(AllocObject, jobject
1430                    , HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));
1431#endif /* USDT2 */
1432
1433JNI_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;
1448JNI_END
1449
1450#ifndef USDT2
1451DT_RETURN_MARK_DECL(NewObjectA, jobject);
1452#else /* USDT2 */
1453DT_RETURN_MARK_DECL(NewObjectA, jobject
1454                    , HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));
1455#endif /* USDT2 */
1456
1457JNI_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;
1474JNI_END
1475
1476#ifndef USDT2
1477DT_RETURN_MARK_DECL(NewObjectV, jobject);
1478#else /* USDT2 */
1479DT_RETURN_MARK_DECL(NewObjectV, jobject
1480                    , HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));
1481#endif /* USDT2 */
1482
1483JNI_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;
1500JNI_END
1501
1502#ifndef USDT2
1503DT_RETURN_MARK_DECL(NewObject, jobject);
1504#else /* USDT2 */
1505DT_RETURN_MARK_DECL(NewObject, jobject
1506                    , HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));
1507#endif /* USDT2 */
1508
1509JNI_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;
1529JNI_END
1530
1531
1532JNI_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;
1550JNI_END
1551
1552JNI_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;
1576JNI_END
1577
1578
1579static 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
1633JNI_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;
1650JNI_END
1651
1652
1653JNI_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;
1670JNI_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\
1685JNI_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;\
1702JNI_END \
1703\
1704\
1705JNI_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;\
1719JNI_END \
1720\
1721\
1722JNI_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;\
1735JNI_END
1736
1737// the runtime type of subword integral basic types is integer
1738DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN)
1739DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE)
1740DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR)
1741DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT)
1742
1743DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT)
1744DEFINE_CALLMETHOD(jint,     Int,     T_INT)
1745DEFINE_CALLMETHOD(jlong,    Long,    T_LONG)
1746DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT)
1747DEFINE_CALLMETHOD(jdouble,  Double,  T_DOUBLE)
1748
1749DT_VOID_RETURN_MARK_DECL(CallVoidMethod);
1750DT_VOID_RETURN_MARK_DECL(CallVoidMethodV);
1751DT_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\
1761JNI_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;\
1778JNI_END
1779
1780// the runtime type of subword integral basic types is integer
1781DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN
1782                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1783                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1784DEFINE_CALLMETHOD(jbyte,    Byte,    T_BYTE
1785                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1786                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1787DEFINE_CALLMETHOD(jchar,    Char,    T_CHAR
1788                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1789                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1790DEFINE_CALLMETHOD(jshort,   Short,   T_SHORT
1791                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1792                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1793
1794DEFINE_CALLMETHOD(jobject,  Object,  T_OBJECT
1795                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1796                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1797DEFINE_CALLMETHOD(jint,     Int,     T_INT,
1798                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1799                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1800DEFINE_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
1804DEFINE_CALLMETHOD(jfloat,   Float,   T_FLOAT
1805                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1806                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1807DEFINE_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\
1817JNI_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;\
1831JNI_END
1832
1833// the runtime type of subword integral basic types is integer
1834DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN
1835                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1836                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1837DEFINE_CALLMETHODV(jbyte,    Byte,    T_BYTE
1838                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1839                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1840DEFINE_CALLMETHODV(jchar,    Char,    T_CHAR
1841                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1842                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1843DEFINE_CALLMETHODV(jshort,   Short,   T_SHORT
1844                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1845                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1846
1847DEFINE_CALLMETHODV(jobject,  Object,  T_OBJECT
1848                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1849                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1850DEFINE_CALLMETHODV(jint,     Int,     T_INT,
1851                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1852                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1853DEFINE_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
1857DEFINE_CALLMETHODV(jfloat,   Float,   T_FLOAT
1858                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1859                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1860DEFINE_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\
1870JNI_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;\
1883JNI_END
1884
1885// the runtime type of subword integral basic types is integer
1886DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN
1887                  , HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1888                  HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))
1889DEFINE_CALLMETHODA(jbyte,    Byte,    T_BYTE
1890                  , HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1891                  HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))
1892DEFINE_CALLMETHODA(jchar,    Char,    T_CHAR
1893                  , HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1894                  HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))
1895DEFINE_CALLMETHODA(jshort,   Short,   T_SHORT
1896                  , HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1897                  HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))
1898
1899DEFINE_CALLMETHODA(jobject,  Object,  T_OBJECT
1900                  , HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1901                  HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))
1902DEFINE_CALLMETHODA(jint,     Int,     T_INT,
1903                  HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1904                  HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))
1905DEFINE_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
1909DEFINE_CALLMETHODA(jfloat,   Float,   T_FLOAT
1910                  , HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1911                  HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())
1912DEFINE_CALLMETHODA(jdouble,  Double,  T_DOUBLE
1913                  , HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),
1914                  HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())
1915
1916DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());
1917DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());
1918DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());
1919
1920#endif /* USDT2 */
1921
1922JNI_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);
1938JNI_END
1939
1940
1941JNI_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);
1954JNI_END
1955
1956
1957JNI_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);
1970JNI_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\
1980JNI_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;\
1997JNI_END \
1998\
1999JNI_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;\
2012JNI_END \
2013\
2014JNI_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;\
2027JNI_END
2028
2029// the runtime type of subword integral basic types is integer
2030DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN)
2031DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE)
2032DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR)
2033DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT)
2034
2035DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT)
2036DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT)
2037DEFINE_CALLNONVIRTUALMETHOD(jlong,    Long,    T_LONG)
2038DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT)
2039DEFINE_CALLNONVIRTUALMETHOD(jdouble,  Double,  T_DOUBLE)
2040
2041
2042DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod);
2043DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV);
2044DT_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\
2054JNI_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;\
2071JNI_END
2072
2073// the runtime type of subword integral basic types is integer
2074DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN
2075                            , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2076                            HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))
2077DEFINE_CALLNONVIRTUALMETHOD(jbyte,    Byte,    T_BYTE
2078                            , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2079                            HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))
2080DEFINE_CALLNONVIRTUALMETHOD(jchar,    Char,    T_CHAR
2081                            , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2082                            HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))
2083DEFINE_CALLNONVIRTUALMETHOD(jshort,   Short,   T_SHORT
2084                            , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2085                            HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))
2086
2087DEFINE_CALLNONVIRTUALMETHOD(jobject,  Object,  T_OBJECT
2088                            , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2089                            HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))
2090DEFINE_CALLNONVIRTUALMETHOD(jint,     Int,     T_INT
2091                            , HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2092                            HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))
2093DEFINE_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))
2097DEFINE_CALLNONVIRTUALMETHOD(jfloat,   Float,   T_FLOAT
2098                            , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),
2099                            HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())
2100DEFINE_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\
2110JNI_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;\
2124JNI_END
2125
2126// the runtime type of subword integral basic types is integer
2127DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN
2128                            , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2129                            HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))
2130DEFINE_CALLNONVIRTUALMETHODV(jbyte,    Byte,    T_BYTE
2131                            , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2132                            HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))
2133DEFINE_CALLNONVIRTUALMETHODV(jchar,    Char,    T_CHAR
2134                            , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2135                            HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))
2136DEFINE_CALLNONVIRTUALMETHODV(jshort,   Short,   T_SHORT
2137                            , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2138                            HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))
2139
2140DEFINE_CALLNONVIRTUALMETHODV(jobject,  Object,  T_OBJECT
2141                            , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2142                            HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))
2143DEFINE_CALLNONVIRTUALMETHODV(jint,     Int,     T_INT
2144                            , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2145                            HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))
2146DEFINE_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))
2150DEFINE_CALLNONVIRTUALMETHODV(jfloat,   Float,   T_FLOAT
2151                            , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),
2152                            HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())
2153DEFINE_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\
2163JNI_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;\
2177JNI_END
2178
2179// the runtime type of subword integral basic types is integer
2180DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN
2181                            , HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2182                            HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))
2183DEFINE_CALLNONVIRTUALMETHODA(jbyte,    Byte,    T_BYTE
2184                            , HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2185                            HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))
2186DEFINE_CALLNONVIRTUALMETHODA(jchar,    Char,    T_CHAR
2187                            , HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2188                            HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))
2189DEFINE_CALLNONVIRTUALMETHODA(jshort,   Short,   T_SHORT
2190                            , HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2191                            HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))
2192
2193DEFINE_CALLNONVIRTUALMETHODA(jobject,  Object,  T_OBJECT
2194                            , HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2195                            HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))
2196DEFINE_CALLNONVIRTUALMETHODA(jint,     Int,     T_INT
2197                            , HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2198                            HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))
2199DEFINE_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))
2203DEFINE_CALLNONVIRTUALMETHODA(jfloat,   Float,   T_FLOAT
2204                            , HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2205                            HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())
2206DEFINE_CALLNONVIRTUALMETHODA(jdouble,  Double,  T_DOUBLE
2207                            , HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),
2208                            HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())
2209
2210DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod
2211                         , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());
2212DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV
2213                         , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());
2214DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA
2215                         , HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());
2216#endif /* USDT2 */
2217
2218JNI_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);
2236JNI_END
2237
2238
2239JNI_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);
2254JNI_END
2255
2256
2257JNI_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);
2270JNI_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\
2280JNI_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;\
2297JNI_END \
2298\
2299JNI_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;\
2312JNI_END \
2313\
2314JNI_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;\
2327JNI_END
2328
2329// the runtime type of subword integral basic types is integer
2330DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN)
2331DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE)
2332DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR)
2333DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT)
2334
2335DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT)
2336DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT)
2337DEFINE_CALLSTATICMETHOD(jlong,    Long,    T_LONG)
2338DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT)
2339DEFINE_CALLSTATICMETHOD(jdouble,  Double,  T_DOUBLE)
2340
2341
2342DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod);
2343DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV);
2344DT_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\
2354JNI_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;\
2371JNI_END
2372
2373// the runtime type of subword integral basic types is integer
2374DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN
2375                        , HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2376                        HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));
2377DEFINE_CALLSTATICMETHOD(jbyte,    Byte,    T_BYTE
2378                        , HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2379                        HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));
2380DEFINE_CALLSTATICMETHOD(jchar,    Char,    T_CHAR
2381                        , HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2382                        HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));
2383DEFINE_CALLSTATICMETHOD(jshort,   Short,   T_SHORT
2384                        , HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2385                        HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));
2386
2387DEFINE_CALLSTATICMETHOD(jobject,  Object,  T_OBJECT
2388                        , HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2389                        HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));
2390DEFINE_CALLSTATICMETHOD(jint,     Int,     T_INT
2391                        , HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2392                        HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));
2393DEFINE_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
2397DEFINE_CALLSTATICMETHOD(jfloat,   Float,   T_FLOAT
2398                        , HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),
2399                        HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());
2400DEFINE_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\
2410JNI_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;\
2428JNI_END
2429
2430// the runtime type of subword integral basic types is integer
2431DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN
2432                        , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2433                        HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));
2434DEFINE_CALLSTATICMETHODV(jbyte,    Byte,    T_BYTE
2435                        , HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2436                        HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));
2437DEFINE_CALLSTATICMETHODV(jchar,    Char,    T_CHAR
2438                        , HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2439                        HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));
2440DEFINE_CALLSTATICMETHODV(jshort,   Short,   T_SHORT
2441                        , HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2442                        HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));
2443
2444DEFINE_CALLSTATICMETHODV(jobject,  Object,  T_OBJECT
2445                        , HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2446                        HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));
2447DEFINE_CALLSTATICMETHODV(jint,     Int,     T_INT
2448                        , HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2449                        HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));
2450DEFINE_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
2454DEFINE_CALLSTATICMETHODV(jfloat,   Float,   T_FLOAT
2455                        , HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),
2456                        HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());
2457DEFINE_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\
2467JNI_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;\
2481JNI_END
2482
2483// the runtime type of subword integral basic types is integer
2484DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN
2485                        , HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2486                        HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));
2487DEFINE_CALLSTATICMETHODA(jbyte,    Byte,    T_BYTE
2488                        , HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2489                        HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));
2490DEFINE_CALLSTATICMETHODA(jchar,    Char,    T_CHAR
2491                        , HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2492                        HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));
2493DEFINE_CALLSTATICMETHODA(jshort,   Short,   T_SHORT
2494                        , HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2495                        HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));
2496
2497DEFINE_CALLSTATICMETHODA(jobject,  Object,  T_OBJECT
2498                        , HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2499                        HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));
2500DEFINE_CALLSTATICMETHODA(jint,     Int,     T_INT
2501                        , HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2502                        HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));
2503DEFINE_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
2507DEFINE_CALLSTATICMETHODA(jfloat,   Float,   T_FLOAT
2508                        , HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2509                        HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());
2510DEFINE_CALLSTATICMETHODA(jdouble,  Double,  T_DOUBLE
2511                        , HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),
2512                        HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());
2513
2514DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod
2515                         , HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());
2516DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV
2517                         , HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());
2518DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA
2519                         , HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());
2520#endif /* USDT2 */
2521
2522JNI_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);
2538JNI_END
2539
2540
2541JNI_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);
2554JNI_END
2555
2556
2557JNI_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);
2570JNI_END
2571
2572
2573//
2574// Accessing Fields
2575//
2576
2577
2578#ifndef USDT2
2579DT_RETURN_MARK_DECL(GetFieldID, jfieldID);
2580#else /* USDT2 */
2581DT_RETURN_MARK_DECL(GetFieldID, jfieldID
2582                    , HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));
2583#endif /* USDT2 */
2584
2585JNI_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;
2620JNI_END
2621
2622
2623JNI_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 */
2663HOTSPOT_JNI_GETOBJECTFIELD_RETURN(
2664                                  ret);
2665#endif /* USDT2 */
2666  return ret;
2667JNI_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\
2675JNI_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; \
2693JNI_END
2694
2695DEFINE_GETFIELD(jboolean, bool,   Boolean)
2696DEFINE_GETFIELD(jbyte,    byte,   Byte)
2697DEFINE_GETFIELD(jchar,    char,   Char)
2698DEFINE_GETFIELD(jshort,   short,  Short)
2699DEFINE_GETFIELD(jint,     int,    Int)
2700DEFINE_GETFIELD(jlong,    long,   Long)
2701DEFINE_GETFIELD(jfloat,   float,  Float)
2702DEFINE_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\
2712JNI_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; \
2730JNI_END
2731
2732DEFINE_GETFIELD(jboolean, bool,   Boolean
2733                , HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2734                HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))
2735DEFINE_GETFIELD(jbyte,    byte,   Byte
2736                , HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2737                HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))
2738DEFINE_GETFIELD(jchar,    char,   Char
2739                , HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2740                HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))
2741DEFINE_GETFIELD(jshort,   short,  Short
2742                , HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2743                HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))
2744DEFINE_GETFIELD(jint,     int,    Int
2745                , HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2746                HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))
2747DEFINE_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
2751DEFINE_GETFIELD(jfloat,   float,  Float
2752                , HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2753                HOTSPOT_JNI_GETFLOATFIELD_RETURN())
2754DEFINE_GETFIELD(jdouble,  double, Double
2755                , HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2756                HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())
2757#endif /* USDT2 */
2758
2759address jni_GetBooleanField_addr() {
2760  return (address)jni_GetBooleanField;
2761}
2762address jni_GetByteField_addr() {
2763  return (address)jni_GetByteField;
2764}
2765address jni_GetCharField_addr() {
2766  return (address)jni_GetCharField;
2767}
2768address jni_GetShortField_addr() {
2769  return (address)jni_GetShortField;
2770}
2771address jni_GetIntField_addr() {
2772  return (address)jni_GetIntField;
2773}
2774address jni_GetLongField_addr() {
2775  return (address)jni_GetLongField;
2776}
2777address jni_GetFloatField_addr() {
2778  return (address)jni_GetFloatField;
2779}
2780address jni_GetDoubleField_addr() {
2781  return (address)jni_GetDoubleField;
2782}
2783
2784JNI_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 */
2810JNI_END
2811
2812#ifndef USDT2
2813#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \
2814\
2815JNI_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);\
2836JNI_END
2837
2838DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z)
2839DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b)
2840DEFINE_SETFIELD(jchar,    char,   Char,    'C', c)
2841DEFINE_SETFIELD(jshort,   short,  Short,   'S', s)
2842DEFINE_SETFIELD(jint,     int,    Int,     'I', i)
2843DEFINE_SETFIELD(jlong,    long,   Long,    'J', j)
2844DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f)
2845DEFINE_SETFIELD(jdouble,  double, Double,  'D', d)
2846
2847#else /* USDT2 */
2848
2849#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \
2850                        , EntryProbe, ReturnProbe) \
2851\
2852JNI_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; \
2870JNI_END
2871
2872DEFINE_SETFIELD(jboolean, bool,   Boolean, 'Z', z
2873                , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2874                HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
2875DEFINE_SETFIELD(jbyte,    byte,   Byte,    'B', b
2876                , HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2877                HOTSPOT_JNI_SETBYTEFIELD_RETURN())
2878DEFINE_SETFIELD(jchar,    char,   Char,    'C', c
2879                , HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2880                HOTSPOT_JNI_SETCHARFIELD_RETURN())
2881DEFINE_SETFIELD(jshort,   short,  Short,   'S', s
2882                , HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2883                HOTSPOT_JNI_SETSHORTFIELD_RETURN())
2884DEFINE_SETFIELD(jint,     int,    Int,     'I', i
2885                , HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),
2886                HOTSPOT_JNI_SETINTFIELD_RETURN())
2887DEFINE_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
2891DEFINE_SETFIELD(jfloat,   float,  Float,   'F', f
2892                , HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),
2893                HOTSPOT_JNI_SETFLOATFIELD_RETURN())
2894DEFINE_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
2900DT_RETURN_MARK_DECL(ToReflectedField, jobject);
2901#else /* USDT2 */
2902DT_RETURN_MARK_DECL(ToReflectedField, jobject
2903                    , HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));
2904#endif /* USDT2 */
2905
2906JNI_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;
2938JNI_END
2939
2940
2941//
2942// Accessing Static Fields
2943//
2944#ifndef USDT2
2945DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);
2946#else /* USDT2 */
2947DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID
2948                    , HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));
2949#endif /* USDT2 */
2950
2951JNI_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;
2990JNI_END
2991
2992
2993JNI_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;
3019JNI_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\
3026JNI_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;\
3041JNI_END
3042
3043DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean)
3044DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte)
3045DEFINE_GETSTATICFIELD(jchar,    char,   Char)
3046DEFINE_GETSTATICFIELD(jshort,   short,  Short)
3047DEFINE_GETSTATICFIELD(jint,     int,    Int)
3048DEFINE_GETSTATICFIELD(jlong,    long,   Long)
3049DEFINE_GETSTATICFIELD(jfloat,   float,  Float)
3050DEFINE_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\
3060JNI_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;\
3075JNI_END
3076
3077DEFINE_GETSTATICFIELD(jboolean, bool,   Boolean
3078                      , HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))
3079DEFINE_GETSTATICFIELD(jbyte,    byte,   Byte
3080                      , HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref)   )
3081DEFINE_GETSTATICFIELD(jchar,    char,   Char
3082                      , HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),    HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref)   )
3083DEFINE_GETSTATICFIELD(jshort,   short,  Short
3084                      , HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref)  )
3085DEFINE_GETSTATICFIELD(jint,     int,    Int
3086                      , HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),     HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref)    )
3087DEFINE_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
3090DEFINE_GETSTATICFIELD(jfloat,   float,  Float
3091                      , HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),   HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN()          )
3092DEFINE_GETSTATICFIELD(jdouble,  double, Double
3093                      , HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),  HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN()         )
3094#endif /* USDT2 */
3095
3096JNI_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 */
3120JNI_END
3121
3122
3123#ifndef USDT2
3124#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \
3125\
3126JNI_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);\
3144JNI_END
3145
3146DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z)
3147DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b)
3148DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c)
3149DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s)
3150DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i)
3151DEFINE_SETSTATICFIELD(jlong,    long,   Long,    'J', j)
3152DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f)
3153DEFINE_SETSTATICFIELD(jdouble,  double, Double,  'D', d)
3154
3155#else /* USDT2 */
3156
3157#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \
3158                              , EntryProbe, ReturnProbe) \
3159\
3160JNI_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;\
3175JNI_END
3176
3177DEFINE_SETSTATICFIELD(jboolean, bool,   Boolean, 'Z', z
3178                      , HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),
3179                      HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())
3180DEFINE_SETSTATICFIELD(jbyte,    byte,   Byte,    'B', b
3181                      , HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3182                      HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())
3183DEFINE_SETSTATICFIELD(jchar,    char,   Char,    'C', c
3184                      , HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3185                      HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())
3186DEFINE_SETSTATICFIELD(jshort,   short,  Short,   'S', s
3187                      , HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3188                      HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())
3189DEFINE_SETSTATICFIELD(jint,     int,    Int,     'I', i
3190                      , HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),
3191                      HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())
3192DEFINE_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
3196DEFINE_SETSTATICFIELD(jfloat,   float,  Float,   'F', f
3197                      , HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),
3198                      HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())
3199DEFINE_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
3211DT_RETURN_MARK_DECL(NewString, jstring);
3212#else /* USDT2 */
3213DT_RETURN_MARK_DECL(NewString, jstring
3214                    , HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));
3215#endif /* USDT2 */
3216
3217JNI_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;
3230JNI_END
3231
3232
3233JNI_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;
3249JNI_END
3250
3251
3252JNI_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;
3281JNI_END
3282
3283
3284JNI_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 */
3304JNI_END
3305
3306
3307// UTF Interface
3308
3309#ifndef USDT2
3310DT_RETURN_MARK_DECL(NewStringUTF, jstring);
3311#else /* USDT2 */
3312DT_RETURN_MARK_DECL(NewStringUTF, jstring
3313                    , HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));
3314#endif /* USDT2 */
3315
3316JNI_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;
3330JNI_END
3331
3332
3333JNI_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;
3349JNI_END
3350
3351
3352JNI_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;
3372JNI_END
3373
3374
3375JNI_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 */
3389HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN(
3390);
3391#endif /* USDT2 */
3392JNI_END
3393
3394
3395JNI_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;
3413JNI_END
3414
3415
3416//
3417// Object Array Operations
3418//
3419
3420#ifndef USDT2
3421DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);
3422#else /* USDT2 */
3423DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray
3424                    , HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));
3425#endif /* USDT2 */
3426
3427JNI_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;
3450JNI_END
3451
3452#ifndef USDT2
3453DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);
3454#else /* USDT2 */
3455DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject
3456                    , HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));
3457#endif /* USDT2 */
3458
3459JNI_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  }
3478JNI_END
3479
3480#ifndef USDT2
3481DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);
3482#else /* USDT2 */
3483DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement
3484                         , HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());
3485#endif /* USDT2 */
3486
3487JNI_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  }
3510JNI_END
3511
3512
3513#ifndef USDT2
3514#define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \
3515\
3516  DT_RETURN_MARK_DECL(New##Result##Array, Return); \
3517\
3518JNI_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;\
3528JNI_END
3529
3530DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean)
3531DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte)
3532DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short)
3533DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char)
3534DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int)
3535DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long)
3536DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float)
3537DEFINE_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\
3547JNI_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;\
3557JNI_END
3558
3559DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray,   Boolean,
3560                      HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),
3561                      HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))
3562DEFINE_NEWSCALARARRAY(jbyteArray,    new_byteArray,   Byte,
3563                      HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),
3564                      HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))
3565DEFINE_NEWSCALARARRAY(jshortArray,   new_shortArray,  Short,
3566                      HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),
3567                      HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))
3568DEFINE_NEWSCALARARRAY(jcharArray,    new_charArray,   Char,
3569                      HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),
3570                      HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))
3571DEFINE_NEWSCALARARRAY(jintArray,     new_intArray,    Int,
3572                      HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),
3573                      HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))
3574DEFINE_NEWSCALARARRAY(jlongArray,    new_longArray,   Long,
3575                      HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),
3576                      HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))
3577DEFINE_NEWSCALARARRAY(jfloatArray,   new_singleArray, Float,
3578                      HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),
3579                      HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))
3580DEFINE_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
3587static 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\
3604JNI_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; \
3625JNI_END
3626
3627DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
3628DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
3629DEFINE_GETSCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
3630DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
3631DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
3632DEFINE_GETSCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
3633DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
3634DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
3635
3636#else /* USDT2 */
3637
3638#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \
3639                                      , EntryProbe, ReturnProbe) \
3640\
3641JNI_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; \
3662JNI_END
3663
3664DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
3665                              , HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3666                              HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))
3667DEFINE_GETSCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
3668                              , HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3669                              HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))
3670DEFINE_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))
3673DEFINE_GETSCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
3674                              , HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),
3675                              HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))
3676DEFINE_GETSCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
3677                              , HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3678                              HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))
3679DEFINE_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
3683DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
3684                              , HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),
3685                              HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))
3686DEFINE_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\
3694JNI_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);\
3710JNI_END
3711
3712DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)
3713DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte)
3714DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short)
3715DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char)
3716DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int)
3717DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long)
3718DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float)
3719DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE,  jdouble,  Double,  double)
3720
3721#else /* USDT2 */
3722
3723#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \
3724                                          , EntryProbe, ReturnProbe);\
3725\
3726JNI_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; \
3742JNI_END
3743
3744DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool
3745                                  , HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
3746                                  HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())
3747DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE,    jbyte,    Byte,    byte
3748                                  , HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),
3749                                  HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())
3750DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT,   jshort,   Short,   short
3751                                  ,  HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
3752                                  HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())
3753DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR,    jchar,    Char,    char
3754                                  ,  HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),
3755                                  HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())
3756DEFINE_RELEASESCALARARRAYELEMENTS(T_INT,     jint,     Int,     int
3757                                  , HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),
3758                                  HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())
3759DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG,    jlong,    Long,    long
3760                                  , HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),
3761                                  HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())
3762DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT,   jfloat,   Float,   float
3763                                  , HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),
3764                                  HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())
3765DEFINE_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\
3774JNI_ENTRY(void, \
3775jni_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  } \
3791JNI_END
3792
3793DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool)
3794DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte)
3795DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short)
3796DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char)
3797DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int)
3798DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long)
3799DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float)
3800DEFINE_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\
3809JNI_ENTRY(void, \
3810jni_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  } \
3826JNI_END
3827
3828DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool
3829                            , HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3830                            HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());
3831DEFINE_GETSCALARARRAYREGION(T_BYTE,    jbyte,   Byte,    byte
3832                            ,  HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
3833                            HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());
3834DEFINE_GETSCALARARRAYREGION(T_SHORT,   jshort,  Short,   short
3835                            , HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3836                            HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());
3837DEFINE_GETSCALARARRAYREGION(T_CHAR,    jchar,   Char,    char
3838                            ,  HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),
3839                            HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());
3840DEFINE_GETSCALARARRAYREGION(T_INT,     jint,    Int,     int
3841                            , HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),
3842                            HOTSPOT_JNI_GETINTARRAYREGION_RETURN());
3843DEFINE_GETSCALARARRAYREGION(T_LONG,    jlong,   Long,    long
3844                            ,  HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3845                            HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());
3846DEFINE_GETSCALARARRAYREGION(T_FLOAT,   jfloat,  Float,   float
3847                            , HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3848                            HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());
3849DEFINE_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\
3858JNI_ENTRY(void, \
3859jni_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  } \
3875JNI_END
3876
3877DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool)
3878DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte)
3879DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short)
3880DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char)
3881DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int)
3882DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long)
3883DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float)
3884DEFINE_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\
3893JNI_ENTRY(void, \
3894jni_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  } \
3910JNI_END
3911
3912DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool
3913                            , HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),
3914                            HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())
3915DEFINE_SETSCALARARRAYREGION(T_BYTE,    jbyte,    Byte,    byte
3916                            , HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),
3917                            HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())
3918DEFINE_SETSCALARARRAYREGION(T_SHORT,   jshort,   Short,   short
3919                            , HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3920                            HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())
3921DEFINE_SETSCALARARRAYREGION(T_CHAR,    jchar,    Char,    char
3922                            , HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),
3923                            HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())
3924DEFINE_SETSCALARARRAYREGION(T_INT,     jint,     Int,     int
3925                            , HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),
3926                            HOTSPOT_JNI_SETINTARRAYREGION_RETURN())
3927DEFINE_SETSCALARARRAYREGION(T_LONG,    jlong,    Long,    long
3928                            , HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),
3929                            HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
3930DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float
3931                            , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3932                            HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
3933DEFINE_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.
3947static 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
3983static 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
4020DT_RETURN_MARK_DECL(RegisterNatives, jint);
4021#else /* USDT2 */
4022DT_RETURN_MARK_DECL(RegisterNatives, jint
4023                    , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));
4024#endif /* USDT2 */
4025
4026JNI_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;
4068JNI_END
4069
4070
4071JNI_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;
4097JNI_END
4098
4099//
4100// Monitor functions
4101//
4102
4103#ifndef USDT2
4104DT_RETURN_MARK_DECL(MonitorEnter, jint);
4105#else /* USDT2 */
4106DT_RETURN_MARK_DECL(MonitorEnter, jint
4107                    , HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));
4108#endif /* USDT2 */
4109
4110JNI_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;
4129JNI_END
4130
4131#ifndef USDT2
4132DT_RETURN_MARK_DECL(MonitorExit, jint);
4133#else /* USDT2 */
4134DT_RETURN_MARK_DECL(MonitorExit, jint
4135                    , HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));
4136#endif /* USDT2 */
4137
4138JNI_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;
4158JNI_END
4159
4160//
4161// Extensions
4162//
4163
4164#ifndef USDT2
4165DT_VOID_RETURN_MARK_DECL(GetStringRegion);
4166#else /* USDT2 */
4167DT_VOID_RETURN_MARK_DECL(GetStringRegion
4168                         , HOTSPOT_JNI_GETSTRINGREGION_RETURN());
4169#endif /* USDT2 */
4170
4171JNI_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  }
4191JNI_END
4192
4193#ifndef USDT2
4194DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);
4195#else /* USDT2 */
4196DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion
4197                         , HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());
4198#endif /* USDT2 */
4199
4200JNI_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  }
4228JNI_END
4229
4230
4231JNI_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;
4259JNI_END
4260
4261
4262JNI_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 */
4275HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(
4276);
4277#endif /* USDT2 */
4278JNI_END
4279
4280
4281JNI_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;
4310JNI_END
4311
4312
4313JNI_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 */
4326HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(
4327);
4328#endif /* USDT2 */
4329JNI_END
4330
4331
4332JNI_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;
4349JNI_END
4350
4351// Must be JNI_ENTRY (with HandleMark)
4352JNI_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 */
4367JNI_END
4368
4369
4370JNI_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;
4387JNI_END
4388
4389
4390// Initialization state for three routines below relating to
4391// java.nio.DirectBuffers
4392static          jint directBufferSupportInitializeStarted = 0;
4393static volatile jint directBufferSupportInitializeEnded   = 0;
4394static volatile jint directBufferSupportInitializeFailed  = 0;
4395static jclass    bufferClass                 = NULL;
4396static jclass    directBufferClass           = NULL;
4397static jclass    directByteBufferClass       = NULL;
4398static jmethodID directByteBufferConstructor = NULL;
4399static jfieldID  directBufferAddressField    = NULL;
4400static jfieldID  bufferCapacityField         = NULL;
4401
4402static 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.
4417JNI_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}
4424JNI_END
4425
4426
4427static 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
4471extern "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
4512DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);
4513#else /* USDT2 */
4514DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*
4515                    , HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));
4516#endif /* USDT2 */
4517
4518extern "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
4548DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);
4549#else /* USDT2 */
4550DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong
4551                    , HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));
4552#endif /* USDT2 */
4553
4554extern "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
4590JNI_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;
4605JNI_END
4606
4607extern struct JavaVM_ main_vm;
4608
4609JNI_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;
4625JNI_END
4626
4627// Structure containing all jni functions
4628struct 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.
4916void 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
4925void 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
4972struct 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
4982struct JNINativeInterface_* jni_functions_nocheck() {
4983  return &jni_NativeInterface;
4984}
4985
4986
4987// Invocation API
4988
4989
4990// Forward declaration
4991extern const struct JNIInvokeInterface_ jni_InvokeInterface;
4992
4993// Global invocation API vars
4994volatile jint vm_created = 0;
4995// Indicate whether it is safe to recreate VM
4996volatile jint safe_to_recreate_vm = 1;
4997struct JavaVM_ main_vm = {&jni_InvokeInterface};
4998
4999
5000#define JAVASTACKSIZE (400 * 1024)    /* Default size of a thread java stack */
5001enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };
5002
5003#ifndef USDT2
5004HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*);
5005DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint);
5006#else /* USDT2 */
5007DT_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
5042void 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
5052HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);
5053DT_RETURN_MARK_DECL(CreateJavaVM, jint);
5054#else /* USDT2 */
5055DT_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
5156HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \
5157  JavaVM**, jsize, jsize*);
5158HS_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
5186extern "C" {
5187
5188#ifndef USDT2
5189DT_RETURN_MARK_DECL(DestroyJavaVM, jint);
5190#else /* USDT2 */
5191DT_RETURN_MARK_DECL(DestroyJavaVM, jint
5192                    , HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));
5193#endif /* USDT2 */
5194
5195jint 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
5237static 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
5346jint 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
5375jint 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
5435DT_RETURN_MARK_DECL(GetEnv, jint);
5436#else /* USDT2 */
5437DT_RETURN_MARK_DECL(GetEnv, jint
5438                    , HOTSPOT_JNI_GETENV_RETURN(_ret_ref));
5439#endif /* USDT2 */
5440
5441jint 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
5501jint 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
5532const 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};
5543