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