Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/prims/jni.cpp
32285 views
/*1* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2012 Red Hat, Inc.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "ci/ciReplay.hpp"27#include "classfile/altHashing.hpp"28#include "classfile/classLoader.hpp"29#include "classfile/javaClasses.hpp"30#include "classfile/symbolTable.hpp"31#include "classfile/systemDictionary.hpp"32#include "classfile/vmSymbols.hpp"33#include "interpreter/linkResolver.hpp"34#include "jfr/jfrEvents.hpp"35#include "jfr/support/jfrThreadId.hpp"36#include "utilities/macros.hpp"37#include "utilities/ostream.hpp"38#if INCLUDE_ALL_GCS39#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"40#endif // INCLUDE_ALL_GCS41#include "memory/allocation.hpp"42#include "memory/allocation.inline.hpp"43#include "memory/gcLocker.inline.hpp"44#include "memory/oopFactory.hpp"45#include "memory/universe.inline.hpp"46#include "oops/instanceKlass.hpp"47#include "oops/instanceOop.hpp"48#include "oops/markOop.hpp"49#include "oops/method.hpp"50#include "oops/objArrayKlass.hpp"51#include "oops/objArrayOop.hpp"52#include "oops/oop.inline.hpp"53#include "oops/symbol.hpp"54#include "oops/typeArrayKlass.hpp"55#include "oops/typeArrayOop.hpp"56#include "prims/jni.h"57#include "prims/jniCheck.hpp"58#include "prims/jniExport.hpp"59#include "prims/jniFastGetField.hpp"60#include "prims/jvm.h"61#include "prims/jvm_misc.hpp"62#include "prims/jvmtiExport.hpp"63#include "prims/jvmtiThreadState.hpp"64#include "runtime/compilationPolicy.hpp"65#include "runtime/fieldDescriptor.hpp"66#include "runtime/fprofiler.hpp"67#include "runtime/handles.inline.hpp"68#include "runtime/interfaceSupport.hpp"69#include "runtime/java.hpp"70#include "runtime/javaCalls.hpp"71#include "runtime/jfieldIDWorkaround.hpp"72#include "runtime/orderAccess.inline.hpp"73#include "runtime/reflection.hpp"74#include "runtime/sharedRuntime.hpp"75#include "runtime/signature.hpp"76#include "runtime/thread.inline.hpp"77#include "runtime/vm_operations.hpp"78#include "services/memTracker.hpp"79#include "services/runtimeService.hpp"80#include "utilities/defaultStream.hpp"81#include "utilities/dtrace.hpp"82#include "utilities/events.hpp"83#include "utilities/histogram.hpp"84#ifdef TARGET_OS_FAMILY_linux85# include "os_linux.inline.hpp"86#endif87#ifdef TARGET_OS_FAMILY_solaris88# include "os_solaris.inline.hpp"89#endif90#ifdef TARGET_OS_FAMILY_windows91# include "os_windows.inline.hpp"92#endif93#ifdef TARGET_OS_FAMILY_bsd94# include "os_bsd.inline.hpp"95#endif9697static jint CurrentVersion = JNI_VERSION_1_8;9899100// The DT_RETURN_MARK macros create a scoped object to fire the dtrace101// '-return' probe regardless of the return path is taken out of the function.102// Methods that have multiple return paths use this to avoid having to103// instrument each return path. Methods that use CHECK or THROW must use this104// since those macros can cause an immedate uninstrumented return.105//106// In order to get the return value, a reference to the variable containing107// the return value must be passed to the contructor of the object, and108// the return value must be set before return (since the mark object has109// a reference to it).110//111// Example:112// DT_RETURN_MARK_DECL(SomeFunc, int);113// JNI_ENTRY(int, SomeFunc, ...)114// int return_value = 0;115// DT_RETURN_MARK(SomeFunc, int, (const int&)return_value);116// foo(CHECK_0)117// return_value = 5;118// return return_value;119// JNI_END120#ifndef USDT2121#define DT_RETURN_MARK_DECL(name, type) \122HS_DTRACE_PROBE_DECL1(hotspot_jni, name##__return, type); \123DTRACE_ONLY( \124class DTraceReturnProbeMark_##name { \125public: \126const type& _ret_ref; \127DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {} \128~DTraceReturnProbeMark_##name() { \129HS_DTRACE_PROBE1(hotspot_jni, name##__return, _ret_ref); \130} \131} \132)133// Void functions are simpler since there's no return value134#define DT_VOID_RETURN_MARK_DECL(name) \135HS_DTRACE_PROBE_DECL0(hotspot_jni, name##__return); \136DTRACE_ONLY( \137class DTraceReturnProbeMark_##name { \138public: \139~DTraceReturnProbeMark_##name() { \140HS_DTRACE_PROBE0(hotspot_jni, name##__return); \141} \142} \143)144145#else /* USDT2 */146147#define DT_RETURN_MARK_DECL(name, type, probe) \148DTRACE_ONLY( \149class DTraceReturnProbeMark_##name { \150public: \151const type& _ret_ref; \152DTraceReturnProbeMark_##name(const type& v) : _ret_ref(v) {} \153~DTraceReturnProbeMark_##name() { \154probe; \155} \156} \157)158// Void functions are simpler since there's no return value159#define DT_VOID_RETURN_MARK_DECL(name, probe) \160DTRACE_ONLY( \161class DTraceReturnProbeMark_##name { \162public: \163~DTraceReturnProbeMark_##name() { \164probe; \165} \166} \167)168#endif /* USDT2 */169170// Place these macros in the function to mark the return. Non-void171// functions need the type and address of the return value.172#define DT_RETURN_MARK(name, type, ref) \173DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark(ref) )174#define DT_VOID_RETURN_MARK(name) \175DTRACE_ONLY( DTraceReturnProbeMark_##name dtrace_return_mark )176177178// Use these to select distinct code for floating-point vs. non-floating point179// situations. Used from within common macros where we need slightly180// different behavior for Float/Double181#define FP_SELECT_Boolean(intcode, fpcode) intcode182#define FP_SELECT_Byte(intcode, fpcode) intcode183#define FP_SELECT_Char(intcode, fpcode) intcode184#define FP_SELECT_Short(intcode, fpcode) intcode185#define FP_SELECT_Object(intcode, fpcode) intcode186#define FP_SELECT_Int(intcode, fpcode) intcode187#define FP_SELECT_Long(intcode, fpcode) intcode188#define FP_SELECT_Float(intcode, fpcode) fpcode189#define FP_SELECT_Double(intcode, fpcode) fpcode190#define FP_SELECT(TypeName, intcode, fpcode) \191FP_SELECT_##TypeName(intcode, fpcode)192193#define COMMA ,194195// Choose DT_RETURN_MARK macros based on the type: float/double -> void196// (dtrace doesn't do FP yet)197#ifndef USDT2198#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type) \199FP_SELECT(TypeName, \200DT_RETURN_MARK_DECL(name, type), DT_VOID_RETURN_MARK_DECL(name) )201#else /* USDT2 */202#define DT_RETURN_MARK_DECL_FOR(TypeName, name, type, probe) \203FP_SELECT(TypeName, \204DT_RETURN_MARK_DECL(name, type, probe), DT_VOID_RETURN_MARK_DECL(name, probe) )205#endif /* USDT2 */206#define DT_RETURN_MARK_FOR(TypeName, name, type, ref) \207FP_SELECT(TypeName, \208DT_RETURN_MARK(name, type, ref), DT_VOID_RETURN_MARK(name) )209210211// out-of-line helpers for class jfieldIDWorkaround:212213bool jfieldIDWorkaround::is_valid_jfieldID(Klass* k, jfieldID id) {214if (jfieldIDWorkaround::is_instance_jfieldID(k, id)) {215uintptr_t as_uint = (uintptr_t) id;216intptr_t offset = raw_instance_offset(id);217if (is_checked_jfieldID(id)) {218if (!klass_hash_ok(k, id)) {219return false;220}221}222return InstanceKlass::cast(k)->contains_field_offset(offset);223} else {224JNIid* result = (JNIid*) id;225#ifdef ASSERT226return result != NULL && result->is_static_field_id();227#else228return result != NULL;229#endif230}231}232233234intptr_t jfieldIDWorkaround::encode_klass_hash(Klass* k, intptr_t offset) {235if (offset <= small_offset_mask) {236Klass* field_klass = k;237Klass* super_klass = field_klass->super();238// With compressed oops the most super class with nonstatic fields would239// be the owner of fields embedded in the header.240while (InstanceKlass::cast(super_klass)->has_nonstatic_fields() &&241InstanceKlass::cast(super_klass)->contains_field_offset(offset)) {242field_klass = super_klass; // super contains the field also243super_klass = field_klass->super();244}245debug_only(No_Safepoint_Verifier nosafepoint;)246uintptr_t klass_hash = field_klass->identity_hash();247return ((klass_hash & klass_mask) << klass_shift) | checked_mask_in_place;248} else {249#if 0250#ifndef PRODUCT251{252ResourceMark rm;253warning("VerifyJNIFields: long offset %d in %s", offset, k->external_name());254}255#endif256#endif257return 0;258}259}260261bool jfieldIDWorkaround::klass_hash_ok(Klass* k, jfieldID id) {262uintptr_t as_uint = (uintptr_t) id;263intptr_t klass_hash = (as_uint >> klass_shift) & klass_mask;264do {265debug_only(No_Safepoint_Verifier nosafepoint;)266// Could use a non-blocking query for identity_hash here...267if ((k->identity_hash() & klass_mask) == klass_hash)268return true;269k = k->super();270} while (k != NULL);271return false;272}273274void jfieldIDWorkaround::verify_instance_jfieldID(Klass* k, jfieldID id) {275guarantee(jfieldIDWorkaround::is_instance_jfieldID(k, id), "must be an instance field" );276uintptr_t as_uint = (uintptr_t) id;277intptr_t offset = raw_instance_offset(id);278if (VerifyJNIFields) {279if (is_checked_jfieldID(id)) {280guarantee(klass_hash_ok(k, id),281"Bug in native code: jfieldID class must match object");282} else {283#if 0284#ifndef PRODUCT285if (Verbose) {286ResourceMark rm;287warning("VerifyJNIFields: unverified offset %d for %s", offset, k->external_name());288}289#endif290#endif291}292}293guarantee(InstanceKlass::cast(k)->contains_field_offset(offset),294"Bug in native code: jfieldID offset must address interior of object");295}296297// Wrapper to trace JNI functions298299#ifdef ASSERT300Histogram* JNIHistogram;301static volatile jint JNIHistogram_lock = 0;302303class JNITraceWrapper : public StackObj {304public:305JNITraceWrapper(const char* format, ...) ATTRIBUTE_PRINTF(2, 3) {306if (TraceJNICalls) {307va_list ap;308va_start(ap, format);309tty->print("JNI ");310tty->vprint_cr(format, ap);311va_end(ap);312}313}314};315316class JNIHistogramElement : public HistogramElement {317public:318JNIHistogramElement(const char* name);319};320321JNIHistogramElement::JNIHistogramElement(const char* elementName) {322_name = elementName;323uintx count = 0;324325while (Atomic::cmpxchg(1, &JNIHistogram_lock, 0) != 0) {326while (OrderAccess::load_acquire(&JNIHistogram_lock) != 0) {327count +=1;328if ( (WarnOnStalledSpinLock > 0)329&& (count % WarnOnStalledSpinLock == 0)) {330warning("JNIHistogram_lock seems to be stalled");331}332}333}334335336if(JNIHistogram == NULL)337JNIHistogram = new Histogram("JNI Call Counts",100);338339JNIHistogram->add_element(this);340Atomic::dec(&JNIHistogram_lock);341}342343#define JNICountWrapper(arg) \344static JNIHistogramElement* e = new JNIHistogramElement(arg); \345/* There is a MT-race condition in VC++. So we need to make sure that that e has been initialized */ \346if (e != NULL) e->increment_count()347#define JNIWrapper(arg) JNICountWrapper(arg); JNITraceWrapper(arg)348#else349#define JNIWrapper(arg)350#endif351352353// Implementation of JNI entries354355#ifndef USDT2356DT_RETURN_MARK_DECL(DefineClass, jclass);357#else /* USDT2 */358DT_RETURN_MARK_DECL(DefineClass, jclass359, HOTSPOT_JNI_DEFINECLASS_RETURN(_ret_ref));360#endif /* USDT2 */361362JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderRef,363const jbyte *buf, jsize bufLen))364JNIWrapper("DefineClass");365366#ifndef USDT2367DTRACE_PROBE5(hotspot_jni, DefineClass__entry,368env, name, loaderRef, buf, bufLen);369#else /* USDT2 */370HOTSPOT_JNI_DEFINECLASS_ENTRY(371env, (char*) name, loaderRef, (char*) buf, bufLen);372#endif /* USDT2 */373jclass cls = NULL;374DT_RETURN_MARK(DefineClass, jclass, (const jclass&)cls);375376TempNewSymbol class_name = NULL;377// Since exceptions can be thrown, class initialization can take place378// if name is NULL no check for class name in .class stream has to be made.379if (name != NULL) {380const int str_len = (int)strlen(name);381if (str_len > Symbol::max_length()) {382// It's impossible to create this class; the name cannot fit383// into the constant pool.384THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);385}386class_name = SymbolTable::new_symbol(name, CHECK_NULL);387}388ResourceMark rm(THREAD);389ClassFileStream st((u1*) buf, bufLen, NULL);390Handle class_loader (THREAD, JNIHandles::resolve(loaderRef));391392if (UsePerfData && !class_loader.is_null()) {393// check whether the current caller thread holds the lock or not.394// If not, increment the corresponding counter395if (ObjectSynchronizer::396query_lock_ownership((JavaThread*)THREAD, class_loader) !=397ObjectSynchronizer::owner_self) {398ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();399}400}401Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,402Handle(), &st, true,403CHECK_NULL);404405if (TraceClassResolution && k != NULL) {406trace_class_resolution(k);407}408409cls = (jclass)JNIHandles::make_local(410env, k->java_mirror());411return cls;412JNI_END413414415416static bool first_time_FindClass = true;417418#ifndef USDT2419DT_RETURN_MARK_DECL(FindClass, jclass);420#else /* USDT2 */421DT_RETURN_MARK_DECL(FindClass, jclass422, HOTSPOT_JNI_FINDCLASS_RETURN(_ret_ref));423#endif /* USDT2 */424425JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name))426JNIWrapper("FindClass");427#ifndef USDT2428DTRACE_PROBE2(hotspot_jni, FindClass__entry, env, name);429#else /* USDT2 */430HOTSPOT_JNI_FINDCLASS_ENTRY(431env, (char *)name);432#endif /* USDT2 */433434jclass result = NULL;435DT_RETURN_MARK(FindClass, jclass, (const jclass&)result);436437// Remember if we are the first invocation of jni_FindClass438bool first_time = first_time_FindClass;439first_time_FindClass = false;440441// Sanity check the name: it cannot be null or larger than the maximum size442// name we can fit in the constant pool.443if (name == NULL || (int)strlen(name) > Symbol::max_length()) {444THROW_MSG_0(vmSymbols::java_lang_NoClassDefFoundError(), name);445}446447//%note jni_3448Handle loader;449Handle protection_domain;450// Find calling class451instanceKlassHandle k (THREAD, thread->security_get_caller_class(0));452if (k.not_null()) {453loader = Handle(THREAD, k->class_loader());454// Special handling to make sure JNI_OnLoad and JNI_OnUnload are executed455// in the correct class context.456if (loader.is_null() &&457k->name() == vmSymbols::java_lang_ClassLoader_NativeLibrary()) {458JavaValue result(T_OBJECT);459JavaCalls::call_static(&result, k,460vmSymbols::getFromClass_name(),461vmSymbols::void_class_signature(),462thread);463if (HAS_PENDING_EXCEPTION) {464Handle ex(thread, thread->pending_exception());465CLEAR_PENDING_EXCEPTION;466THROW_HANDLE_0(ex);467}468oop mirror = (oop) result.get_jobject();469loader = Handle(THREAD,470InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->class_loader());471protection_domain = Handle(THREAD,472InstanceKlass::cast(java_lang_Class::as_Klass(mirror))->protection_domain());473}474} else {475// We call ClassLoader.getSystemClassLoader to obtain the system class loader.476loader = Handle(THREAD, SystemDictionary::java_system_loader());477}478479TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);480result = find_class_from_class_loader(env, sym, true, loader,481protection_domain, true, thread);482483if (TraceClassResolution && result != NULL) {484trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));485}486487// If we were the first invocation of jni_FindClass, we enable compilation again488// rather than just allowing invocation counter to overflow and decay.489// Controlled by flag DelayCompilationDuringStartup.490if (first_time && !CompileTheWorld)491CompilationPolicy::completed_vm_startup();492493return result;494JNI_END495496#ifndef USDT2497DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID);498#else /* USDT2 */499DT_RETURN_MARK_DECL(FromReflectedMethod, jmethodID500, HOTSPOT_JNI_FROMREFLECTEDMETHOD_RETURN((uintptr_t)_ret_ref));501#endif /* USDT2 */502503JNI_ENTRY(jmethodID, jni_FromReflectedMethod(JNIEnv *env, jobject method))504JNIWrapper("FromReflectedMethod");505#ifndef USDT2506DTRACE_PROBE2(hotspot_jni, FromReflectedMethod__entry, env, method);507#else /* USDT2 */508HOTSPOT_JNI_FROMREFLECTEDMETHOD_ENTRY(509env, method);510#endif /* USDT2 */511jmethodID ret = NULL;512DT_RETURN_MARK(FromReflectedMethod, jmethodID, (const jmethodID&)ret);513514// method is a handle to a java.lang.reflect.Method object515oop reflected = JNIHandles::resolve_non_null(method);516oop mirror = NULL;517int slot = 0;518519if (reflected->klass() == SystemDictionary::reflect_Constructor_klass()) {520mirror = java_lang_reflect_Constructor::clazz(reflected);521slot = java_lang_reflect_Constructor::slot(reflected);522} else {523assert(reflected->klass() == SystemDictionary::reflect_Method_klass(), "wrong type");524mirror = java_lang_reflect_Method::clazz(reflected);525slot = java_lang_reflect_Method::slot(reflected);526}527Klass* k = java_lang_Class::as_Klass(mirror);528529KlassHandle k1(THREAD, k);530// Make sure class is initialized before handing id's out to methods531k1()->initialize(CHECK_NULL);532Method* m = InstanceKlass::cast(k1())->method_with_idnum(slot);533ret = m==NULL? NULL : m->jmethod_id(); // return NULL if reflected method deleted534return ret;535JNI_END536537#ifndef USDT2538DT_RETURN_MARK_DECL(FromReflectedField, jfieldID);539#else /* USDT2 */540DT_RETURN_MARK_DECL(FromReflectedField, jfieldID541, HOTSPOT_JNI_FROMREFLECTEDFIELD_RETURN((uintptr_t)_ret_ref));542#endif /* USDT2 */543544JNI_ENTRY(jfieldID, jni_FromReflectedField(JNIEnv *env, jobject field))545JNIWrapper("FromReflectedField");546#ifndef USDT2547DTRACE_PROBE2(hotspot_jni, FromReflectedField__entry, env, field);548#else /* USDT2 */549HOTSPOT_JNI_FROMREFLECTEDFIELD_ENTRY(550env, field);551#endif /* USDT2 */552jfieldID ret = NULL;553DT_RETURN_MARK(FromReflectedField, jfieldID, (const jfieldID&)ret);554555// field is a handle to a java.lang.reflect.Field object556oop reflected = JNIHandles::resolve_non_null(field);557oop mirror = java_lang_reflect_Field::clazz(reflected);558Klass* k = java_lang_Class::as_Klass(mirror);559int slot = java_lang_reflect_Field::slot(reflected);560int modifiers = java_lang_reflect_Field::modifiers(reflected);561562KlassHandle k1(THREAD, k);563// Make sure class is initialized before handing id's out to fields564k1()->initialize(CHECK_NULL);565566// First check if this is a static field567if (modifiers & JVM_ACC_STATIC) {568intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );569JNIid* id = InstanceKlass::cast(k1())->jni_id_for(offset);570assert(id != NULL, "corrupt Field object");571debug_only(id->set_is_static_field_id();)572// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*573ret = jfieldIDWorkaround::to_static_jfieldID(id);574return ret;575}576577// The slot is the index of the field description in the field-array578// The jfieldID is the offset of the field within the object579// It may also have hash bits for k, if VerifyJNIFields is turned on.580intptr_t offset = InstanceKlass::cast(k1())->field_offset( slot );581assert(InstanceKlass::cast(k1())->contains_field_offset(offset), "stay within object");582ret = jfieldIDWorkaround::to_instance_jfieldID(k1(), offset);583return ret;584JNI_END585586#ifndef USDT2587DT_RETURN_MARK_DECL(ToReflectedMethod, jobject);588#else /* USDT2 */589DT_RETURN_MARK_DECL(ToReflectedMethod, jobject590, HOTSPOT_JNI_TOREFLECTEDMETHOD_RETURN(_ret_ref));591#endif /* USDT2 */592593JNI_ENTRY(jobject, jni_ToReflectedMethod(JNIEnv *env, jclass cls, jmethodID method_id, jboolean isStatic))594JNIWrapper("ToReflectedMethod");595#ifndef USDT2596DTRACE_PROBE4(hotspot_jni, ToReflectedMethod__entry, env, cls, method_id, isStatic);597#else /* USDT2 */598HOTSPOT_JNI_TOREFLECTEDMETHOD_ENTRY(599env, cls, (uintptr_t) method_id, isStatic);600#endif /* USDT2 */601jobject ret = NULL;602DT_RETURN_MARK(ToReflectedMethod, jobject, (const jobject&)ret);603604methodHandle m (THREAD, Method::resolve_jmethod_id(method_id));605assert(m->is_static() == (isStatic != 0), "jni_ToReflectedMethod access flags doesn't match");606oop reflection_method;607if (m->is_initializer()) {608reflection_method = Reflection::new_constructor(m, CHECK_NULL);609} else {610reflection_method = Reflection::new_method(m, UseNewReflection, false, CHECK_NULL);611}612ret = JNIHandles::make_local(env, reflection_method);613return ret;614JNI_END615616#ifndef USDT2617DT_RETURN_MARK_DECL(GetSuperclass, jclass);618#else /* USDT2 */619DT_RETURN_MARK_DECL(GetSuperclass, jclass620, HOTSPOT_JNI_GETSUPERCLASS_RETURN(_ret_ref));621#endif /* USDT2 */622623JNI_ENTRY(jclass, jni_GetSuperclass(JNIEnv *env, jclass sub))624JNIWrapper("GetSuperclass");625#ifndef USDT2626DTRACE_PROBE2(hotspot_jni, GetSuperclass__entry, env, sub);627#else /* USDT2 */628HOTSPOT_JNI_GETSUPERCLASS_ENTRY(629env, sub);630#endif /* USDT2 */631jclass obj = NULL;632DT_RETURN_MARK(GetSuperclass, jclass, (const jclass&)obj);633634oop mirror = JNIHandles::resolve_non_null(sub);635// primitive classes return NULL636if (java_lang_Class::is_primitive(mirror)) return NULL;637638// Rules of Class.getSuperClass as implemented by KLass::java_super:639// arrays return Object640// interfaces return NULL641// proper classes return Klass::super()642Klass* k = java_lang_Class::as_Klass(mirror);643if (k->is_interface()) return NULL;644645// return mirror for superclass646Klass* super = k->java_super();647// super2 is the value computed by the compiler's getSuperClass intrinsic:648debug_only(Klass* super2 = ( k->oop_is_array()649? SystemDictionary::Object_klass()650: k->super() ) );651assert(super == super2,652"java_super computation depends on interface, array, other super");653obj = (super == NULL) ? NULL : (jclass) JNIHandles::make_local(super->java_mirror());654return obj;655JNI_END656657JNI_QUICK_ENTRY(jboolean, jni_IsAssignableFrom(JNIEnv *env, jclass sub, jclass super))658JNIWrapper("IsSubclassOf");659#ifndef USDT2660DTRACE_PROBE3(hotspot_jni, IsAssignableFrom__entry, env, sub, super);661#else /* USDT2 */662HOTSPOT_JNI_ISASSIGNABLEFROM_ENTRY(663env, sub, super);664#endif /* USDT2 */665oop sub_mirror = JNIHandles::resolve_non_null(sub);666oop super_mirror = JNIHandles::resolve_non_null(super);667if (java_lang_Class::is_primitive(sub_mirror) ||668java_lang_Class::is_primitive(super_mirror)) {669jboolean ret = (sub_mirror == super_mirror);670#ifndef USDT2671DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);672#else /* USDT2 */673HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(674ret);675#endif /* USDT2 */676return ret;677}678Klass* sub_klass = java_lang_Class::as_Klass(sub_mirror);679Klass* super_klass = java_lang_Class::as_Klass(super_mirror);680assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");681jboolean ret = sub_klass->is_subtype_of(super_klass) ?682JNI_TRUE : JNI_FALSE;683#ifndef USDT2684DTRACE_PROBE1(hotspot_jni, IsAssignableFrom__return, ret);685#else /* USDT2 */686HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(687ret);688#endif /* USDT2 */689return ret;690JNI_END691692#ifndef USDT2693DT_RETURN_MARK_DECL(Throw, jint);694#else /* USDT2 */695DT_RETURN_MARK_DECL(Throw, jint696, HOTSPOT_JNI_THROW_RETURN(_ret_ref));697#endif /* USDT2 */698699JNI_ENTRY(jint, jni_Throw(JNIEnv *env, jthrowable obj))700JNIWrapper("Throw");701#ifndef USDT2702DTRACE_PROBE2(hotspot_jni, Throw__entry, env, obj);703#else /* USDT2 */704HOTSPOT_JNI_THROW_ENTRY(705env, obj);706#endif /* USDT2 */707jint ret = JNI_OK;708DT_RETURN_MARK(Throw, jint, (const jint&)ret);709710THROW_OOP_(JNIHandles::resolve(obj), JNI_OK);711ShouldNotReachHere();712return 0; // Mute compiler.713JNI_END714715#ifndef USDT2716DT_RETURN_MARK_DECL(ThrowNew, jint);717#else /* USDT2 */718DT_RETURN_MARK_DECL(ThrowNew, jint719, HOTSPOT_JNI_THROWNEW_RETURN(_ret_ref));720#endif /* USDT2 */721722JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message))723JNIWrapper("ThrowNew");724#ifndef USDT2725DTRACE_PROBE3(hotspot_jni, ThrowNew__entry, env, clazz, message);726#else /* USDT2 */727HOTSPOT_JNI_THROWNEW_ENTRY(728env, clazz, (char *) message);729#endif /* USDT2 */730jint ret = JNI_OK;731DT_RETURN_MARK(ThrowNew, jint, (const jint&)ret);732733InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));734Symbol* name = k->name();735Handle class_loader (THREAD, k->class_loader());736Handle protection_domain (THREAD, k->protection_domain());737THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK);738ShouldNotReachHere();739return 0; // Mute compiler.740JNI_END741742743// JNI functions only transform a pending async exception to a synchronous744// exception in ExceptionOccurred and ExceptionCheck calls, since745// delivering an async exception in other places won't change the native746// code's control flow and would be harmful when native code further calls747// JNI functions with a pending exception. Async exception is also checked748// during the call, so ExceptionOccurred/ExceptionCheck won't return749// false but deliver the async exception at the very end during750// state transition.751752static void jni_check_async_exceptions(JavaThread *thread) {753assert(thread == Thread::current(), "must be itself");754thread->check_and_handle_async_exceptions();755}756757JNI_ENTRY_NO_PRESERVE(jthrowable, jni_ExceptionOccurred(JNIEnv *env))758JNIWrapper("ExceptionOccurred");759#ifndef USDT2760DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__entry, env);761#else /* USDT2 */762HOTSPOT_JNI_EXCEPTIONOCCURRED_ENTRY(763env);764#endif /* USDT2 */765jni_check_async_exceptions(thread);766oop exception = thread->pending_exception();767jthrowable ret = (jthrowable) JNIHandles::make_local(env, exception);768#ifndef USDT2769DTRACE_PROBE1(hotspot_jni, ExceptionOccurred__return, ret);770#else /* USDT2 */771HOTSPOT_JNI_EXCEPTIONOCCURRED_RETURN(772ret);773#endif /* USDT2 */774return ret;775JNI_END776777778JNI_ENTRY_NO_PRESERVE(void, jni_ExceptionDescribe(JNIEnv *env))779JNIWrapper("ExceptionDescribe");780#ifndef USDT2781DTRACE_PROBE1(hotspot_jni, ExceptionDescribe__entry, env);782#else /* USDT2 */783HOTSPOT_JNI_EXCEPTIONDESCRIBE_ENTRY(784env);785#endif /* USDT2 */786if (thread->has_pending_exception()) {787Handle ex(thread, thread->pending_exception());788thread->clear_pending_exception();789if (ex->is_a(SystemDictionary::ThreadDeath_klass())) {790// Don't print anything if we are being killed.791} else {792jio_fprintf(defaultStream::error_stream(), "Exception ");793if (thread != NULL && thread->threadObj() != NULL) {794ResourceMark rm(THREAD);795jio_fprintf(defaultStream::error_stream(),796"in thread \"%s\" ", thread->get_thread_name());797}798if (ex->is_a(SystemDictionary::Throwable_klass())) {799JavaValue result(T_VOID);800JavaCalls::call_virtual(&result,801ex,802KlassHandle(THREAD,803SystemDictionary::Throwable_klass()),804vmSymbols::printStackTrace_name(),805vmSymbols::void_method_signature(),806THREAD);807// If an exception is thrown in the call it gets thrown away. Not much808// we can do with it. The native code that calls this, does not check809// for the exception - hence, it might still be in the thread when DestroyVM gets810// called, potentially causing a few asserts to trigger - since no pending exception811// is expected.812CLEAR_PENDING_EXCEPTION;813} else {814ResourceMark rm(THREAD);815jio_fprintf(defaultStream::error_stream(),816". Uncaught exception of type %s.",817ex->klass()->external_name());818}819}820}821#ifndef USDT2822DTRACE_PROBE(hotspot_jni, ExceptionDescribe__return);823#else /* USDT2 */824HOTSPOT_JNI_EXCEPTIONDESCRIBE_RETURN(825);826#endif /* USDT2 */827JNI_END828829830JNI_QUICK_ENTRY(void, jni_ExceptionClear(JNIEnv *env))831JNIWrapper("ExceptionClear");832#ifndef USDT2833DTRACE_PROBE1(hotspot_jni, ExceptionClear__entry, env);834#else /* USDT2 */835HOTSPOT_JNI_EXCEPTIONCLEAR_ENTRY(836env);837#endif /* USDT2 */838839// The jni code might be using this API to clear java thrown exception.840// So just mark jvmti thread exception state as exception caught.841JvmtiThreadState *state = JavaThread::current()->jvmti_thread_state();842if (state != NULL && state->is_exception_detected()) {843state->set_exception_caught();844}845thread->clear_pending_exception();846#ifndef USDT2847DTRACE_PROBE(hotspot_jni, ExceptionClear__return);848#else /* USDT2 */849HOTSPOT_JNI_EXCEPTIONCLEAR_RETURN(850);851#endif /* USDT2 */852JNI_END853854855JNI_ENTRY(void, jni_FatalError(JNIEnv *env, const char *msg))856JNIWrapper("FatalError");857#ifndef USDT2858DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);859#else /* USDT2 */860HOTSPOT_JNI_FATALERROR_ENTRY(861env, (char *) msg);862#endif /* USDT2 */863tty->print_cr("FATAL ERROR in native method: %s", msg);864thread->print_stack();865os::abort(); // Dump core and abort866JNI_END867868869JNI_ENTRY(jint, jni_PushLocalFrame(JNIEnv *env, jint capacity))870JNIWrapper("PushLocalFrame");871#ifndef USDT2872DTRACE_PROBE2(hotspot_jni, PushLocalFrame__entry, env, capacity);873#else /* USDT2 */874HOTSPOT_JNI_PUSHLOCALFRAME_ENTRY(875env, capacity);876#endif /* USDT2 */877//%note jni_11878if (capacity < 0 ||879((MaxJNILocalCapacity > 0) && (capacity > MaxJNILocalCapacity))) {880#ifndef USDT2881DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, JNI_ERR);882#else /* USDT2 */883HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(884(uint32_t)JNI_ERR);885#endif /* USDT2 */886return JNI_ERR;887}888JNIHandleBlock* old_handles = thread->active_handles();889JNIHandleBlock* new_handles = JNIHandleBlock::allocate_block(thread);890assert(new_handles != NULL, "should not be NULL");891new_handles->set_pop_frame_link(old_handles);892thread->set_active_handles(new_handles);893jint ret = JNI_OK;894#ifndef USDT2895DTRACE_PROBE1(hotspot_jni, PushLocalFrame__return, ret);896#else /* USDT2 */897HOTSPOT_JNI_PUSHLOCALFRAME_RETURN(898ret);899#endif /* USDT2 */900return ret;901JNI_END902903904JNI_ENTRY(jobject, jni_PopLocalFrame(JNIEnv *env, jobject result))905JNIWrapper("PopLocalFrame");906#ifndef USDT2907DTRACE_PROBE2(hotspot_jni, PopLocalFrame__entry, env, result);908#else /* USDT2 */909HOTSPOT_JNI_POPLOCALFRAME_ENTRY(910env, result);911#endif /* USDT2 */912//%note jni_11913Handle result_handle(thread, JNIHandles::resolve(result));914JNIHandleBlock* old_handles = thread->active_handles();915JNIHandleBlock* new_handles = old_handles->pop_frame_link();916if (new_handles != NULL) {917// As a sanity check we only release the handle blocks if the pop_frame_link is not NULL.918// This way code will still work if PopLocalFrame is called without a corresponding919// PushLocalFrame call. Note that we set the pop_frame_link to NULL explicitly, otherwise920// the release_block call will release the blocks.921thread->set_active_handles(new_handles);922old_handles->set_pop_frame_link(NULL); // clear link we won't release new_handles below923JNIHandleBlock::release_block(old_handles, thread); // may block924result = JNIHandles::make_local(thread, result_handle());925}926#ifndef USDT2927DTRACE_PROBE1(hotspot_jni, PopLocalFrame__return, result);928#else /* USDT2 */929HOTSPOT_JNI_POPLOCALFRAME_RETURN(930result);931#endif /* USDT2 */932return result;933JNI_END934935936JNI_ENTRY(jobject, jni_NewGlobalRef(JNIEnv *env, jobject ref))937JNIWrapper("NewGlobalRef");938#ifndef USDT2939DTRACE_PROBE2(hotspot_jni, NewGlobalRef__entry, env, ref);940#else /* USDT2 */941HOTSPOT_JNI_NEWGLOBALREF_ENTRY(942env, ref);943#endif /* USDT2 */944Handle ref_handle(thread, JNIHandles::resolve(ref));945jobject ret = JNIHandles::make_global(ref_handle);946#ifndef USDT2947DTRACE_PROBE1(hotspot_jni, NewGlobalRef__return, ret);948#else /* USDT2 */949HOTSPOT_JNI_NEWGLOBALREF_RETURN(950ret);951#endif /* USDT2 */952return ret;953JNI_END954955// Must be JNI_ENTRY (with HandleMark)956JNI_ENTRY_NO_PRESERVE(void, jni_DeleteGlobalRef(JNIEnv *env, jobject ref))957JNIWrapper("DeleteGlobalRef");958#ifndef USDT2959DTRACE_PROBE2(hotspot_jni, DeleteGlobalRef__entry, env, ref);960#else /* USDT2 */961HOTSPOT_JNI_DELETEGLOBALREF_ENTRY(962env, ref);963#endif /* USDT2 */964JNIHandles::destroy_global(ref);965#ifndef USDT2966DTRACE_PROBE(hotspot_jni, DeleteGlobalRef__return);967#else /* USDT2 */968HOTSPOT_JNI_DELETEGLOBALREF_RETURN(969);970#endif /* USDT2 */971JNI_END972973JNI_QUICK_ENTRY(void, jni_DeleteLocalRef(JNIEnv *env, jobject obj))974JNIWrapper("DeleteLocalRef");975#ifndef USDT2976DTRACE_PROBE2(hotspot_jni, DeleteLocalRef__entry, env, obj);977#else /* USDT2 */978HOTSPOT_JNI_DELETELOCALREF_ENTRY(979env, obj);980#endif /* USDT2 */981JNIHandles::destroy_local(obj);982#ifndef USDT2983DTRACE_PROBE(hotspot_jni, DeleteLocalRef__return);984#else /* USDT2 */985HOTSPOT_JNI_DELETELOCALREF_RETURN(986);987#endif /* USDT2 */988JNI_END989990JNI_QUICK_ENTRY(jboolean, jni_IsSameObject(JNIEnv *env, jobject r1, jobject r2))991JNIWrapper("IsSameObject");992#ifndef USDT2993DTRACE_PROBE3(hotspot_jni, IsSameObject__entry, env, r1, r2);994#else /* USDT2 */995HOTSPOT_JNI_ISSAMEOBJECT_ENTRY(996env, r1, r2);997#endif /* USDT2 */998oop a = JNIHandles::resolve(r1);999oop b = JNIHandles::resolve(r2);1000jboolean ret = (a == b) ? JNI_TRUE : JNI_FALSE;1001#ifndef USDT21002DTRACE_PROBE1(hotspot_jni, IsSameObject__return, ret);1003#else /* USDT2 */1004HOTSPOT_JNI_ISSAMEOBJECT_RETURN(1005ret);1006#endif /* USDT2 */1007return ret;1008JNI_END100910101011JNI_ENTRY(jobject, jni_NewLocalRef(JNIEnv *env, jobject ref))1012JNIWrapper("NewLocalRef");1013#ifndef USDT21014DTRACE_PROBE2(hotspot_jni, NewLocalRef__entry, env, ref);1015#else /* USDT2 */1016HOTSPOT_JNI_NEWLOCALREF_ENTRY(1017env, ref);1018#endif /* USDT2 */1019jobject ret = JNIHandles::make_local(env, JNIHandles::resolve(ref));1020#ifndef USDT21021DTRACE_PROBE1(hotspot_jni, NewLocalRef__return, ret);1022#else /* USDT2 */1023HOTSPOT_JNI_NEWLOCALREF_RETURN(1024ret);1025#endif /* USDT2 */1026return ret;1027JNI_END10281029JNI_LEAF(jint, jni_EnsureLocalCapacity(JNIEnv *env, jint capacity))1030JNIWrapper("EnsureLocalCapacity");1031#ifndef USDT21032DTRACE_PROBE2(hotspot_jni, EnsureLocalCapacity__entry, env, capacity);1033#else /* USDT2 */1034HOTSPOT_JNI_ENSURELOCALCAPACITY_ENTRY(1035env, capacity);1036#endif /* USDT2 */1037jint ret;1038if (capacity >= 0 &&1039((MaxJNILocalCapacity <= 0) || (capacity <= MaxJNILocalCapacity))) {1040ret = JNI_OK;1041} else {1042ret = JNI_ERR;1043}1044#ifndef USDT21045DTRACE_PROBE1(hotspot_jni, EnsureLocalCapacity__return, ret);1046#else /* USDT2 */1047HOTSPOT_JNI_ENSURELOCALCAPACITY_RETURN(1048ret);1049#endif /* USDT2 */1050return ret;1051JNI_END10521053// Return the Handle Type1054JNI_LEAF(jobjectRefType, jni_GetObjectRefType(JNIEnv *env, jobject obj))1055JNIWrapper("GetObjectRefType");1056#ifndef USDT21057DTRACE_PROBE2(hotspot_jni, GetObjectRefType__entry, env, obj);1058#else /* USDT2 */1059HOTSPOT_JNI_GETOBJECTREFTYPE_ENTRY(1060env, obj);1061#endif /* USDT2 */1062jobjectRefType ret;1063if (JNIHandles::is_local_handle(thread, obj) ||1064JNIHandles::is_frame_handle(thread, obj))1065ret = JNILocalRefType;1066else if (JNIHandles::is_global_handle(obj))1067ret = JNIGlobalRefType;1068else if (JNIHandles::is_weak_global_handle(obj))1069ret = JNIWeakGlobalRefType;1070else1071ret = JNIInvalidRefType;1072#ifndef USDT21073DTRACE_PROBE1(hotspot_jni, GetObjectRefType__return, ret);1074#else /* USDT2 */1075HOTSPOT_JNI_GETOBJECTREFTYPE_RETURN(1076(void *) ret);1077#endif /* USDT2 */1078return ret;1079JNI_END108010811082class JNI_ArgumentPusher : public SignatureIterator {1083protected:1084JavaCallArguments* _arguments;10851086virtual void get_bool () = 0;1087virtual void get_char () = 0;1088virtual void get_short () = 0;1089virtual void get_byte () = 0;1090virtual void get_int () = 0;1091virtual void get_long () = 0;1092virtual void get_float () = 0;1093virtual void get_double () = 0;1094virtual void get_object () = 0;10951096JNI_ArgumentPusher(Symbol* signature) : SignatureIterator(signature) {1097this->_return_type = T_ILLEGAL;1098_arguments = NULL;1099}11001101public:1102virtual void iterate( uint64_t fingerprint ) = 0;11031104void set_java_argument_object(JavaCallArguments *arguments) { _arguments = arguments; }11051106inline void do_bool() { if (!is_return_type()) get_bool(); }1107inline void do_char() { if (!is_return_type()) get_char(); }1108inline void do_short() { if (!is_return_type()) get_short(); }1109inline void do_byte() { if (!is_return_type()) get_byte(); }1110inline void do_int() { if (!is_return_type()) get_int(); }1111inline void do_long() { if (!is_return_type()) get_long(); }1112inline void do_float() { if (!is_return_type()) get_float(); }1113inline void do_double() { if (!is_return_type()) get_double(); }1114inline void do_object(int begin, int end) { if (!is_return_type()) get_object(); }1115inline void do_array(int begin, int end) { if (!is_return_type()) get_object(); } // do_array uses get_object -- there is no get_array1116inline void do_void() { }11171118JavaCallArguments* arguments() { return _arguments; }1119void push_receiver(Handle h) { _arguments->push_oop(h); }1120};112111221123class JNI_ArgumentPusherVaArg : public JNI_ArgumentPusher {1124protected:1125va_list _ap;11261127inline void get_bool() {1128// Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and1129// 0 to JNI_FALSE. Boolean return values from native are normalized the same in1130// TemplateInterpreterGenerator::generate_result_handler_for and1131// SharedRuntime::generate_native_wrapper.1132jboolean b = va_arg(_ap, jint);1133_arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));1134}1135inline void get_char() { _arguments->push_int(va_arg(_ap, jint)); } // char is coerced to int when using va_arg1136inline void get_short() { _arguments->push_int(va_arg(_ap, jint)); } // short is coerced to int when using va_arg1137inline void get_byte() { _arguments->push_int(va_arg(_ap, jint)); } // byte is coerced to int when using va_arg1138inline void get_int() { _arguments->push_int(va_arg(_ap, jint)); }11391140// each of these paths is exercized by the various jck Call[Static,Nonvirtual,][Void,Int,..]Method[A,V,] tests11411142inline void get_long() { _arguments->push_long(va_arg(_ap, jlong)); }1143inline void get_float() { _arguments->push_float((jfloat)va_arg(_ap, jdouble)); } // float is coerced to double w/ va_arg1144inline void get_double() { _arguments->push_double(va_arg(_ap, jdouble)); }1145inline void get_object() { _arguments->push_jobject(va_arg(_ap, jobject)); }11461147inline void set_ap(va_list rap) {1148#ifdef va_copy1149va_copy(_ap, rap);1150#elif defined (__va_copy)1151__va_copy(_ap, rap);1152#else1153_ap = rap;1154#endif1155}11561157public:1158JNI_ArgumentPusherVaArg(Symbol* signature, va_list rap)1159: JNI_ArgumentPusher(signature) {1160set_ap(rap);1161}1162JNI_ArgumentPusherVaArg(jmethodID method_id, va_list rap)1163: JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {1164set_ap(rap);1165}11661167// Optimized path if we have the bitvector form of signature1168void iterate( uint64_t fingerprint ) {1169if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate();// Must be too many arguments1170else {1171_return_type = (BasicType)((fingerprint >> static_feature_size) &1172result_feature_mask);11731174assert(fingerprint, "Fingerprint should not be 0");1175fingerprint = fingerprint >> (static_feature_size + result_feature_size);1176while ( 1 ) {1177switch ( fingerprint & parameter_feature_mask ) {1178case bool_parm:1179get_bool();1180break;1181case char_parm:1182get_char();1183break;1184case short_parm:1185get_short();1186break;1187case byte_parm:1188get_byte();1189break;1190case int_parm:1191get_int();1192break;1193case obj_parm:1194get_object();1195break;1196case long_parm:1197get_long();1198break;1199case float_parm:1200get_float();1201break;1202case double_parm:1203get_double();1204break;1205case done_parm:1206return;1207break;1208default:1209ShouldNotReachHere();1210break;1211}1212fingerprint >>= parameter_feature_size;1213}1214}1215}1216};121712181219class JNI_ArgumentPusherArray : public JNI_ArgumentPusher {1220protected:1221const jvalue *_ap;12221223inline void get_bool() {1224// Normalize boolean arguments from native code by converting 1-255 to JNI_TRUE and1225// 0 to JNI_FALSE. Boolean return values from native are normalized the same in1226// TemplateInterpreterGenerator::generate_result_handler_for and1227// SharedRuntime::generate_native_wrapper.1228jboolean b = (_ap++)->z;1229_arguments->push_int((jint)(b == 0 ? JNI_FALSE : JNI_TRUE));1230}1231inline void get_char() { _arguments->push_int((jint)(_ap++)->c); }1232inline void get_short() { _arguments->push_int((jint)(_ap++)->s); }1233inline void get_byte() { _arguments->push_int((jint)(_ap++)->b); }1234inline void get_int() { _arguments->push_int((jint)(_ap++)->i); }12351236inline void get_long() { _arguments->push_long((_ap++)->j); }1237inline void get_float() { _arguments->push_float((_ap++)->f); }1238inline void get_double() { _arguments->push_double((_ap++)->d);}1239inline void get_object() { _arguments->push_jobject((_ap++)->l); }12401241inline void set_ap(const jvalue *rap) { _ap = rap; }12421243public:1244JNI_ArgumentPusherArray(Symbol* signature, const jvalue *rap)1245: JNI_ArgumentPusher(signature) {1246set_ap(rap);1247}1248JNI_ArgumentPusherArray(jmethodID method_id, const jvalue *rap)1249: JNI_ArgumentPusher(Method::resolve_jmethod_id(method_id)->signature()) {1250set_ap(rap);1251}12521253// Optimized path if we have the bitvector form of signature1254void iterate( uint64_t fingerprint ) {1255if ( fingerprint == UCONST64(-1) ) SignatureIterator::iterate(); // Must be too many arguments1256else {1257_return_type = (BasicType)((fingerprint >> static_feature_size) &1258result_feature_mask);1259assert(fingerprint, "Fingerprint should not be 0");1260fingerprint = fingerprint >> (static_feature_size + result_feature_size);1261while ( 1 ) {1262switch ( fingerprint & parameter_feature_mask ) {1263case bool_parm:1264get_bool();1265break;1266case char_parm:1267get_char();1268break;1269case short_parm:1270get_short();1271break;1272case byte_parm:1273get_byte();1274break;1275case int_parm:1276get_int();1277break;1278case obj_parm:1279get_object();1280break;1281case long_parm:1282get_long();1283break;1284case float_parm:1285get_float();1286break;1287case double_parm:1288get_double();1289break;1290case done_parm:1291return;1292break;1293default:1294ShouldNotReachHere();1295break;1296}1297fingerprint >>= parameter_feature_size;1298}1299}1300}1301};130213031304enum JNICallType {1305JNI_STATIC,1306JNI_VIRTUAL,1307JNI_NONVIRTUAL1308};1309131013111312static void jni_invoke_static(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {1313methodHandle method(THREAD, Method::resolve_jmethod_id(method_id));13141315// Create object to hold arguments for the JavaCall, and associate it with1316// the jni parser1317ResourceMark rm(THREAD);1318int number_of_parameters = method->size_of_parameters();1319JavaCallArguments java_args(number_of_parameters);1320args->set_java_argument_object(&java_args);13211322assert(method->is_static(), "method should be static");13231324// Fill out JavaCallArguments object1325args->iterate( Fingerprinter(method).fingerprint() );1326// Initialize result type1327result->set_type(args->get_ret_type());13281329// Invoke the method. Result is returned as oop.1330JavaCalls::call(result, method, &java_args, CHECK);13311332// Convert result1333if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {1334result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));1335}1336}133713381339static void jni_invoke_nonstatic(JNIEnv *env, JavaValue* result, jobject receiver, JNICallType call_type, jmethodID method_id, JNI_ArgumentPusher *args, TRAPS) {1340oop recv = JNIHandles::resolve(receiver);1341if (recv == NULL) {1342THROW(vmSymbols::java_lang_NullPointerException());1343}1344Handle h_recv(THREAD, recv);13451346int number_of_parameters;1347Method* selected_method;1348{1349Method* m = Method::resolve_jmethod_id(method_id);1350number_of_parameters = m->size_of_parameters();1351Klass* holder = m->method_holder();1352if (call_type != JNI_VIRTUAL) {1353selected_method = m;1354} else if (!m->has_itable_index()) {1355// non-interface call -- for that little speed boost, don't handlize1356debug_only(No_Safepoint_Verifier nosafepoint;)1357// jni_GetMethodID makes sure class is linked and initialized1358// so m should have a valid vtable index.1359assert(m->valid_vtable_index(), "no valid vtable index");1360int vtbl_index = m->vtable_index();1361if (vtbl_index != Method::nonvirtual_vtable_index) {1362Klass* k = h_recv->klass();1363// k might be an arrayKlassOop but all vtables start at1364// the same place. The cast is to avoid virtual call and assertion.1365InstanceKlass *ik = (InstanceKlass*)k;1366selected_method = ik->method_at_vtable(vtbl_index);1367} else {1368// final method1369selected_method = m;1370}1371} else {1372// interface call1373KlassHandle h_holder(THREAD, holder);13741375int itbl_index = m->itable_index();1376Klass* k = h_recv->klass();1377selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK);1378}1379}13801381methodHandle method(THREAD, selected_method);13821383// Create object to hold arguments for the JavaCall, and associate it with1384// the jni parser1385ResourceMark rm(THREAD);1386JavaCallArguments java_args(number_of_parameters);1387args->set_java_argument_object(&java_args);13881389// handle arguments1390assert(!method->is_static(), "method should not be static");1391args->push_receiver(h_recv); // Push jobject handle13921393// Fill out JavaCallArguments object1394args->iterate( Fingerprinter(method).fingerprint() );1395// Initialize result type1396result->set_type(args->get_ret_type());13971398// Invoke the method. Result is returned as oop.1399JavaCalls::call(result, method, &java_args, CHECK);14001401// Convert result1402if (result->get_type() == T_OBJECT || result->get_type() == T_ARRAY) {1403result->set_jobject(JNIHandles::make_local(env, (oop) result->get_jobject()));1404}1405}140614071408static instanceOop alloc_object(jclass clazz, TRAPS) {1409KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));1410k()->check_valid_for_instantiation(false, CHECK_NULL);1411InstanceKlass::cast(k())->initialize(CHECK_NULL);1412instanceOop ih = InstanceKlass::cast(k())->allocate_instance(THREAD);1413return ih;1414}14151416#ifndef USDT21417DT_RETURN_MARK_DECL(AllocObject, jobject);1418#else /* USDT2 */1419DT_RETURN_MARK_DECL(AllocObject, jobject1420, HOTSPOT_JNI_ALLOCOBJECT_RETURN(_ret_ref));1421#endif /* USDT2 */14221423JNI_ENTRY(jobject, jni_AllocObject(JNIEnv *env, jclass clazz))1424JNIWrapper("AllocObject");14251426#ifndef USDT21427DTRACE_PROBE2(hotspot_jni, AllocObject__entry, env, clazz);1428#else /* USDT2 */1429HOTSPOT_JNI_ALLOCOBJECT_ENTRY(1430env, clazz);1431#endif /* USDT2 */1432jobject ret = NULL;1433DT_RETURN_MARK(AllocObject, jobject, (const jobject&)ret);14341435instanceOop i = alloc_object(clazz, CHECK_NULL);1436ret = JNIHandles::make_local(env, i);1437return ret;1438JNI_END14391440#ifndef USDT21441DT_RETURN_MARK_DECL(NewObjectA, jobject);1442#else /* USDT2 */1443DT_RETURN_MARK_DECL(NewObjectA, jobject1444, HOTSPOT_JNI_NEWOBJECTA_RETURN(_ret_ref));1445#endif /* USDT2 */14461447JNI_ENTRY(jobject, jni_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args))1448JNIWrapper("NewObjectA");1449#ifndef USDT21450DTRACE_PROBE3(hotspot_jni, NewObjectA__entry, env, clazz, methodID);1451#else /* USDT2 */1452HOTSPOT_JNI_NEWOBJECTA_ENTRY(1453env, clazz, (uintptr_t) methodID);1454#endif /* USDT2 */1455jobject obj = NULL;1456DT_RETURN_MARK(NewObjectA, jobject, (const jobject)obj);14571458instanceOop i = alloc_object(clazz, CHECK_NULL);1459obj = JNIHandles::make_local(env, i);1460JavaValue jvalue(T_VOID);1461JNI_ArgumentPusherArray ap(methodID, args);1462jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);1463return obj;1464JNI_END14651466#ifndef USDT21467DT_RETURN_MARK_DECL(NewObjectV, jobject);1468#else /* USDT2 */1469DT_RETURN_MARK_DECL(NewObjectV, jobject1470, HOTSPOT_JNI_NEWOBJECTV_RETURN(_ret_ref));1471#endif /* USDT2 */14721473JNI_ENTRY(jobject, jni_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args))1474JNIWrapper("NewObjectV");1475#ifndef USDT21476DTRACE_PROBE3(hotspot_jni, NewObjectV__entry, env, clazz, methodID);1477#else /* USDT2 */1478HOTSPOT_JNI_NEWOBJECTV_ENTRY(1479env, clazz, (uintptr_t) methodID);1480#endif /* USDT2 */1481jobject obj = NULL;1482DT_RETURN_MARK(NewObjectV, jobject, (const jobject&)obj);14831484instanceOop i = alloc_object(clazz, CHECK_NULL);1485obj = JNIHandles::make_local(env, i);1486JavaValue jvalue(T_VOID);1487JNI_ArgumentPusherVaArg ap(methodID, args);1488jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);1489return obj;1490JNI_END14911492#ifndef USDT21493DT_RETURN_MARK_DECL(NewObject, jobject);1494#else /* USDT2 */1495DT_RETURN_MARK_DECL(NewObject, jobject1496, HOTSPOT_JNI_NEWOBJECT_RETURN(_ret_ref));1497#endif /* USDT2 */14981499JNI_ENTRY(jobject, jni_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...))1500JNIWrapper("NewObject");1501#ifndef USDT21502DTRACE_PROBE3(hotspot_jni, NewObject__entry, env, clazz, methodID);1503#else /* USDT2 */1504HOTSPOT_JNI_NEWOBJECT_ENTRY(1505env, clazz, (uintptr_t) methodID);1506#endif /* USDT2 */1507jobject obj = NULL;1508DT_RETURN_MARK(NewObject, jobject, (const jobject&)obj);15091510instanceOop i = alloc_object(clazz, CHECK_NULL);1511obj = JNIHandles::make_local(env, i);1512va_list args;1513va_start(args, methodID);1514JavaValue jvalue(T_VOID);1515JNI_ArgumentPusherVaArg ap(methodID, args);1516jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_NULL);1517va_end(args);1518return obj;1519JNI_END152015211522JNI_ENTRY(jclass, jni_GetObjectClass(JNIEnv *env, jobject obj))1523JNIWrapper("GetObjectClass");1524#ifndef USDT21525DTRACE_PROBE2(hotspot_jni, GetObjectClass__entry, env, obj);1526#else /* USDT2 */1527HOTSPOT_JNI_GETOBJECTCLASS_ENTRY(1528env, obj);1529#endif /* USDT2 */1530Klass* k = JNIHandles::resolve_non_null(obj)->klass();1531jclass ret =1532(jclass) JNIHandles::make_local(env, k->java_mirror());1533#ifndef USDT21534DTRACE_PROBE1(hotspot_jni, GetObjectClass__return, ret);1535#else /* USDT2 */1536HOTSPOT_JNI_GETOBJECTCLASS_RETURN(1537ret);1538#endif /* USDT2 */1539return ret;1540JNI_END15411542JNI_QUICK_ENTRY(jboolean, jni_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz))1543JNIWrapper("IsInstanceOf");1544#ifndef USDT21545DTRACE_PROBE3(hotspot_jni, IsInstanceOf__entry, env, obj, clazz);1546#else /* USDT2 */1547HOTSPOT_JNI_ISINSTANCEOF_ENTRY(1548env, obj, clazz);1549#endif /* USDT2 */1550jboolean ret = JNI_TRUE;1551if (obj != NULL) {1552ret = JNI_FALSE;1553Klass* k = java_lang_Class::as_Klass(1554JNIHandles::resolve_non_null(clazz));1555if (k != NULL) {1556ret = JNIHandles::resolve_non_null(obj)->is_a(k) ? JNI_TRUE : JNI_FALSE;1557}1558}1559#ifndef USDT21560DTRACE_PROBE1(hotspot_jni, IsInstanceOf__return, ret);1561#else /* USDT2 */1562HOTSPOT_JNI_ISINSTANCEOF_RETURN(1563ret);1564#endif /* USDT2 */1565return ret;1566JNI_END156715681569static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,1570const char *sig, bool is_static, TRAPS) {1571// %%%% This code should probably just call into a method in the LinkResolver1572//1573// The class should have been loaded (we have an instance of the class1574// passed in) so the method and signature should already be in the symbol1575// table. If they're not there, the method doesn't exist.1576const char *name_to_probe = (name_str == NULL)1577? vmSymbols::object_initializer_name()->as_C_string()1578: name_str;1579TempNewSymbol name = SymbolTable::probe(name_to_probe, (int)strlen(name_to_probe));1580TempNewSymbol signature = SymbolTable::probe(sig, (int)strlen(sig));15811582if (name == NULL || signature == NULL) {1583THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);1584}15851586// Throw a NoSuchMethodError exception if we have an instance of a1587// primitive java.lang.Class1588if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {1589THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);1590}15911592KlassHandle klass(THREAD,1593java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));15941595// Make sure class is linked and initialized before handing id's out to1596// Method*s.1597klass()->initialize(CHECK_NULL);15981599Method* m;1600if (name == vmSymbols::object_initializer_name() ||1601name == vmSymbols::class_initializer_name()) {1602// Never search superclasses for constructors1603if (klass->oop_is_instance()) {1604m = InstanceKlass::cast(klass())->find_method(name, signature);1605} else {1606m = NULL;1607}1608} else {1609m = klass->lookup_method(name, signature);1610if (m == NULL && klass->oop_is_instance()) {1611m = InstanceKlass::cast(klass())->lookup_method_in_ordered_interfaces(name, signature);1612}1613}1614if (m == NULL || (m->is_static() != is_static)) {1615THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);1616}1617return m->jmethod_id();1618}161916201621JNI_ENTRY(jmethodID, jni_GetMethodID(JNIEnv *env, jclass clazz,1622const char *name, const char *sig))1623JNIWrapper("GetMethodID");1624#ifndef USDT21625DTRACE_PROBE4(hotspot_jni, GetMethodID__entry, env, clazz, name, sig);1626#else /* USDT2 */1627HOTSPOT_JNI_GETMETHODID_ENTRY(1628env, clazz, (char *) name, (char *) sig);1629#endif /* USDT2 */1630jmethodID ret = get_method_id(env, clazz, name, sig, false, thread);1631#ifndef USDT21632DTRACE_PROBE1(hotspot_jni, GetMethodID__return, ret);1633#else /* USDT2 */1634HOTSPOT_JNI_GETMETHODID_RETURN(1635(uintptr_t) ret);1636#endif /* USDT2 */1637return ret;1638JNI_END163916401641JNI_ENTRY(jmethodID, jni_GetStaticMethodID(JNIEnv *env, jclass clazz,1642const char *name, const char *sig))1643JNIWrapper("GetStaticMethodID");1644#ifndef USDT21645DTRACE_PROBE4(hotspot_jni, GetStaticMethodID__entry, env, clazz, name, sig);1646#else /* USDT2 */1647HOTSPOT_JNI_GETSTATICMETHODID_ENTRY(1648env, (char *) clazz, (char *) name, (char *)sig);1649#endif /* USDT2 */1650jmethodID ret = get_method_id(env, clazz, name, sig, true, thread);1651#ifndef USDT21652DTRACE_PROBE1(hotspot_jni, GetStaticMethodID__return, ret);1653#else /* USDT2 */1654HOTSPOT_JNI_GETSTATICMETHODID_RETURN(1655(uintptr_t) ret);1656#endif /* USDT2 */1657return ret;1658JNI_END1659166016611662//1663// Calling Methods1664//16651666#ifndef USDT21667#define DEFINE_CALLMETHOD(ResultType, Result, Tag) \1668\1669DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType);\1670DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType);\1671DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType);\1672\1673JNI_ENTRY(ResultType, \1674jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \1675JNIWrapper("Call" XSTR(Result) "Method"); \1676\1677DTRACE_PROBE3(hotspot_jni, Call##Result##Method__entry, env, obj, methodID); \1678ResultType ret = 0;\1679DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \1680(const ResultType&)ret);\1681\1682va_list args; \1683va_start(args, methodID); \1684JavaValue jvalue(Tag); \1685JNI_ArgumentPusherVaArg ap(methodID, args); \1686jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \1687va_end(args); \1688ret = jvalue.get_##ResultType(); \1689return ret;\1690JNI_END \1691\1692\1693JNI_ENTRY(ResultType, \1694jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \1695JNIWrapper("Call" XSTR(Result) "MethodV"); \1696\1697DTRACE_PROBE3(hotspot_jni, Call##Result##MethodV__entry, env, obj, methodID); \1698ResultType ret = 0;\1699DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \1700(const ResultType&)ret);\1701\1702JavaValue jvalue(Tag); \1703JNI_ArgumentPusherVaArg ap(methodID, args); \1704jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \1705ret = jvalue.get_##ResultType(); \1706return ret;\1707JNI_END \1708\1709\1710JNI_ENTRY(ResultType, \1711jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \1712JNIWrapper("Call" XSTR(Result) "MethodA"); \1713DTRACE_PROBE3(hotspot_jni, Call##Result##MethodA__entry, env, obj, methodID); \1714ResultType ret = 0;\1715DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \1716(const ResultType&)ret);\1717\1718JavaValue jvalue(Tag); \1719JNI_ArgumentPusherArray ap(methodID, args); \1720jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \1721ret = jvalue.get_##ResultType(); \1722return ret;\1723JNI_END17241725// the runtime type of subword integral basic types is integer1726DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN)1727DEFINE_CALLMETHOD(jbyte, Byte, T_BYTE)1728DEFINE_CALLMETHOD(jchar, Char, T_CHAR)1729DEFINE_CALLMETHOD(jshort, Short, T_SHORT)17301731DEFINE_CALLMETHOD(jobject, Object, T_OBJECT)1732DEFINE_CALLMETHOD(jint, Int, T_INT)1733DEFINE_CALLMETHOD(jlong, Long, T_LONG)1734DEFINE_CALLMETHOD(jfloat, Float, T_FLOAT)1735DEFINE_CALLMETHOD(jdouble, Double, T_DOUBLE)17361737DT_VOID_RETURN_MARK_DECL(CallVoidMethod);1738DT_VOID_RETURN_MARK_DECL(CallVoidMethodV);1739DT_VOID_RETURN_MARK_DECL(CallVoidMethodA);17401741#else /* USDT2 */17421743#define DEFINE_CALLMETHOD(ResultType, Result, Tag \1744, EntryProbe, ReturnProbe) \1745\1746DT_RETURN_MARK_DECL_FOR(Result, Call##Result##Method, ResultType \1747, ReturnProbe); \1748\1749JNI_ENTRY(ResultType, \1750jni_Call##Result##Method(JNIEnv *env, jobject obj, jmethodID methodID, ...)) \1751JNIWrapper("Call" XSTR(Result) "Method"); \1752\1753EntryProbe; \1754ResultType ret = 0;\1755DT_RETURN_MARK_FOR(Result, Call##Result##Method, ResultType, \1756(const ResultType&)ret);\1757\1758va_list args; \1759va_start(args, methodID); \1760JavaValue jvalue(Tag); \1761JNI_ArgumentPusherVaArg ap(methodID, args); \1762jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \1763va_end(args); \1764ret = jvalue.get_##ResultType(); \1765return ret;\1766JNI_END17671768// the runtime type of subword integral basic types is integer1769DEFINE_CALLMETHOD(jboolean, Boolean, T_BOOLEAN1770, HOTSPOT_JNI_CALLBOOLEANMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1771HOTSPOT_JNI_CALLBOOLEANMETHOD_RETURN(_ret_ref))1772DEFINE_CALLMETHOD(jbyte, Byte, T_BYTE1773, HOTSPOT_JNI_CALLBYTEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1774HOTSPOT_JNI_CALLBYTEMETHOD_RETURN(_ret_ref))1775DEFINE_CALLMETHOD(jchar, Char, T_CHAR1776, HOTSPOT_JNI_CALLCHARMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1777HOTSPOT_JNI_CALLCHARMETHOD_RETURN(_ret_ref))1778DEFINE_CALLMETHOD(jshort, Short, T_SHORT1779, HOTSPOT_JNI_CALLSHORTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1780HOTSPOT_JNI_CALLSHORTMETHOD_RETURN(_ret_ref))17811782DEFINE_CALLMETHOD(jobject, Object, T_OBJECT1783, HOTSPOT_JNI_CALLOBJECTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1784HOTSPOT_JNI_CALLOBJECTMETHOD_RETURN(_ret_ref))1785DEFINE_CALLMETHOD(jint, Int, T_INT,1786HOTSPOT_JNI_CALLINTMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1787HOTSPOT_JNI_CALLINTMETHOD_RETURN(_ret_ref))1788DEFINE_CALLMETHOD(jlong, Long, T_LONG1789, HOTSPOT_JNI_CALLLONGMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1790HOTSPOT_JNI_CALLLONGMETHOD_RETURN(_ret_ref))1791// Float and double probes don't return value because dtrace doesn't currently support it1792DEFINE_CALLMETHOD(jfloat, Float, T_FLOAT1793, HOTSPOT_JNI_CALLFLOATMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1794HOTSPOT_JNI_CALLFLOATMETHOD_RETURN())1795DEFINE_CALLMETHOD(jdouble, Double, T_DOUBLE1796, HOTSPOT_JNI_CALLDOUBLEMETHOD_ENTRY(env, obj, (uintptr_t)methodID),1797HOTSPOT_JNI_CALLDOUBLEMETHOD_RETURN())17981799#define DEFINE_CALLMETHODV(ResultType, Result, Tag \1800, EntryProbe, ReturnProbe) \1801\1802DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodV, ResultType \1803, ReturnProbe); \1804\1805JNI_ENTRY(ResultType, \1806jni_Call##Result##MethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)) \1807JNIWrapper("Call" XSTR(Result) "MethodV"); \1808\1809EntryProbe;\1810ResultType ret = 0;\1811DT_RETURN_MARK_FOR(Result, Call##Result##MethodV, ResultType, \1812(const ResultType&)ret);\1813\1814JavaValue jvalue(Tag); \1815JNI_ArgumentPusherVaArg ap(methodID, args); \1816jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \1817ret = jvalue.get_##ResultType(); \1818return ret;\1819JNI_END18201821// the runtime type of subword integral basic types is integer1822DEFINE_CALLMETHODV(jboolean, Boolean, T_BOOLEAN1823, HOTSPOT_JNI_CALLBOOLEANMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1824HOTSPOT_JNI_CALLBOOLEANMETHODV_RETURN(_ret_ref))1825DEFINE_CALLMETHODV(jbyte, Byte, T_BYTE1826, HOTSPOT_JNI_CALLBYTEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1827HOTSPOT_JNI_CALLBYTEMETHODV_RETURN(_ret_ref))1828DEFINE_CALLMETHODV(jchar, Char, T_CHAR1829, HOTSPOT_JNI_CALLCHARMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1830HOTSPOT_JNI_CALLCHARMETHODV_RETURN(_ret_ref))1831DEFINE_CALLMETHODV(jshort, Short, T_SHORT1832, HOTSPOT_JNI_CALLSHORTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1833HOTSPOT_JNI_CALLSHORTMETHODV_RETURN(_ret_ref))18341835DEFINE_CALLMETHODV(jobject, Object, T_OBJECT1836, HOTSPOT_JNI_CALLOBJECTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1837HOTSPOT_JNI_CALLOBJECTMETHODV_RETURN(_ret_ref))1838DEFINE_CALLMETHODV(jint, Int, T_INT,1839HOTSPOT_JNI_CALLINTMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1840HOTSPOT_JNI_CALLINTMETHODV_RETURN(_ret_ref))1841DEFINE_CALLMETHODV(jlong, Long, T_LONG1842, HOTSPOT_JNI_CALLLONGMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1843HOTSPOT_JNI_CALLLONGMETHODV_RETURN(_ret_ref))1844// Float and double probes don't return value because dtrace doesn't currently support it1845DEFINE_CALLMETHODV(jfloat, Float, T_FLOAT1846, HOTSPOT_JNI_CALLFLOATMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1847HOTSPOT_JNI_CALLFLOATMETHODV_RETURN())1848DEFINE_CALLMETHODV(jdouble, Double, T_DOUBLE1849, HOTSPOT_JNI_CALLDOUBLEMETHODV_ENTRY(env, obj, (uintptr_t)methodID),1850HOTSPOT_JNI_CALLDOUBLEMETHODV_RETURN())18511852#define DEFINE_CALLMETHODA(ResultType, Result, Tag \1853, EntryProbe, ReturnProbe) \1854\1855DT_RETURN_MARK_DECL_FOR(Result, Call##Result##MethodA, ResultType \1856, ReturnProbe); \1857\1858JNI_ENTRY(ResultType, \1859jni_Call##Result##MethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args)) \1860JNIWrapper("Call" XSTR(Result) "MethodA"); \1861EntryProbe; \1862ResultType ret = 0;\1863DT_RETURN_MARK_FOR(Result, Call##Result##MethodA, ResultType, \1864(const ResultType&)ret);\1865\1866JavaValue jvalue(Tag); \1867JNI_ArgumentPusherArray ap(methodID, args); \1868jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK_0); \1869ret = jvalue.get_##ResultType(); \1870return ret;\1871JNI_END18721873// the runtime type of subword integral basic types is integer1874DEFINE_CALLMETHODA(jboolean, Boolean, T_BOOLEAN1875, HOTSPOT_JNI_CALLBOOLEANMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1876HOTSPOT_JNI_CALLBOOLEANMETHODA_RETURN(_ret_ref))1877DEFINE_CALLMETHODA(jbyte, Byte, T_BYTE1878, HOTSPOT_JNI_CALLBYTEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1879HOTSPOT_JNI_CALLBYTEMETHODA_RETURN(_ret_ref))1880DEFINE_CALLMETHODA(jchar, Char, T_CHAR1881, HOTSPOT_JNI_CALLCHARMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1882HOTSPOT_JNI_CALLCHARMETHODA_RETURN(_ret_ref))1883DEFINE_CALLMETHODA(jshort, Short, T_SHORT1884, HOTSPOT_JNI_CALLSHORTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1885HOTSPOT_JNI_CALLSHORTMETHODA_RETURN(_ret_ref))18861887DEFINE_CALLMETHODA(jobject, Object, T_OBJECT1888, HOTSPOT_JNI_CALLOBJECTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1889HOTSPOT_JNI_CALLOBJECTMETHODA_RETURN(_ret_ref))1890DEFINE_CALLMETHODA(jint, Int, T_INT,1891HOTSPOT_JNI_CALLINTMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1892HOTSPOT_JNI_CALLINTMETHODA_RETURN(_ret_ref))1893DEFINE_CALLMETHODA(jlong, Long, T_LONG1894, HOTSPOT_JNI_CALLLONGMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1895HOTSPOT_JNI_CALLLONGMETHODA_RETURN(_ret_ref))1896// Float and double probes don't return value because dtrace doesn't currently support it1897DEFINE_CALLMETHODA(jfloat, Float, T_FLOAT1898, HOTSPOT_JNI_CALLFLOATMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1899HOTSPOT_JNI_CALLFLOATMETHODA_RETURN())1900DEFINE_CALLMETHODA(jdouble, Double, T_DOUBLE1901, HOTSPOT_JNI_CALLDOUBLEMETHODA_ENTRY(env, obj, (uintptr_t)methodID),1902HOTSPOT_JNI_CALLDOUBLEMETHODA_RETURN())19031904DT_VOID_RETURN_MARK_DECL(CallVoidMethod, HOTSPOT_JNI_CALLVOIDMETHOD_RETURN());1905DT_VOID_RETURN_MARK_DECL(CallVoidMethodV, HOTSPOT_JNI_CALLVOIDMETHODV_RETURN());1906DT_VOID_RETURN_MARK_DECL(CallVoidMethodA, HOTSPOT_JNI_CALLVOIDMETHODA_RETURN());19071908#endif /* USDT2 */19091910JNI_ENTRY(void, jni_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...))1911JNIWrapper("CallVoidMethod");1912#ifndef USDT21913DTRACE_PROBE3(hotspot_jni, CallVoidMethod__entry, env, obj, methodID);1914#else /* USDT2 */1915HOTSPOT_JNI_CALLVOIDMETHOD_ENTRY(1916env, obj, (uintptr_t) methodID);1917#endif /* USDT2 */1918DT_VOID_RETURN_MARK(CallVoidMethod);19191920va_list args;1921va_start(args, methodID);1922JavaValue jvalue(T_VOID);1923JNI_ArgumentPusherVaArg ap(methodID, args);1924jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);1925va_end(args);1926JNI_END192719281929JNI_ENTRY(void, jni_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args))1930JNIWrapper("CallVoidMethodV");1931#ifndef USDT21932DTRACE_PROBE3(hotspot_jni, CallVoidMethodV__entry, env, obj, methodID);1933#else /* USDT2 */1934HOTSPOT_JNI_CALLVOIDMETHODV_ENTRY(1935env, obj, (uintptr_t) methodID);1936#endif /* USDT2 */1937DT_VOID_RETURN_MARK(CallVoidMethodV);19381939JavaValue jvalue(T_VOID);1940JNI_ArgumentPusherVaArg ap(methodID, args);1941jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);1942JNI_END194319441945JNI_ENTRY(void, jni_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args))1946JNIWrapper("CallVoidMethodA");1947#ifndef USDT21948DTRACE_PROBE3(hotspot_jni, CallVoidMethodA__entry, env, obj, methodID);1949#else /* USDT2 */1950HOTSPOT_JNI_CALLVOIDMETHODA_ENTRY(1951env, obj, (uintptr_t) methodID);1952#endif /* USDT2 */1953DT_VOID_RETURN_MARK(CallVoidMethodA);19541955JavaValue jvalue(T_VOID);1956JNI_ArgumentPusherArray ap(methodID, args);1957jni_invoke_nonstatic(env, &jvalue, obj, JNI_VIRTUAL, methodID, &ap, CHECK);1958JNI_END195919601961#ifndef USDT21962#define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag) \1963\1964DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType);\1965DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType);\1966DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType);\1967\1968JNI_ENTRY(ResultType, \1969jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \1970JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \1971\1972DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##Method__entry, env, obj, cls, methodID);\1973ResultType ret;\1974DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \1975(const ResultType&)ret);\1976\1977va_list args; \1978va_start(args, methodID); \1979JavaValue jvalue(Tag); \1980JNI_ArgumentPusherVaArg ap(methodID, args); \1981jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \1982va_end(args); \1983ret = jvalue.get_##ResultType(); \1984return ret;\1985JNI_END \1986\1987JNI_ENTRY(ResultType, \1988jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \1989JNIWrapper("CallNonvitual" XSTR(Result) "#MethodV"); \1990DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodV__entry, env, obj, cls, methodID);\1991ResultType ret;\1992DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \1993(const ResultType&)ret);\1994\1995JavaValue jvalue(Tag); \1996JNI_ArgumentPusherVaArg ap(methodID, args); \1997jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \1998ret = jvalue.get_##ResultType(); \1999return ret;\2000JNI_END \2001\2002JNI_ENTRY(ResultType, \2003jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \2004JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \2005DTRACE_PROBE4(hotspot_jni, CallNonvirtual##Result##MethodA__entry, env, obj, cls, methodID);\2006ResultType ret;\2007DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \2008(const ResultType&)ret);\2009\2010JavaValue jvalue(Tag); \2011JNI_ArgumentPusherArray ap(methodID, args); \2012jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \2013ret = jvalue.get_##ResultType(); \2014return ret;\2015JNI_END20162017// the runtime type of subword integral basic types is integer2018DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN)2019DEFINE_CALLNONVIRTUALMETHOD(jbyte, Byte, T_BYTE)2020DEFINE_CALLNONVIRTUALMETHOD(jchar, Char, T_CHAR)2021DEFINE_CALLNONVIRTUALMETHOD(jshort, Short, T_SHORT)20222023DEFINE_CALLNONVIRTUALMETHOD(jobject, Object, T_OBJECT)2024DEFINE_CALLNONVIRTUALMETHOD(jint, Int, T_INT)2025DEFINE_CALLNONVIRTUALMETHOD(jlong, Long, T_LONG)2026DEFINE_CALLNONVIRTUALMETHOD(jfloat, Float, T_FLOAT)2027DEFINE_CALLNONVIRTUALMETHOD(jdouble, Double, T_DOUBLE)202820292030DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod);2031DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV);2032DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA);20332034#else /* USDT2 */20352036#define DEFINE_CALLNONVIRTUALMETHOD(ResultType, Result, Tag \2037, EntryProbe, ReturnProbe) \2038\2039DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##Method, ResultType \2040, ReturnProbe);\2041\2042JNI_ENTRY(ResultType, \2043jni_CallNonvirtual##Result##Method(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...)) \2044JNIWrapper("CallNonvitual" XSTR(Result) "Method"); \2045\2046EntryProbe;\2047ResultType ret;\2048DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##Method, ResultType, \2049(const ResultType&)ret);\2050\2051va_list args; \2052va_start(args, methodID); \2053JavaValue jvalue(Tag); \2054JNI_ArgumentPusherVaArg ap(methodID, args); \2055jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \2056va_end(args); \2057ret = jvalue.get_##ResultType(); \2058return ret;\2059JNI_END20602061// the runtime type of subword integral basic types is integer2062DEFINE_CALLNONVIRTUALMETHOD(jboolean, Boolean, T_BOOLEAN2063, HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2064HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHOD_RETURN(_ret_ref))2065DEFINE_CALLNONVIRTUALMETHOD(jbyte, Byte, T_BYTE2066, HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2067HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHOD_RETURN(_ret_ref))2068DEFINE_CALLNONVIRTUALMETHOD(jchar, Char, T_CHAR2069, HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2070HOTSPOT_JNI_CALLNONVIRTUALCHARMETHOD_RETURN(_ret_ref))2071DEFINE_CALLNONVIRTUALMETHOD(jshort, Short, T_SHORT2072, HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2073HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHOD_RETURN(_ret_ref))20742075DEFINE_CALLNONVIRTUALMETHOD(jobject, Object, T_OBJECT2076, HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2077HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHOD_RETURN(_ret_ref))2078DEFINE_CALLNONVIRTUALMETHOD(jint, Int, T_INT2079, HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2080HOTSPOT_JNI_CALLNONVIRTUALINTMETHOD_RETURN(_ret_ref))2081DEFINE_CALLNONVIRTUALMETHOD(jlong, Long, T_LONG2082, HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2083// Float and double probes don't return value because dtrace doesn't currently support it2084HOTSPOT_JNI_CALLNONVIRTUALLONGMETHOD_RETURN(_ret_ref))2085DEFINE_CALLNONVIRTUALMETHOD(jfloat, Float, T_FLOAT2086, HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2087HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHOD_RETURN())2088DEFINE_CALLNONVIRTUALMETHOD(jdouble, Double, T_DOUBLE2089, HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_ENTRY(env, obj, cls, (uintptr_t)methodID),2090HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHOD_RETURN())20912092#define DEFINE_CALLNONVIRTUALMETHODV(ResultType, Result, Tag \2093, EntryProbe, ReturnProbe) \2094\2095DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodV, ResultType \2096, ReturnProbe);\2097\2098JNI_ENTRY(ResultType, \2099jni_CallNonvirtual##Result##MethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args)) \2100JNIWrapper("CallNonvitual" XSTR(Result) "MethodV"); \2101\2102EntryProbe;\2103ResultType ret;\2104DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodV, ResultType, \2105(const ResultType&)ret);\2106\2107JavaValue jvalue(Tag); \2108JNI_ArgumentPusherVaArg ap(methodID, args); \2109jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \2110ret = jvalue.get_##ResultType(); \2111return ret;\2112JNI_END21132114// the runtime type of subword integral basic types is integer2115DEFINE_CALLNONVIRTUALMETHODV(jboolean, Boolean, T_BOOLEAN2116, HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2117HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODV_RETURN(_ret_ref))2118DEFINE_CALLNONVIRTUALMETHODV(jbyte, Byte, T_BYTE2119, HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2120HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODV_RETURN(_ret_ref))2121DEFINE_CALLNONVIRTUALMETHODV(jchar, Char, T_CHAR2122, HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2123HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODV_RETURN(_ret_ref))2124DEFINE_CALLNONVIRTUALMETHODV(jshort, Short, T_SHORT2125, HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2126HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODV_RETURN(_ret_ref))21272128DEFINE_CALLNONVIRTUALMETHODV(jobject, Object, T_OBJECT2129, HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2130HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODV_RETURN(_ret_ref))2131DEFINE_CALLNONVIRTUALMETHODV(jint, Int, T_INT2132, HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2133HOTSPOT_JNI_CALLNONVIRTUALINTMETHODV_RETURN(_ret_ref))2134DEFINE_CALLNONVIRTUALMETHODV(jlong, Long, T_LONG2135, HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2136// Float and double probes don't return value because dtrace doesn't currently support it2137HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODV_RETURN(_ret_ref))2138DEFINE_CALLNONVIRTUALMETHODV(jfloat, Float, T_FLOAT2139, HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2140HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODV_RETURN())2141DEFINE_CALLNONVIRTUALMETHODV(jdouble, Double, T_DOUBLE2142, HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_ENTRY(env, obj, cls, (uintptr_t)methodID),2143HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODV_RETURN())21442145#define DEFINE_CALLNONVIRTUALMETHODA(ResultType, Result, Tag \2146, EntryProbe, ReturnProbe) \2147\2148DT_RETURN_MARK_DECL_FOR(Result, CallNonvirtual##Result##MethodA, ResultType \2149, ReturnProbe);\2150\2151JNI_ENTRY(ResultType, \2152jni_CallNonvirtual##Result##MethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args)) \2153JNIWrapper("CallNonvitual" XSTR(Result) "MethodA"); \2154\2155EntryProbe;\2156ResultType ret;\2157DT_RETURN_MARK_FOR(Result, CallNonvirtual##Result##MethodA, ResultType, \2158(const ResultType&)ret);\2159\2160JavaValue jvalue(Tag); \2161JNI_ArgumentPusherArray ap(methodID, args); \2162jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK_0); \2163ret = jvalue.get_##ResultType(); \2164return ret;\2165JNI_END21662167// the runtime type of subword integral basic types is integer2168DEFINE_CALLNONVIRTUALMETHODA(jboolean, Boolean, T_BOOLEAN2169, HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2170HOTSPOT_JNI_CALLNONVIRTUALBOOLEANMETHODA_RETURN(_ret_ref))2171DEFINE_CALLNONVIRTUALMETHODA(jbyte, Byte, T_BYTE2172, HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2173HOTSPOT_JNI_CALLNONVIRTUALBYTEMETHODA_RETURN(_ret_ref))2174DEFINE_CALLNONVIRTUALMETHODA(jchar, Char, T_CHAR2175, HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2176HOTSPOT_JNI_CALLNONVIRTUALCHARMETHODA_RETURN(_ret_ref))2177DEFINE_CALLNONVIRTUALMETHODA(jshort, Short, T_SHORT2178, HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2179HOTSPOT_JNI_CALLNONVIRTUALSHORTMETHODA_RETURN(_ret_ref))21802181DEFINE_CALLNONVIRTUALMETHODA(jobject, Object, T_OBJECT2182, HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2183HOTSPOT_JNI_CALLNONVIRTUALOBJECTMETHODA_RETURN(_ret_ref))2184DEFINE_CALLNONVIRTUALMETHODA(jint, Int, T_INT2185, HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2186HOTSPOT_JNI_CALLNONVIRTUALINTMETHODA_RETURN(_ret_ref))2187DEFINE_CALLNONVIRTUALMETHODA(jlong, Long, T_LONG2188, HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2189// Float and double probes don't return value because dtrace doesn't currently support it2190HOTSPOT_JNI_CALLNONVIRTUALLONGMETHODA_RETURN(_ret_ref))2191DEFINE_CALLNONVIRTUALMETHODA(jfloat, Float, T_FLOAT2192, HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2193HOTSPOT_JNI_CALLNONVIRTUALFLOATMETHODA_RETURN())2194DEFINE_CALLNONVIRTUALMETHODA(jdouble, Double, T_DOUBLE2195, HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_ENTRY(env, obj, cls, (uintptr_t)methodID),2196HOTSPOT_JNI_CALLNONVIRTUALDOUBLEMETHODA_RETURN())21972198DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethod2199, HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_RETURN());2200DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodV2201, HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_RETURN());2202DT_VOID_RETURN_MARK_DECL(CallNonvirtualVoidMethodA2203, HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_RETURN());2204#endif /* USDT2 */22052206JNI_ENTRY(void, jni_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, ...))2207JNIWrapper("CallNonvirtualVoidMethod");22082209#ifndef USDT22210DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethod__entry,2211env, obj, cls, methodID);2212#else /* USDT2 */2213HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHOD_ENTRY(2214env, obj, cls, (uintptr_t) methodID);2215#endif /* USDT2 */2216DT_VOID_RETURN_MARK(CallNonvirtualVoidMethod);22172218va_list args;2219va_start(args, methodID);2220JavaValue jvalue(T_VOID);2221JNI_ArgumentPusherVaArg ap(methodID, args);2222jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);2223va_end(args);2224JNI_END222522262227JNI_ENTRY(void, jni_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, va_list args))2228JNIWrapper("CallNonvirtualVoidMethodV");22292230#ifndef USDT22231DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodV__entry,2232env, obj, cls, methodID);2233#else /* USDT2 */2234HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODV_ENTRY(2235env, obj, cls, (uintptr_t) methodID);2236#endif /* USDT2 */2237DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodV);22382239JavaValue jvalue(T_VOID);2240JNI_ArgumentPusherVaArg ap(methodID, args);2241jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);2242JNI_END224322442245JNI_ENTRY(void, jni_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass cls, jmethodID methodID, const jvalue *args))2246JNIWrapper("CallNonvirtualVoidMethodA");2247#ifndef USDT22248DTRACE_PROBE4(hotspot_jni, CallNonvirtualVoidMethodA__entry,2249env, obj, cls, methodID);2250#else /* USDT2 */2251HOTSPOT_JNI_CALLNONVIRTUALVOIDMETHODA_ENTRY(2252env, obj, cls, (uintptr_t) methodID);2253#endif /* USDT2 */2254DT_VOID_RETURN_MARK(CallNonvirtualVoidMethodA);2255JavaValue jvalue(T_VOID);2256JNI_ArgumentPusherArray ap(methodID, args);2257jni_invoke_nonstatic(env, &jvalue, obj, JNI_NONVIRTUAL, methodID, &ap, CHECK);2258JNI_END225922602261#ifndef USDT22262#define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag) \2263\2264DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType);\2265DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType);\2266DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType);\2267\2268JNI_ENTRY(ResultType, \2269jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \2270JNIWrapper("CallStatic" XSTR(Result) "Method"); \2271\2272DTRACE_PROBE3(hotspot_jni, CallStatic##Result##Method__entry, env, cls, methodID);\2273ResultType ret = 0;\2274DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \2275(const ResultType&)ret);\2276\2277va_list args; \2278va_start(args, methodID); \2279JavaValue jvalue(Tag); \2280JNI_ArgumentPusherVaArg ap(methodID, args); \2281jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \2282va_end(args); \2283ret = jvalue.get_##ResultType(); \2284return ret;\2285JNI_END \2286\2287JNI_ENTRY(ResultType, \2288jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \2289JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \2290DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodV__entry, env, cls, methodID);\2291ResultType ret = 0;\2292DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \2293(const ResultType&)ret);\2294\2295JavaValue jvalue(Tag); \2296JNI_ArgumentPusherVaArg ap(methodID, args); \2297jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \2298ret = jvalue.get_##ResultType(); \2299return ret;\2300JNI_END \2301\2302JNI_ENTRY(ResultType, \2303jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \2304JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \2305DTRACE_PROBE3(hotspot_jni, CallStatic##Result##MethodA__entry, env, cls, methodID);\2306ResultType ret = 0;\2307DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \2308(const ResultType&)ret);\2309\2310JavaValue jvalue(Tag); \2311JNI_ArgumentPusherArray ap(methodID, args); \2312jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \2313ret = jvalue.get_##ResultType(); \2314return ret;\2315JNI_END23162317// the runtime type of subword integral basic types is integer2318DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN)2319DEFINE_CALLSTATICMETHOD(jbyte, Byte, T_BYTE)2320DEFINE_CALLSTATICMETHOD(jchar, Char, T_CHAR)2321DEFINE_CALLSTATICMETHOD(jshort, Short, T_SHORT)23222323DEFINE_CALLSTATICMETHOD(jobject, Object, T_OBJECT)2324DEFINE_CALLSTATICMETHOD(jint, Int, T_INT)2325DEFINE_CALLSTATICMETHOD(jlong, Long, T_LONG)2326DEFINE_CALLSTATICMETHOD(jfloat, Float, T_FLOAT)2327DEFINE_CALLSTATICMETHOD(jdouble, Double, T_DOUBLE)232823292330DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod);2331DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV);2332DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA);23332334#else /* USDT2 */23352336#define DEFINE_CALLSTATICMETHOD(ResultType, Result, Tag \2337, EntryProbe, ResultProbe) \2338\2339DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##Method, ResultType \2340, ResultProbe); \2341\2342JNI_ENTRY(ResultType, \2343jni_CallStatic##Result##Method(JNIEnv *env, jclass cls, jmethodID methodID, ...)) \2344JNIWrapper("CallStatic" XSTR(Result) "Method"); \2345\2346EntryProbe; \2347ResultType ret = 0;\2348DT_RETURN_MARK_FOR(Result, CallStatic##Result##Method, ResultType, \2349(const ResultType&)ret);\2350\2351va_list args; \2352va_start(args, methodID); \2353JavaValue jvalue(Tag); \2354JNI_ArgumentPusherVaArg ap(methodID, args); \2355jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \2356va_end(args); \2357ret = jvalue.get_##ResultType(); \2358return ret;\2359JNI_END23602361// the runtime type of subword integral basic types is integer2362DEFINE_CALLSTATICMETHOD(jboolean, Boolean, T_BOOLEAN2363, HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2364HOTSPOT_JNI_CALLSTATICBOOLEANMETHOD_RETURN(_ret_ref));2365DEFINE_CALLSTATICMETHOD(jbyte, Byte, T_BYTE2366, HOTSPOT_JNI_CALLSTATICBYTEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2367HOTSPOT_JNI_CALLSTATICBYTEMETHOD_RETURN(_ret_ref));2368DEFINE_CALLSTATICMETHOD(jchar, Char, T_CHAR2369, HOTSPOT_JNI_CALLSTATICCHARMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2370HOTSPOT_JNI_CALLSTATICCHARMETHOD_RETURN(_ret_ref));2371DEFINE_CALLSTATICMETHOD(jshort, Short, T_SHORT2372, HOTSPOT_JNI_CALLSTATICSHORTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2373HOTSPOT_JNI_CALLSTATICSHORTMETHOD_RETURN(_ret_ref));23742375DEFINE_CALLSTATICMETHOD(jobject, Object, T_OBJECT2376, HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2377HOTSPOT_JNI_CALLSTATICOBJECTMETHOD_RETURN(_ret_ref));2378DEFINE_CALLSTATICMETHOD(jint, Int, T_INT2379, HOTSPOT_JNI_CALLSTATICINTMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2380HOTSPOT_JNI_CALLSTATICINTMETHOD_RETURN(_ret_ref));2381DEFINE_CALLSTATICMETHOD(jlong, Long, T_LONG2382, HOTSPOT_JNI_CALLSTATICLONGMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2383HOTSPOT_JNI_CALLSTATICLONGMETHOD_RETURN(_ret_ref));2384// Float and double probes don't return value because dtrace doesn't currently support it2385DEFINE_CALLSTATICMETHOD(jfloat, Float, T_FLOAT2386, HOTSPOT_JNI_CALLSTATICFLOATMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2387HOTSPOT_JNI_CALLSTATICFLOATMETHOD_RETURN());2388DEFINE_CALLSTATICMETHOD(jdouble, Double, T_DOUBLE2389, HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_ENTRY(env, cls, (uintptr_t)methodID),2390HOTSPOT_JNI_CALLSTATICDOUBLEMETHOD_RETURN());23912392#define DEFINE_CALLSTATICMETHODV(ResultType, Result, Tag \2393, EntryProbe, ResultProbe) \2394\2395DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodV, ResultType \2396, ResultProbe); \2397\2398JNI_ENTRY(ResultType, \2399jni_CallStatic##Result##MethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)) \2400JNIWrapper("CallStatic" XSTR(Result) "MethodV"); \2401\2402EntryProbe; \2403ResultType ret = 0;\2404DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodV, ResultType, \2405(const ResultType&)ret);\2406\2407JavaValue jvalue(Tag); \2408JNI_ArgumentPusherVaArg ap(methodID, args); \2409/* Make sure class is initialized before trying to invoke its method */ \2410KlassHandle k(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls))); \2411k()->initialize(CHECK_0); \2412jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \2413va_end(args); \2414ret = jvalue.get_##ResultType(); \2415return ret;\2416JNI_END24172418// the runtime type of subword integral basic types is integer2419DEFINE_CALLSTATICMETHODV(jboolean, Boolean, T_BOOLEAN2420, HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2421HOTSPOT_JNI_CALLSTATICBOOLEANMETHODV_RETURN(_ret_ref));2422DEFINE_CALLSTATICMETHODV(jbyte, Byte, T_BYTE2423, HOTSPOT_JNI_CALLSTATICBYTEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2424HOTSPOT_JNI_CALLSTATICBYTEMETHODV_RETURN(_ret_ref));2425DEFINE_CALLSTATICMETHODV(jchar, Char, T_CHAR2426, HOTSPOT_JNI_CALLSTATICCHARMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2427HOTSPOT_JNI_CALLSTATICCHARMETHODV_RETURN(_ret_ref));2428DEFINE_CALLSTATICMETHODV(jshort, Short, T_SHORT2429, HOTSPOT_JNI_CALLSTATICSHORTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2430HOTSPOT_JNI_CALLSTATICSHORTMETHODV_RETURN(_ret_ref));24312432DEFINE_CALLSTATICMETHODV(jobject, Object, T_OBJECT2433, HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2434HOTSPOT_JNI_CALLSTATICOBJECTMETHODV_RETURN(_ret_ref));2435DEFINE_CALLSTATICMETHODV(jint, Int, T_INT2436, HOTSPOT_JNI_CALLSTATICINTMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2437HOTSPOT_JNI_CALLSTATICINTMETHODV_RETURN(_ret_ref));2438DEFINE_CALLSTATICMETHODV(jlong, Long, T_LONG2439, HOTSPOT_JNI_CALLSTATICLONGMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2440HOTSPOT_JNI_CALLSTATICLONGMETHODV_RETURN(_ret_ref));2441// Float and double probes don't return value because dtrace doesn't currently support it2442DEFINE_CALLSTATICMETHODV(jfloat, Float, T_FLOAT2443, HOTSPOT_JNI_CALLSTATICFLOATMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2444HOTSPOT_JNI_CALLSTATICFLOATMETHODV_RETURN());2445DEFINE_CALLSTATICMETHODV(jdouble, Double, T_DOUBLE2446, HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_ENTRY(env, cls, (uintptr_t)methodID),2447HOTSPOT_JNI_CALLSTATICDOUBLEMETHODV_RETURN());24482449#define DEFINE_CALLSTATICMETHODA(ResultType, Result, Tag \2450, EntryProbe, ResultProbe) \2451\2452DT_RETURN_MARK_DECL_FOR(Result, CallStatic##Result##MethodA, ResultType \2453, ResultProbe); \2454\2455JNI_ENTRY(ResultType, \2456jni_CallStatic##Result##MethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args)) \2457JNIWrapper("CallStatic" XSTR(Result) "MethodA"); \2458\2459EntryProbe; \2460ResultType ret = 0;\2461DT_RETURN_MARK_FOR(Result, CallStatic##Result##MethodA, ResultType, \2462(const ResultType&)ret);\2463\2464JavaValue jvalue(Tag); \2465JNI_ArgumentPusherArray ap(methodID, args); \2466jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK_0); \2467ret = jvalue.get_##ResultType(); \2468return ret;\2469JNI_END24702471// the runtime type of subword integral basic types is integer2472DEFINE_CALLSTATICMETHODA(jboolean, Boolean, T_BOOLEAN2473, HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2474HOTSPOT_JNI_CALLSTATICBOOLEANMETHODA_RETURN(_ret_ref));2475DEFINE_CALLSTATICMETHODA(jbyte, Byte, T_BYTE2476, HOTSPOT_JNI_CALLSTATICBYTEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2477HOTSPOT_JNI_CALLSTATICBYTEMETHODA_RETURN(_ret_ref));2478DEFINE_CALLSTATICMETHODA(jchar, Char, T_CHAR2479, HOTSPOT_JNI_CALLSTATICCHARMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2480HOTSPOT_JNI_CALLSTATICCHARMETHODA_RETURN(_ret_ref));2481DEFINE_CALLSTATICMETHODA(jshort, Short, T_SHORT2482, HOTSPOT_JNI_CALLSTATICSHORTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2483HOTSPOT_JNI_CALLSTATICSHORTMETHODA_RETURN(_ret_ref));24842485DEFINE_CALLSTATICMETHODA(jobject, Object, T_OBJECT2486, HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2487HOTSPOT_JNI_CALLSTATICOBJECTMETHODA_RETURN(_ret_ref));2488DEFINE_CALLSTATICMETHODA(jint, Int, T_INT2489, HOTSPOT_JNI_CALLSTATICINTMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2490HOTSPOT_JNI_CALLSTATICINTMETHODA_RETURN(_ret_ref));2491DEFINE_CALLSTATICMETHODA(jlong, Long, T_LONG2492, HOTSPOT_JNI_CALLSTATICLONGMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2493HOTSPOT_JNI_CALLSTATICLONGMETHODA_RETURN(_ret_ref));2494// Float and double probes don't return value because dtrace doesn't currently support it2495DEFINE_CALLSTATICMETHODA(jfloat, Float, T_FLOAT2496, HOTSPOT_JNI_CALLSTATICFLOATMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2497HOTSPOT_JNI_CALLSTATICFLOATMETHODA_RETURN());2498DEFINE_CALLSTATICMETHODA(jdouble, Double, T_DOUBLE2499, HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_ENTRY(env, cls, (uintptr_t)methodID),2500HOTSPOT_JNI_CALLSTATICDOUBLEMETHODA_RETURN());25012502DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethod2503, HOTSPOT_JNI_CALLSTATICVOIDMETHOD_RETURN());2504DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodV2505, HOTSPOT_JNI_CALLSTATICVOIDMETHODV_RETURN());2506DT_VOID_RETURN_MARK_DECL(CallStaticVoidMethodA2507, HOTSPOT_JNI_CALLSTATICVOIDMETHODA_RETURN());2508#endif /* USDT2 */25092510JNI_ENTRY(void, jni_CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...))2511JNIWrapper("CallStaticVoidMethod");2512#ifndef USDT22513DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethod__entry, env, cls, methodID);2514#else /* USDT2 */2515HOTSPOT_JNI_CALLSTATICVOIDMETHOD_ENTRY(2516env, cls, (uintptr_t) methodID);2517#endif /* USDT2 */2518DT_VOID_RETURN_MARK(CallStaticVoidMethod);25192520va_list args;2521va_start(args, methodID);2522JavaValue jvalue(T_VOID);2523JNI_ArgumentPusherVaArg ap(methodID, args);2524jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);2525va_end(args);2526JNI_END252725282529JNI_ENTRY(void, jni_CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args))2530JNIWrapper("CallStaticVoidMethodV");2531#ifndef USDT22532DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodV__entry, env, cls, methodID);2533#else /* USDT2 */2534HOTSPOT_JNI_CALLSTATICVOIDMETHODV_ENTRY(2535env, cls, (uintptr_t) methodID);2536#endif /* USDT2 */2537DT_VOID_RETURN_MARK(CallStaticVoidMethodV);25382539JavaValue jvalue(T_VOID);2540JNI_ArgumentPusherVaArg ap(methodID, args);2541jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);2542JNI_END254325442545JNI_ENTRY(void, jni_CallStaticVoidMethodA(JNIEnv *env, jclass cls, jmethodID methodID, const jvalue *args))2546JNIWrapper("CallStaticVoidMethodA");2547#ifndef USDT22548DTRACE_PROBE3(hotspot_jni, CallStaticVoidMethodA__entry, env, cls, methodID);2549#else /* USDT2 */2550HOTSPOT_JNI_CALLSTATICVOIDMETHODA_ENTRY(2551env, cls, (uintptr_t) methodID);2552#endif /* USDT2 */2553DT_VOID_RETURN_MARK(CallStaticVoidMethodA);25542555JavaValue jvalue(T_VOID);2556JNI_ArgumentPusherArray ap(methodID, args);2557jni_invoke_static(env, &jvalue, NULL, JNI_STATIC, methodID, &ap, CHECK);2558JNI_END255925602561//2562// Accessing Fields2563//256425652566#ifndef USDT22567DT_RETURN_MARK_DECL(GetFieldID, jfieldID);2568#else /* USDT2 */2569DT_RETURN_MARK_DECL(GetFieldID, jfieldID2570, HOTSPOT_JNI_GETFIELDID_RETURN((uintptr_t)_ret_ref));2571#endif /* USDT2 */25722573JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,2574const char *name, const char *sig))2575JNIWrapper("GetFieldID");2576#ifndef USDT22577DTRACE_PROBE4(hotspot_jni, GetFieldID__entry, env, clazz, name, sig);2578#else /* USDT2 */2579HOTSPOT_JNI_GETFIELDID_ENTRY(2580env, clazz, (char *) name, (char *) sig);2581#endif /* USDT2 */2582jfieldID ret = 0;2583DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);25842585// The class should have been loaded (we have an instance of the class2586// passed in) so the field and signature should already be in the symbol2587// table. If they're not there, the field doesn't exist.2588TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));2589TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));2590if (fieldname == NULL || signame == NULL) {2591THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);2592}2593KlassHandle k(THREAD,2594java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));2595// Make sure class is initialized before handing id's out to fields2596k()->initialize(CHECK_NULL);25972598fieldDescriptor fd;2599if (!k()->oop_is_instance() ||2600!InstanceKlass::cast(k())->find_field(fieldname, signame, false, &fd)) {2601THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);2602}26032604// A jfieldID for a non-static field is simply the offset of the field within the instanceOop2605// It may also have hash bits for k, if VerifyJNIFields is turned on.2606ret = jfieldIDWorkaround::to_instance_jfieldID(k(), fd.offset());2607return ret;2608JNI_END260926102611JNI_ENTRY(jobject, jni_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID))2612JNIWrapper("GetObjectField");2613#ifndef USDT22614DTRACE_PROBE3(hotspot_jni, GetObjectField__entry, env, obj, fieldID);2615#else /* USDT2 */2616HOTSPOT_JNI_GETOBJECTFIELD_ENTRY(2617env, obj, (uintptr_t) fieldID);2618#endif /* USDT2 */2619oop o = JNIHandles::resolve_non_null(obj);2620Klass* k = o->klass();2621int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);2622// Keep JVMTI addition small and only check enabled flag here.2623// jni_GetField_probe() assumes that is okay to create handles.2624if (JvmtiExport::should_post_field_access()) {2625o = JvmtiExport::jni_GetField_probe(thread, obj, o, k, fieldID, false);2626}2627jobject ret = JNIHandles::make_local(env, o->obj_field(offset));2628#if INCLUDE_ALL_GCS2629// If G1 is enabled and we are accessing the value of the referent2630// field in a reference object then we need to register a non-null2631// referent with the SATB barrier.2632if (UseG1GC || (UseShenandoahGC && ShenandoahSATBBarrier)) {2633bool needs_barrier = false;26342635if (ret != NULL &&2636offset == java_lang_ref_Reference::referent_offset &&2637InstanceKlass::cast(k)->reference_type() != REF_NONE) {2638assert(InstanceKlass::cast(k)->is_subclass_of(SystemDictionary::Reference_klass()), "sanity");2639needs_barrier = true;2640}26412642if (needs_barrier) {2643oop referent = JNIHandles::resolve(ret);2644G1SATBCardTableModRefBS::enqueue(referent);2645}2646}2647#endif // INCLUDE_ALL_GCS2648#ifndef USDT22649DTRACE_PROBE1(hotspot_jni, GetObjectField__return, ret);2650#else /* USDT2 */2651HOTSPOT_JNI_GETOBJECTFIELD_RETURN(2652ret);2653#endif /* USDT2 */2654return ret;2655JNI_END265626572658#ifndef USDT22659#define DEFINE_GETFIELD(Return,Fieldname,Result) \2660\2661DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return);\2662\2663JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \2664JNIWrapper("Get" XSTR(Result) "Field"); \2665\2666DTRACE_PROBE3(hotspot_jni, Get##Result##Field__entry, env, obj, fieldID);\2667Return ret = 0;\2668DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\2669\2670oop o = JNIHandles::resolve_non_null(obj); \2671Klass* k = o->klass(); \2672int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \2673/* Keep JVMTI addition small and only check enabled flag here. */ \2674/* jni_GetField_probe_nh() assumes that is not okay to create handles */ \2675/* and creates a ResetNoHandleMark. */ \2676if (JvmtiExport::should_post_field_access()) { \2677o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \2678} \2679ret = o->Fieldname##_field(offset); \2680return ret; \2681JNI_END26822683DEFINE_GETFIELD(jboolean, bool, Boolean)2684DEFINE_GETFIELD(jbyte, byte, Byte)2685DEFINE_GETFIELD(jchar, char, Char)2686DEFINE_GETFIELD(jshort, short, Short)2687DEFINE_GETFIELD(jint, int, Int)2688DEFINE_GETFIELD(jlong, long, Long)2689DEFINE_GETFIELD(jfloat, float, Float)2690DEFINE_GETFIELD(jdouble, double, Double)26912692#else /* USDT2 */26932694#define DEFINE_GETFIELD(Return,Fieldname,Result \2695, EntryProbe, ReturnProbe) \2696\2697DT_RETURN_MARK_DECL_FOR(Result, Get##Result##Field, Return \2698, ReturnProbe); \2699\2700JNI_QUICK_ENTRY(Return, jni_Get##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID)) \2701JNIWrapper("Get" XSTR(Result) "Field"); \2702\2703EntryProbe; \2704Return ret = 0;\2705DT_RETURN_MARK_FOR(Result, Get##Result##Field, Return, (const Return&)ret);\2706\2707oop o = JNIHandles::resolve_non_null(obj); \2708Klass* k = o->klass(); \2709int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \2710/* Keep JVMTI addition small and only check enabled flag here. */ \2711/* jni_GetField_probe_nh() assumes that is not okay to create handles */ \2712/* and creates a ResetNoHandleMark. */ \2713if (JvmtiExport::should_post_field_access()) { \2714o = JvmtiExport::jni_GetField_probe_nh(thread, obj, o, k, fieldID, false); \2715} \2716ret = o->Fieldname##_field(offset); \2717return ret; \2718JNI_END27192720DEFINE_GETFIELD(jboolean, bool, Boolean2721, HOTSPOT_JNI_GETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2722HOTSPOT_JNI_GETBOOLEANFIELD_RETURN(_ret_ref))2723DEFINE_GETFIELD(jbyte, byte, Byte2724, HOTSPOT_JNI_GETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2725HOTSPOT_JNI_GETBYTEFIELD_RETURN(_ret_ref))2726DEFINE_GETFIELD(jchar, char, Char2727, HOTSPOT_JNI_GETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2728HOTSPOT_JNI_GETCHARFIELD_RETURN(_ret_ref))2729DEFINE_GETFIELD(jshort, short, Short2730, HOTSPOT_JNI_GETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2731HOTSPOT_JNI_GETSHORTFIELD_RETURN(_ret_ref))2732DEFINE_GETFIELD(jint, int, Int2733, HOTSPOT_JNI_GETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2734HOTSPOT_JNI_GETINTFIELD_RETURN(_ret_ref))2735DEFINE_GETFIELD(jlong, long, Long2736, HOTSPOT_JNI_GETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2737HOTSPOT_JNI_GETLONGFIELD_RETURN(_ret_ref))2738// Float and double probes don't return value because dtrace doesn't currently support it2739DEFINE_GETFIELD(jfloat, float, Float2740, HOTSPOT_JNI_GETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2741HOTSPOT_JNI_GETFLOATFIELD_RETURN())2742DEFINE_GETFIELD(jdouble, double, Double2743, HOTSPOT_JNI_GETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2744HOTSPOT_JNI_GETDOUBLEFIELD_RETURN())2745#endif /* USDT2 */27462747address jni_GetBooleanField_addr() {2748return (address)jni_GetBooleanField;2749}2750address jni_GetByteField_addr() {2751return (address)jni_GetByteField;2752}2753address jni_GetCharField_addr() {2754return (address)jni_GetCharField;2755}2756address jni_GetShortField_addr() {2757return (address)jni_GetShortField;2758}2759address jni_GetIntField_addr() {2760return (address)jni_GetIntField;2761}2762address jni_GetLongField_addr() {2763return (address)jni_GetLongField;2764}2765address jni_GetFloatField_addr() {2766return (address)jni_GetFloatField;2767}2768address jni_GetDoubleField_addr() {2769return (address)jni_GetDoubleField;2770}27712772JNI_QUICK_ENTRY(void, jni_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value))2773JNIWrapper("SetObjectField");2774#ifndef USDT22775DTRACE_PROBE4(hotspot_jni, SetObjectField__entry, env, obj, fieldID, value);2776#else /* USDT2 */2777HOTSPOT_JNI_SETOBJECTFIELD_ENTRY(2778env, obj, (uintptr_t) fieldID, value);2779#endif /* USDT2 */2780oop o = JNIHandles::resolve_non_null(obj);2781Klass* k = o->klass();2782int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);2783// Keep JVMTI addition small and only check enabled flag here.2784// jni_SetField_probe_nh() assumes that is not okay to create handles2785// and creates a ResetNoHandleMark.2786if (JvmtiExport::should_post_field_modification()) {2787jvalue field_value;2788field_value.l = value;2789o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, 'L', (jvalue *)&field_value);2790}2791o->obj_field_put(offset, JNIHandles::resolve(value));2792#ifndef USDT22793DTRACE_PROBE(hotspot_jni, SetObjectField__return);2794#else /* USDT2 */2795HOTSPOT_JNI_SETOBJECTFIELD_RETURN(2796);2797#endif /* USDT2 */2798JNI_END27992800#ifndef USDT22801#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType) \2802\2803JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \2804JNIWrapper("Set" XSTR(Result) "Field"); \2805\2806FP_SELECT_##Result( \2807DTRACE_PROBE4(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID, value), \2808DTRACE_PROBE3(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID)); \2809\2810oop o = JNIHandles::resolve_non_null(obj); \2811Klass* k = o->klass(); \2812int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \2813/* Keep JVMTI addition small and only check enabled flag here. */ \2814/* jni_SetField_probe_nh() assumes that is not okay to create handles */ \2815/* and creates a ResetNoHandleMark. */ \2816if (JvmtiExport::should_post_field_modification()) { \2817jvalue field_value; \2818field_value.unionType = value; \2819o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \2820} \2821o->Fieldname##_field_put(offset, value); \2822DTRACE_PROBE(hotspot_jni, Set##Result##Field__return);\2823JNI_END28242825DEFINE_SETFIELD(jboolean, bool, Boolean, 'Z', z)2826DEFINE_SETFIELD(jbyte, byte, Byte, 'B', b)2827DEFINE_SETFIELD(jchar, char, Char, 'C', c)2828DEFINE_SETFIELD(jshort, short, Short, 'S', s)2829DEFINE_SETFIELD(jint, int, Int, 'I', i)2830DEFINE_SETFIELD(jlong, long, Long, 'J', j)2831DEFINE_SETFIELD(jfloat, float, Float, 'F', f)2832DEFINE_SETFIELD(jdouble, double, Double, 'D', d)28332834#else /* USDT2 */28352836#define DEFINE_SETFIELD(Argument,Fieldname,Result,SigType,unionType \2837, EntryProbe, ReturnProbe) \2838\2839JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \2840JNIWrapper("Set" XSTR(Result) "Field"); \2841\2842EntryProbe; \2843\2844oop o = JNIHandles::resolve_non_null(obj); \2845Klass* k = o->klass(); \2846int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID); \2847/* Keep JVMTI addition small and only check enabled flag here. */ \2848/* jni_SetField_probe_nh() assumes that is not okay to create handles */ \2849/* and creates a ResetNoHandleMark. */ \2850if (JvmtiExport::should_post_field_modification()) { \2851jvalue field_value; \2852field_value.unionType = value; \2853o = JvmtiExport::jni_SetField_probe_nh(thread, obj, o, k, fieldID, false, SigType, (jvalue *)&field_value); \2854} \2855if (SigType == 'Z') { value = ((jboolean)value) & 1; } \2856o->Fieldname##_field_put(offset, value); \2857ReturnProbe; \2858JNI_END28592860DEFINE_SETFIELD(jboolean, bool, Boolean, 'Z', z2861, HOTSPOT_JNI_SETBOOLEANFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),2862HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())2863DEFINE_SETFIELD(jbyte, byte, Byte, 'B', b2864, HOTSPOT_JNI_SETBYTEFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),2865HOTSPOT_JNI_SETBYTEFIELD_RETURN())2866DEFINE_SETFIELD(jchar, char, Char, 'C', c2867, HOTSPOT_JNI_SETCHARFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),2868HOTSPOT_JNI_SETCHARFIELD_RETURN())2869DEFINE_SETFIELD(jshort, short, Short, 'S', s2870, HOTSPOT_JNI_SETSHORTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),2871HOTSPOT_JNI_SETSHORTFIELD_RETURN())2872DEFINE_SETFIELD(jint, int, Int, 'I', i2873, HOTSPOT_JNI_SETINTFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),2874HOTSPOT_JNI_SETINTFIELD_RETURN())2875DEFINE_SETFIELD(jlong, long, Long, 'J', j2876, HOTSPOT_JNI_SETLONGFIELD_ENTRY(env, obj, (uintptr_t)fieldID, value),2877HOTSPOT_JNI_SETLONGFIELD_RETURN())2878// Float and double probes don't return value because dtrace doesn't currently support it2879DEFINE_SETFIELD(jfloat, float, Float, 'F', f2880, HOTSPOT_JNI_SETFLOATFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2881HOTSPOT_JNI_SETFLOATFIELD_RETURN())2882DEFINE_SETFIELD(jdouble, double, Double, 'D', d2883, HOTSPOT_JNI_SETDOUBLEFIELD_ENTRY(env, obj, (uintptr_t)fieldID),2884HOTSPOT_JNI_SETDOUBLEFIELD_RETURN())2885#endif /* USDT2 */28862887#ifndef USDT22888DT_RETURN_MARK_DECL(ToReflectedField, jobject);2889#else /* USDT2 */2890DT_RETURN_MARK_DECL(ToReflectedField, jobject2891, HOTSPOT_JNI_TOREFLECTEDFIELD_RETURN(_ret_ref));2892#endif /* USDT2 */28932894JNI_ENTRY(jobject, jni_ToReflectedField(JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic))2895JNIWrapper("ToReflectedField");2896#ifndef USDT22897DTRACE_PROBE4(hotspot_jni, ToReflectedField__entry,2898env, cls, fieldID, isStatic);2899#else /* USDT2 */2900HOTSPOT_JNI_TOREFLECTEDFIELD_ENTRY(2901env, cls, (uintptr_t) fieldID, isStatic);2902#endif /* USDT2 */2903jobject ret = NULL;2904DT_RETURN_MARK(ToReflectedField, jobject, (const jobject&)ret);29052906fieldDescriptor fd;2907bool found = false;2908Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));29092910assert(jfieldIDWorkaround::is_static_jfieldID(fieldID) == (isStatic != 0), "invalid fieldID");29112912if (isStatic) {2913// Static field. The fieldID a JNIid specifying the field holder and the offset within the Klass*.2914JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);2915assert(id->is_static_field_id(), "invalid static field id");2916found = id->find_local_field(&fd);2917} else {2918// Non-static field. The fieldID is really the offset of the field within the instanceOop.2919int offset = jfieldIDWorkaround::from_instance_jfieldID(k, fieldID);2920found = InstanceKlass::cast(k)->find_field_from_offset(offset, false, &fd);2921}2922assert(found, "bad fieldID passed into jni_ToReflectedField");2923oop reflected = Reflection::new_field(&fd, UseNewReflection, CHECK_NULL);2924ret = JNIHandles::make_local(env, reflected);2925return ret;2926JNI_END292729282929//2930// Accessing Static Fields2931//2932#ifndef USDT22933DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID);2934#else /* USDT2 */2935DT_RETURN_MARK_DECL(GetStaticFieldID, jfieldID2936, HOTSPOT_JNI_GETSTATICFIELDID_RETURN((uintptr_t)_ret_ref));2937#endif /* USDT2 */29382939JNI_ENTRY(jfieldID, jni_GetStaticFieldID(JNIEnv *env, jclass clazz,2940const char *name, const char *sig))2941JNIWrapper("GetStaticFieldID");2942#ifndef USDT22943DTRACE_PROBE4(hotspot_jni, GetStaticFieldID__entry, env, clazz, name, sig);2944#else /* USDT2 */2945HOTSPOT_JNI_GETSTATICFIELDID_ENTRY(2946env, clazz, (char *) name, (char *) sig);2947#endif /* USDT2 */2948jfieldID ret = NULL;2949DT_RETURN_MARK(GetStaticFieldID, jfieldID, (const jfieldID&)ret);29502951// The class should have been loaded (we have an instance of the class2952// passed in) so the field and signature should already be in the symbol2953// table. If they're not there, the field doesn't exist.2954TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));2955TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));2956if (fieldname == NULL || signame == NULL) {2957THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);2958}2959KlassHandle k(THREAD,2960java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));2961// Make sure class is initialized before handing id's out to static fields2962k()->initialize(CHECK_NULL);29632964fieldDescriptor fd;2965if (!k()->oop_is_instance() ||2966!InstanceKlass::cast(k())->find_field(fieldname, signame, true, &fd)) {2967THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);2968}29692970// A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*2971JNIid* id = fd.field_holder()->jni_id_for(fd.offset());2972debug_only(id->set_is_static_field_id();)29732974debug_only(id->verify(fd.field_holder()));29752976ret = jfieldIDWorkaround::to_static_jfieldID(id);2977return ret;2978JNI_END297929802981JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))2982JNIWrapper("GetStaticObjectField");2983#ifndef USDT22984DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);2985#else /* USDT2 */2986HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(2987env, clazz, (uintptr_t) fieldID);2988#endif /* USDT2 */2989#if INCLUDE_JNI_CHECK2990DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)2991#endif // INCLUDE_JNI_CHECK2992JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);2993assert(id->is_static_field_id(), "invalid static field id");2994// Keep JVMTI addition small and only check enabled flag here.2995// jni_GetField_probe() assumes that is okay to create handles.2996if (JvmtiExport::should_post_field_access()) {2997JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);2998}2999jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));3000#ifndef USDT23001DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);3002#else /* USDT2 */3003HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(3004ret);3005#endif /* USDT2 */3006return ret;3007JNI_END30083009#ifndef USDT23010#define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \3011\3012DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return);\3013\3014JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \3015JNIWrapper("GetStatic" XSTR(Result) "Field"); \3016DTRACE_PROBE3(hotspot_jni, GetStatic##Result##Field__entry, env, clazz, fieldID);\3017Return ret = 0;\3018DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \3019(const Return&)ret);\3020JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \3021assert(id->is_static_field_id(), "invalid static field id"); \3022/* Keep JVMTI addition small and only check enabled flag here. */ \3023/* jni_GetField_probe() assumes that is okay to create handles. */ \3024if (JvmtiExport::should_post_field_access()) { \3025JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \3026} \3027ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \3028return ret;\3029JNI_END30303031DEFINE_GETSTATICFIELD(jboolean, bool, Boolean)3032DEFINE_GETSTATICFIELD(jbyte, byte, Byte)3033DEFINE_GETSTATICFIELD(jchar, char, Char)3034DEFINE_GETSTATICFIELD(jshort, short, Short)3035DEFINE_GETSTATICFIELD(jint, int, Int)3036DEFINE_GETSTATICFIELD(jlong, long, Long)3037DEFINE_GETSTATICFIELD(jfloat, float, Float)3038DEFINE_GETSTATICFIELD(jdouble, double, Double)30393040#else /* USDT2 */30413042#define DEFINE_GETSTATICFIELD(Return,Fieldname,Result \3043, EntryProbe, ReturnProbe) \3044\3045DT_RETURN_MARK_DECL_FOR(Result, GetStatic##Result##Field, Return \3046, ReturnProbe); \3047\3048JNI_ENTRY(Return, jni_GetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID)) \3049JNIWrapper("GetStatic" XSTR(Result) "Field"); \3050EntryProbe; \3051Return ret = 0;\3052DT_RETURN_MARK_FOR(Result, GetStatic##Result##Field, Return, \3053(const Return&)ret);\3054JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \3055assert(id->is_static_field_id(), "invalid static field id"); \3056/* Keep JVMTI addition small and only check enabled flag here. */ \3057/* jni_GetField_probe() assumes that is okay to create handles. */ \3058if (JvmtiExport::should_post_field_access()) { \3059JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true); \3060} \3061ret = id->holder()->java_mirror()-> Fieldname##_field (id->offset()); \3062return ret;\3063JNI_END30643065DEFINE_GETSTATICFIELD(jboolean, bool, Boolean3066, HOTSPOT_JNI_GETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBOOLEANFIELD_RETURN(_ret_ref))3067DEFINE_GETSTATICFIELD(jbyte, byte, Byte3068, HOTSPOT_JNI_GETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICBYTEFIELD_RETURN(_ret_ref) )3069DEFINE_GETSTATICFIELD(jchar, char, Char3070, HOTSPOT_JNI_GETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICCHARFIELD_RETURN(_ret_ref) )3071DEFINE_GETSTATICFIELD(jshort, short, Short3072, HOTSPOT_JNI_GETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICSHORTFIELD_RETURN(_ret_ref) )3073DEFINE_GETSTATICFIELD(jint, int, Int3074, HOTSPOT_JNI_GETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICINTFIELD_RETURN(_ret_ref) )3075DEFINE_GETSTATICFIELD(jlong, long, Long3076, HOTSPOT_JNI_GETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICLONGFIELD_RETURN(_ret_ref) )3077// Float and double probes don't return value because dtrace doesn't currently support it3078DEFINE_GETSTATICFIELD(jfloat, float, Float3079, HOTSPOT_JNI_GETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICFLOATFIELD_RETURN() )3080DEFINE_GETSTATICFIELD(jdouble, double, Double3081, HOTSPOT_JNI_GETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID), HOTSPOT_JNI_GETSTATICDOUBLEFIELD_RETURN() )3082#endif /* USDT2 */30833084JNI_ENTRY(void, jni_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value))3085JNIWrapper("SetStaticObjectField");3086#ifndef USDT23087DTRACE_PROBE4(hotspot_jni, SetStaticObjectField__entry, env, clazz, fieldID, value);3088#else /* USDT2 */3089HOTSPOT_JNI_SETSTATICOBJECTFIELD_ENTRY(3090env, clazz, (uintptr_t) fieldID, value);3091#endif /* USDT2 */3092JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);3093assert(id->is_static_field_id(), "invalid static field id");3094// Keep JVMTI addition small and only check enabled flag here.3095// jni_SetField_probe() assumes that is okay to create handles.3096if (JvmtiExport::should_post_field_modification()) {3097jvalue field_value;3098field_value.l = value;3099JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, 'L', (jvalue *)&field_value);3100}3101id->holder()->java_mirror()->obj_field_put(id->offset(), JNIHandles::resolve(value));3102#ifndef USDT23103DTRACE_PROBE(hotspot_jni, SetStaticObjectField__return);3104#else /* USDT2 */3105HOTSPOT_JNI_SETSTATICOBJECTFIELD_RETURN(3106);3107#endif /* USDT2 */3108JNI_END310931103111#ifndef USDT23112#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType) \3113\3114JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \3115JNIWrapper("SetStatic" XSTR(Result) "Field"); \3116FP_SELECT_##Result( \3117DTRACE_PROBE4(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID, value), \3118DTRACE_PROBE3(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID)); \3119\3120JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \3121assert(id->is_static_field_id(), "invalid static field id"); \3122/* Keep JVMTI addition small and only check enabled flag here. */ \3123/* jni_SetField_probe() assumes that is okay to create handles. */ \3124if (JvmtiExport::should_post_field_modification()) { \3125jvalue field_value; \3126field_value.unionType = value; \3127JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \3128} \3129id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \3130DTRACE_PROBE(hotspot_jni, SetStatic##Result##Field__return);\3131JNI_END31323133DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, 'Z', z)3134DEFINE_SETSTATICFIELD(jbyte, byte, Byte, 'B', b)3135DEFINE_SETSTATICFIELD(jchar, char, Char, 'C', c)3136DEFINE_SETSTATICFIELD(jshort, short, Short, 'S', s)3137DEFINE_SETSTATICFIELD(jint, int, Int, 'I', i)3138DEFINE_SETSTATICFIELD(jlong, long, Long, 'J', j)3139DEFINE_SETSTATICFIELD(jfloat, float, Float, 'F', f)3140DEFINE_SETSTATICFIELD(jdouble, double, Double, 'D', d)31413142#else /* USDT2 */31433144#define DEFINE_SETSTATICFIELD(Argument,Fieldname,Result,SigType,unionType \3145, EntryProbe, ReturnProbe) \3146\3147JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \3148JNIWrapper("SetStatic" XSTR(Result) "Field"); \3149EntryProbe; \3150\3151JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \3152assert(id->is_static_field_id(), "invalid static field id"); \3153/* Keep JVMTI addition small and only check enabled flag here. */ \3154/* jni_SetField_probe() assumes that is okay to create handles. */ \3155if (JvmtiExport::should_post_field_modification()) { \3156jvalue field_value; \3157field_value.unionType = value; \3158JvmtiExport::jni_SetField_probe(thread, NULL, NULL, id->holder(), fieldID, true, SigType, (jvalue *)&field_value); \3159} \3160if (SigType == 'Z') { value = ((jboolean)value) & 1; } \3161id->holder()->java_mirror()-> Fieldname##_field_put (id->offset(), value); \3162ReturnProbe;\3163JNI_END31643165DEFINE_SETSTATICFIELD(jboolean, bool, Boolean, 'Z', z3166, HOTSPOT_JNI_SETSTATICBOOLEANFIELD_ENTRY(env, clazz, (uintptr_t)fieldID, value),3167HOTSPOT_JNI_SETBOOLEANFIELD_RETURN())3168DEFINE_SETSTATICFIELD(jbyte, byte, Byte, 'B', b3169, HOTSPOT_JNI_SETSTATICBYTEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),3170HOTSPOT_JNI_SETSTATICBYTEFIELD_RETURN())3171DEFINE_SETSTATICFIELD(jchar, char, Char, 'C', c3172, HOTSPOT_JNI_SETSTATICCHARFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),3173HOTSPOT_JNI_SETSTATICCHARFIELD_RETURN())3174DEFINE_SETSTATICFIELD(jshort, short, Short, 'S', s3175, HOTSPOT_JNI_SETSTATICSHORTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),3176HOTSPOT_JNI_SETSTATICSHORTFIELD_RETURN())3177DEFINE_SETSTATICFIELD(jint, int, Int, 'I', i3178, HOTSPOT_JNI_SETSTATICINTFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),3179HOTSPOT_JNI_SETSTATICINTFIELD_RETURN())3180DEFINE_SETSTATICFIELD(jlong, long, Long, 'J', j3181, HOTSPOT_JNI_SETSTATICLONGFIELD_ENTRY(env, clazz, (uintptr_t) fieldID, value),3182HOTSPOT_JNI_SETSTATICLONGFIELD_RETURN())3183// Float and double probes don't return value because dtrace doesn't currently support it3184DEFINE_SETSTATICFIELD(jfloat, float, Float, 'F', f3185, HOTSPOT_JNI_SETSTATICFLOATFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),3186HOTSPOT_JNI_SETSTATICFLOATFIELD_RETURN())3187DEFINE_SETSTATICFIELD(jdouble, double, Double, 'D', d3188, HOTSPOT_JNI_SETSTATICDOUBLEFIELD_ENTRY(env, clazz, (uintptr_t) fieldID),3189HOTSPOT_JNI_SETSTATICDOUBLEFIELD_RETURN())3190#endif /* USDT2 */31913192//3193// String Operations3194//31953196// Unicode Interface31973198#ifndef USDT23199DT_RETURN_MARK_DECL(NewString, jstring);3200#else /* USDT2 */3201DT_RETURN_MARK_DECL(NewString, jstring3202, HOTSPOT_JNI_NEWSTRING_RETURN(_ret_ref));3203#endif /* USDT2 */32043205JNI_ENTRY(jstring, jni_NewString(JNIEnv *env, const jchar *unicodeChars, jsize len))3206JNIWrapper("NewString");3207#ifndef USDT23208DTRACE_PROBE3(hotspot_jni, NewString__entry, env, unicodeChars, len);3209#else /* USDT2 */3210HOTSPOT_JNI_NEWSTRING_ENTRY(3211env, (uint16_t *) unicodeChars, len);3212#endif /* USDT2 */3213jstring ret = NULL;3214DT_RETURN_MARK(NewString, jstring, (const jstring&)ret);3215oop string=java_lang_String::create_oop_from_unicode((jchar*) unicodeChars, len, CHECK_NULL);3216ret = (jstring) JNIHandles::make_local(env, string);3217return ret;3218JNI_END321932203221JNI_QUICK_ENTRY(jsize, jni_GetStringLength(JNIEnv *env, jstring string))3222JNIWrapper("GetStringLength");3223#ifndef USDT23224DTRACE_PROBE2(hotspot_jni, GetStringLength__entry, env, string);3225#else /* USDT2 */3226HOTSPOT_JNI_GETSTRINGLENGTH_ENTRY(3227env, string);3228#endif /* USDT2 */3229jsize ret = 0;3230oop s = JNIHandles::resolve_non_null(string);3231if (java_lang_String::value(s) != NULL) {3232ret = java_lang_String::length(s);3233}3234#ifndef USDT23235DTRACE_PROBE1(hotspot_jni, GetStringLength__return, ret);3236#else /* USDT2 */3237HOTSPOT_JNI_GETSTRINGLENGTH_RETURN(3238ret);3239#endif /* USDT2 */3240return ret;3241JNI_END324232433244JNI_QUICK_ENTRY(const jchar*, jni_GetStringChars(3245JNIEnv *env, jstring string, jboolean *isCopy))3246JNIWrapper("GetStringChars");3247#ifndef USDT23248DTRACE_PROBE3(hotspot_jni, GetStringChars__entry, env, string, isCopy);3249#else /* USDT2 */3250HOTSPOT_JNI_GETSTRINGCHARS_ENTRY(3251env, string, (uintptr_t *) isCopy);3252#endif /* USDT2 */3253jchar* buf = NULL;3254oop s = JNIHandles::resolve_non_null(string);3255typeArrayOop s_value = java_lang_String::value(s);3256if (s_value != NULL) {3257int s_len = java_lang_String::length(s);3258int s_offset = java_lang_String::offset(s);3259buf = NEW_C_HEAP_ARRAY_RETURN_NULL(jchar, s_len + 1, mtInternal); // add one for zero termination3260/* JNI Specification states return NULL on OOM */3261if (buf != NULL) {3262if (s_len > 0) {3263memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);3264}3265buf[s_len] = 0;3266//%note jni_53267if (isCopy != NULL) {3268*isCopy = JNI_TRUE;3269}3270}3271}3272#ifndef USDT23273DTRACE_PROBE1(hotspot_jni, GetStringChars__return, buf);3274#else /* USDT2 */3275HOTSPOT_JNI_GETSTRINGCHARS_RETURN(3276buf);3277#endif /* USDT2 */3278return buf;3279JNI_END328032813282JNI_QUICK_ENTRY(void, jni_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars))3283JNIWrapper("ReleaseStringChars");3284#ifndef USDT23285DTRACE_PROBE3(hotspot_jni, ReleaseStringChars__entry, env, str, chars);3286#else /* USDT2 */3287HOTSPOT_JNI_RELEASESTRINGCHARS_ENTRY(3288env, str, (uint16_t *) chars);3289#endif /* USDT2 */3290//%note jni_63291if (chars != NULL) {3292// Since String objects are supposed to be immutable, don't copy any3293// new data back. A bad user will have to go after the char array.3294FreeHeap((void*) chars);3295}3296#ifndef USDT23297DTRACE_PROBE(hotspot_jni, ReleaseStringChars__return);3298#else /* USDT2 */3299HOTSPOT_JNI_RELEASESTRINGCHARS_RETURN(3300);3301#endif /* USDT2 */3302JNI_END330333043305// UTF Interface33063307#ifndef USDT23308DT_RETURN_MARK_DECL(NewStringUTF, jstring);3309#else /* USDT2 */3310DT_RETURN_MARK_DECL(NewStringUTF, jstring3311, HOTSPOT_JNI_NEWSTRINGUTF_RETURN(_ret_ref));3312#endif /* USDT2 */33133314JNI_ENTRY(jstring, jni_NewStringUTF(JNIEnv *env, const char *bytes))3315JNIWrapper("NewStringUTF");3316#ifndef USDT23317DTRACE_PROBE2(hotspot_jni, NewStringUTF__entry, env, bytes);3318#else /* USDT2 */3319HOTSPOT_JNI_NEWSTRINGUTF_ENTRY(3320env, (char *) bytes);3321#endif /* USDT2 */3322jstring ret;3323DT_RETURN_MARK(NewStringUTF, jstring, (const jstring&)ret);33243325oop result = java_lang_String::create_oop_from_str((char*) bytes, CHECK_NULL);3326ret = (jstring) JNIHandles::make_local(env, result);3327return ret;3328JNI_END332933303331JNI_ENTRY(jsize, jni_GetStringUTFLength(JNIEnv *env, jstring string))3332JNIWrapper("GetStringUTFLength");3333#ifndef USDT23334DTRACE_PROBE2(hotspot_jni, GetStringUTFLength__entry, env, string);3335#else /* USDT2 */3336HOTSPOT_JNI_GETSTRINGUTFLENGTH_ENTRY(3337env, string);3338#endif /* USDT2 */3339jsize ret = 0;3340oop java_string = JNIHandles::resolve_non_null(string);3341if (java_lang_String::value(java_string) != NULL) {3342ret = java_lang_String::utf8_length(java_string);3343}3344#ifndef USDT23345DTRACE_PROBE1(hotspot_jni, GetStringUTFLength__return, ret);3346#else /* USDT2 */3347HOTSPOT_JNI_GETSTRINGUTFLENGTH_RETURN(3348ret);3349#endif /* USDT2 */3350return ret;3351JNI_END335233533354JNI_ENTRY(const char*, jni_GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy))3355JNIWrapper("GetStringUTFChars");3356#ifndef USDT23357DTRACE_PROBE3(hotspot_jni, GetStringUTFChars__entry, env, string, isCopy);3358#else /* USDT2 */3359HOTSPOT_JNI_GETSTRINGUTFCHARS_ENTRY(3360env, string, (uintptr_t *) isCopy);3361#endif /* USDT2 */3362char* result = NULL;3363oop java_string = JNIHandles::resolve_non_null(string);3364if (java_lang_String::value(java_string) != NULL) {3365size_t length = java_lang_String::utf8_length(java_string);3366/* JNI Specification states return NULL on OOM */3367result = AllocateHeap(length + 1, mtInternal, 0, AllocFailStrategy::RETURN_NULL);3368if (result != NULL) {3369java_lang_String::as_utf8_string(java_string, result, (int) length + 1);3370if (isCopy != NULL) {3371*isCopy = JNI_TRUE;3372}3373}3374}3375#ifndef USDT23376DTRACE_PROBE1(hotspot_jni, GetStringUTFChars__return, result);3377#else /* USDT2 */3378HOTSPOT_JNI_GETSTRINGUTFCHARS_RETURN(3379result);3380#endif /* USDT2 */3381return result;3382JNI_END338333843385JNI_LEAF(void, jni_ReleaseStringUTFChars(JNIEnv *env, jstring str, const char *chars))3386JNIWrapper("ReleaseStringUTFChars");3387#ifndef USDT23388DTRACE_PROBE3(hotspot_jni, ReleaseStringUTFChars__entry, env, str, chars);3389#else /* USDT2 */3390HOTSPOT_JNI_RELEASESTRINGUTFCHARS_ENTRY(3391env, str, (char *) chars);3392#endif /* USDT2 */3393if (chars != NULL) {3394FreeHeap((char*) chars);3395}3396#ifndef USDT23397DTRACE_PROBE(hotspot_jni, ReleaseStringUTFChars__return);3398#else /* USDT2 */3399HOTSPOT_JNI_RELEASESTRINGUTFCHARS_RETURN(3400);3401#endif /* USDT2 */3402JNI_END340334043405JNI_QUICK_ENTRY(jsize, jni_GetArrayLength(JNIEnv *env, jarray array))3406JNIWrapper("GetArrayLength");3407#ifndef USDT23408DTRACE_PROBE2(hotspot_jni, GetArrayLength__entry, env, array);3409#else /* USDT2 */3410HOTSPOT_JNI_GETARRAYLENGTH_ENTRY(3411env, array);3412#endif /* USDT2 */3413arrayOop a = arrayOop(JNIHandles::resolve_non_null(array));3414assert(a->is_array(), "must be array");3415jsize ret = a->length();3416#ifndef USDT23417DTRACE_PROBE1(hotspot_jni, GetArrayLength__return, ret);3418#else /* USDT2 */3419HOTSPOT_JNI_GETARRAYLENGTH_RETURN(3420ret);3421#endif /* USDT2 */3422return ret;3423JNI_END342434253426//3427// Object Array Operations3428//34293430#ifndef USDT23431DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray);3432#else /* USDT2 */3433DT_RETURN_MARK_DECL(NewObjectArray, jobjectArray3434, HOTSPOT_JNI_NEWOBJECTARRAY_RETURN(_ret_ref));3435#endif /* USDT2 */34363437JNI_ENTRY(jobjectArray, jni_NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement))3438JNIWrapper("NewObjectArray");3439#ifndef USDT23440DTRACE_PROBE4(hotspot_jni, NewObjectArray__entry, env, length, elementClass, initialElement);3441#else /* USDT2 */3442HOTSPOT_JNI_NEWOBJECTARRAY_ENTRY(3443env, length, elementClass, initialElement);3444#endif /* USDT2 */3445jobjectArray ret = NULL;3446DT_RETURN_MARK(NewObjectArray, jobjectArray, (const jobjectArray&)ret);3447KlassHandle ek(THREAD, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(elementClass)));3448Klass* ako = ek()->array_klass(CHECK_NULL);3449KlassHandle ak = KlassHandle(THREAD, ako);3450ObjArrayKlass::cast(ak())->initialize(CHECK_NULL);3451objArrayOop result = ObjArrayKlass::cast(ak())->allocate(length, CHECK_NULL);3452oop initial_value = JNIHandles::resolve(initialElement);3453if (initial_value != NULL) { // array already initialized with NULL3454for (int index = 0; index < length; index++) {3455result->obj_at_put(index, initial_value);3456}3457}3458ret = (jobjectArray) JNIHandles::make_local(env, result);3459return ret;3460JNI_END34613462#ifndef USDT23463DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject);3464#else /* USDT2 */3465DT_RETURN_MARK_DECL(GetObjectArrayElement, jobject3466, HOTSPOT_JNI_GETOBJECTARRAYELEMENT_RETURN(_ret_ref));3467#endif /* USDT2 */34683469JNI_ENTRY(jobject, jni_GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index))3470JNIWrapper("GetObjectArrayElement");3471#ifndef USDT23472DTRACE_PROBE3(hotspot_jni, GetObjectArrayElement__entry, env, array, index);3473#else /* USDT2 */3474HOTSPOT_JNI_GETOBJECTARRAYELEMENT_ENTRY(3475env, array, index);3476#endif /* USDT2 */3477jobject ret = NULL;3478DT_RETURN_MARK(GetObjectArrayElement, jobject, (const jobject&)ret);3479objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));3480if (a->is_within_bounds(index)) {3481ret = JNIHandles::make_local(env, a->obj_at(index));3482return ret;3483} else {3484char buf[jintAsStringSize];3485sprintf(buf, "%d", index);3486THROW_MSG_0(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);3487}3488JNI_END34893490#ifndef USDT23491DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement);3492#else /* USDT2 */3493DT_VOID_RETURN_MARK_DECL(SetObjectArrayElement3494, HOTSPOT_JNI_SETOBJECTARRAYELEMENT_RETURN());3495#endif /* USDT2 */34963497JNI_ENTRY(void, jni_SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject value))3498JNIWrapper("SetObjectArrayElement");3499#ifndef USDT23500DTRACE_PROBE4(hotspot_jni, SetObjectArrayElement__entry, env, array, index, value);3501#else /* USDT2 */3502HOTSPOT_JNI_SETOBJECTARRAYELEMENT_ENTRY(3503env, array, index, value);3504#endif /* USDT2 */3505DT_VOID_RETURN_MARK(SetObjectArrayElement);35063507objArrayOop a = objArrayOop(JNIHandles::resolve_non_null(array));3508oop v = JNIHandles::resolve(value);3509if (a->is_within_bounds(index)) {3510if (v == NULL || v->is_a(ObjArrayKlass::cast(a->klass())->element_klass())) {3511a->obj_at_put(index, v);3512} else {3513THROW(vmSymbols::java_lang_ArrayStoreException());3514}3515} else {3516char buf[jintAsStringSize];3517sprintf(buf, "%d", index);3518THROW_MSG(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), buf);3519}3520JNI_END352135223523#ifndef USDT23524#define DEFINE_NEWSCALARARRAY(Return,Allocator,Result) \3525\3526DT_RETURN_MARK_DECL(New##Result##Array, Return); \3527\3528JNI_ENTRY(Return, \3529jni_New##Result##Array(JNIEnv *env, jsize len)) \3530JNIWrapper("New" XSTR(Result) "Array"); \3531DTRACE_PROBE2(hotspot_jni, New##Result##Array__entry, env, len);\3532Return ret = NULL;\3533DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\3534\3535oop obj= oopFactory::Allocator(len, CHECK_0); \3536ret = (Return) JNIHandles::make_local(env, obj); \3537return ret;\3538JNI_END35393540DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray, Boolean)3541DEFINE_NEWSCALARARRAY(jbyteArray, new_byteArray, Byte)3542DEFINE_NEWSCALARARRAY(jshortArray, new_shortArray, Short)3543DEFINE_NEWSCALARARRAY(jcharArray, new_charArray, Char)3544DEFINE_NEWSCALARARRAY(jintArray, new_intArray, Int)3545DEFINE_NEWSCALARARRAY(jlongArray, new_longArray, Long)3546DEFINE_NEWSCALARARRAY(jfloatArray, new_singleArray, Float)3547DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double)35483549#else /* USDT2 */35503551#define DEFINE_NEWSCALARARRAY(Return,Allocator,Result \3552,EntryProbe,ReturnProbe) \3553\3554DT_RETURN_MARK_DECL(New##Result##Array, Return \3555, ReturnProbe); \3556\3557JNI_ENTRY(Return, \3558jni_New##Result##Array(JNIEnv *env, jsize len)) \3559JNIWrapper("New" XSTR(Result) "Array"); \3560EntryProbe; \3561Return ret = NULL;\3562DT_RETURN_MARK(New##Result##Array, Return, (const Return&)ret);\3563\3564oop obj= oopFactory::Allocator(len, CHECK_0); \3565ret = (Return) JNIHandles::make_local(env, obj); \3566return ret;\3567JNI_END35683569DEFINE_NEWSCALARARRAY(jbooleanArray, new_boolArray, Boolean,3570HOTSPOT_JNI_NEWBOOLEANARRAY_ENTRY(env, len),3571HOTSPOT_JNI_NEWBOOLEANARRAY_RETURN(_ret_ref))3572DEFINE_NEWSCALARARRAY(jbyteArray, new_byteArray, Byte,3573HOTSPOT_JNI_NEWBYTEARRAY_ENTRY(env, len),3574HOTSPOT_JNI_NEWBYTEARRAY_RETURN(_ret_ref))3575DEFINE_NEWSCALARARRAY(jshortArray, new_shortArray, Short,3576HOTSPOT_JNI_NEWSHORTARRAY_ENTRY(env, len),3577HOTSPOT_JNI_NEWSHORTARRAY_RETURN(_ret_ref))3578DEFINE_NEWSCALARARRAY(jcharArray, new_charArray, Char,3579HOTSPOT_JNI_NEWCHARARRAY_ENTRY(env, len),3580HOTSPOT_JNI_NEWCHARARRAY_RETURN(_ret_ref))3581DEFINE_NEWSCALARARRAY(jintArray, new_intArray, Int,3582HOTSPOT_JNI_NEWINTARRAY_ENTRY(env, len),3583HOTSPOT_JNI_NEWINTARRAY_RETURN(_ret_ref))3584DEFINE_NEWSCALARARRAY(jlongArray, new_longArray, Long,3585HOTSPOT_JNI_NEWLONGARRAY_ENTRY(env, len),3586HOTSPOT_JNI_NEWLONGARRAY_RETURN(_ret_ref))3587DEFINE_NEWSCALARARRAY(jfloatArray, new_singleArray, Float,3588HOTSPOT_JNI_NEWFLOATARRAY_ENTRY(env, len),3589HOTSPOT_JNI_NEWFLOATARRAY_RETURN(_ret_ref))3590DEFINE_NEWSCALARARRAY(jdoubleArray, new_doubleArray, Double,3591HOTSPOT_JNI_NEWDOUBLEARRAY_ENTRY(env, len),3592HOTSPOT_JNI_NEWDOUBLEARRAY_RETURN(_ret_ref))3593#endif /* USDT2 */35943595// Return an address which will fault if the caller writes to it.35963597static char* get_bad_address() {3598static char* bad_address = NULL;3599if (bad_address == NULL) {3600size_t size = os::vm_allocation_granularity();3601bad_address = os::reserve_memory(size);3602if (bad_address != NULL) {3603os::protect_memory(bad_address, size, os::MEM_PROT_READ,3604/*is_committed*/false);3605MemTracker::record_virtual_memory_type((void*)bad_address, mtInternal);3606}3607}3608return bad_address;3609}361036113612#ifndef USDT23613#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag) \3614\3615JNI_QUICK_ENTRY(ElementType*, \3616jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \3617JNIWrapper("Get" XSTR(Result) "ArrayElements"); \3618DTRACE_PROBE3(hotspot_jni, Get##Result##ArrayElements__entry, env, array, isCopy);\3619/* allocate an chunk of memory in c land */ \3620typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \3621ElementType* result; \3622int len = a->length(); \3623if (len == 0) { \3624/* Empty array: legal but useless, can't return NULL. \3625* Return a pointer to something useless. \3626* Avoid asserts in typeArrayOop. */ \3627result = (ElementType*)get_bad_address(); \3628} else { \3629/* JNI Specification states return NULL on OOM */ \3630result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \3631if (result != NULL) { \3632/* copy the array to the c chunk */ \3633memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \3634if (isCopy) { \3635*isCopy = JNI_TRUE; \3636} \3637} \3638} \3639DTRACE_PROBE1(hotspot_jni, Get##Result##ArrayElements__return, result);\3640return result; \3641JNI_END36423643DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)3644DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte)3645DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short)3646DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char)3647DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int)3648DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long)3649DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float)3650DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double)36513652#else /* USDT2 */36533654#define DEFINE_GETSCALARARRAYELEMENTS(ElementTag,ElementType,Result, Tag \3655, EntryProbe, ReturnProbe) \3656\3657JNI_QUICK_ENTRY(ElementType*, \3658jni_Get##Result##ArrayElements(JNIEnv *env, ElementType##Array array, jboolean *isCopy)) \3659JNIWrapper("Get" XSTR(Result) "ArrayElements"); \3660EntryProbe; \3661/* allocate an chunk of memory in c land */ \3662typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \3663ElementType* result; \3664int len = a->length(); \3665if (len == 0) { \3666/* Empty array: legal but useless, can't return NULL. \3667* Return a pointer to something useless. \3668* Avoid asserts in typeArrayOop. */ \3669result = (ElementType*)get_bad_address(); \3670} else { \3671/* JNI Specification states return NULL on OOM */ \3672result = NEW_C_HEAP_ARRAY_RETURN_NULL(ElementType, len, mtInternal); \3673if (result != NULL) { \3674/* copy the array to the c chunk */ \3675memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \3676if (isCopy) { \3677*isCopy = JNI_TRUE; \3678} \3679} \3680} \3681ReturnProbe; \3682return result; \3683JNI_END36843685DEFINE_GETSCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool3686, HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),3687HOTSPOT_JNI_GETBOOLEANARRAYELEMENTS_RETURN((uintptr_t*)result))3688DEFINE_GETSCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte3689, HOTSPOT_JNI_GETBYTEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),3690HOTSPOT_JNI_GETBYTEARRAYELEMENTS_RETURN((char*)result))3691DEFINE_GETSCALARARRAYELEMENTS(T_SHORT, jshort, Short, short3692, HOTSPOT_JNI_GETSHORTARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),3693HOTSPOT_JNI_GETSHORTARRAYELEMENTS_RETURN((uint16_t*)result))3694DEFINE_GETSCALARARRAYELEMENTS(T_CHAR, jchar, Char, char3695, HOTSPOT_JNI_GETCHARARRAYELEMENTS_ENTRY(env, (uint16_t*) array, (uintptr_t *) isCopy),3696HOTSPOT_JNI_GETCHARARRAYELEMENTS_RETURN(result))3697DEFINE_GETSCALARARRAYELEMENTS(T_INT, jint, Int, int3698, HOTSPOT_JNI_GETINTARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),3699HOTSPOT_JNI_GETINTARRAYELEMENTS_RETURN((uint32_t*)result))3700DEFINE_GETSCALARARRAYELEMENTS(T_LONG, jlong, Long, long3701, HOTSPOT_JNI_GETLONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),3702HOTSPOT_JNI_GETLONGARRAYELEMENTS_RETURN(((uintptr_t*)result)))3703// Float and double probes don't return value because dtrace doesn't currently support it3704DEFINE_GETSCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float3705, HOTSPOT_JNI_GETFLOATARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),3706HOTSPOT_JNI_GETFLOATARRAYELEMENTS_RETURN(result))3707DEFINE_GETSCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double3708, HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) isCopy),3709HOTSPOT_JNI_GETDOUBLEARRAYELEMENTS_RETURN(result))3710#endif /* USDT2 */37113712#ifndef USDT23713#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag) \3714\3715JNI_QUICK_ENTRY(void, \3716jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \3717ElementType *buf, jint mode)) \3718JNIWrapper("Release" XSTR(Result) "ArrayElements"); \3719DTRACE_PROBE4(hotspot_jni, Release##Result##ArrayElements__entry, env, array, buf, mode);\3720typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \3721int len = a->length(); \3722if (len != 0) { /* Empty array: nothing to free or copy. */ \3723if ((mode == 0) || (mode == JNI_COMMIT)) { \3724memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \3725} \3726if ((mode == 0) || (mode == JNI_ABORT)) { \3727FreeHeap(buf); \3728} \3729} \3730DTRACE_PROBE(hotspot_jni, Release##Result##ArrayElements__return);\3731JNI_END37323733DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool)3734DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte)3735DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short)3736DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char)3737DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int)3738DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long)3739DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float)3740DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double)37413742#else /* USDT2 */37433744#define DEFINE_RELEASESCALARARRAYELEMENTS(ElementTag,ElementType,Result,Tag \3745, EntryProbe, ReturnProbe);\3746\3747JNI_QUICK_ENTRY(void, \3748jni_Release##Result##ArrayElements(JNIEnv *env, ElementType##Array array, \3749ElementType *buf, jint mode)) \3750JNIWrapper("Release" XSTR(Result) "ArrayElements"); \3751EntryProbe; \3752typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \3753int len = a->length(); \3754if (len != 0) { /* Empty array: nothing to free or copy. */ \3755if ((mode == 0) || (mode == JNI_COMMIT)) { \3756memcpy(a->Tag##_at_addr(0), buf, sizeof(ElementType)*len); \3757} \3758if ((mode == 0) || (mode == JNI_ABORT)) { \3759FreeHeap(buf); \3760} \3761} \3762ReturnProbe; \3763JNI_END37643765DEFINE_RELEASESCALARARRAYELEMENTS(T_BOOLEAN, jboolean, Boolean, bool3766, HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),3767HOTSPOT_JNI_RELEASEBOOLEANARRAYELEMENTS_RETURN())3768DEFINE_RELEASESCALARARRAYELEMENTS(T_BYTE, jbyte, Byte, byte3769, HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_ENTRY(env, array, (char *) buf, mode),3770HOTSPOT_JNI_RELEASEBYTEARRAYELEMENTS_RETURN())3771DEFINE_RELEASESCALARARRAYELEMENTS(T_SHORT, jshort, Short, short3772, HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),3773HOTSPOT_JNI_RELEASESHORTARRAYELEMENTS_RETURN())3774DEFINE_RELEASESCALARARRAYELEMENTS(T_CHAR, jchar, Char, char3775, HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_ENTRY(env, array, (uint16_t *) buf, mode),3776HOTSPOT_JNI_RELEASECHARARRAYELEMENTS_RETURN())3777DEFINE_RELEASESCALARARRAYELEMENTS(T_INT, jint, Int, int3778, HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_ENTRY(env, array, (uint32_t *) buf, mode),3779HOTSPOT_JNI_RELEASEINTARRAYELEMENTS_RETURN())3780DEFINE_RELEASESCALARARRAYELEMENTS(T_LONG, jlong, Long, long3781, HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_ENTRY(env, array, (uintptr_t *) buf, mode),3782HOTSPOT_JNI_RELEASELONGARRAYELEMENTS_RETURN())3783DEFINE_RELEASESCALARARRAYELEMENTS(T_FLOAT, jfloat, Float, float3784, HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_ENTRY(env, array, (float *) buf, mode),3785HOTSPOT_JNI_RELEASEFLOATARRAYELEMENTS_RETURN())3786DEFINE_RELEASESCALARARRAYELEMENTS(T_DOUBLE, jdouble, Double, double3787, HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_ENTRY(env, array, (double *) buf, mode),3788HOTSPOT_JNI_RELEASEDOUBLEARRAYELEMENTS_RETURN())3789#endif /* USDT2 */37903791#ifndef USDT23792#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \3793DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion);\3794\3795JNI_ENTRY(void, \3796jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \3797jsize len, ElementType *buf)) \3798JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \3799DTRACE_PROBE5(hotspot_jni, Get##Result##ArrayRegion__entry, env, array, start, len, buf);\3800DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \3801typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \3802if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)src->length())) { \3803THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \3804} else { \3805if (len > 0) { \3806int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \3807memcpy((u_char*) buf, \3808(u_char*) src->Tag##_at_addr(start), \3809len << sc); \3810} \3811} \3812JNI_END38133814DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool)3815DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte)3816DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short)3817DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char)3818DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int)3819DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long)3820DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float)3821DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double)38223823#else /* USDT2 */38243825#define DEFINE_GETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \3826, EntryProbe, ReturnProbe); \3827DT_VOID_RETURN_MARK_DECL(Get##Result##ArrayRegion \3828, ReturnProbe); \3829\3830JNI_ENTRY(void, \3831jni_Get##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \3832jsize len, ElementType *buf)) \3833JNIWrapper("Get" XSTR(Result) "ArrayRegion"); \3834EntryProbe; \3835DT_VOID_RETURN_MARK(Get##Result##ArrayRegion); \3836typeArrayOop src = typeArrayOop(JNIHandles::resolve_non_null(array)); \3837if (start < 0 || len < 0 || (start > src->length() - len)) { \3838THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \3839} else { \3840if (len > 0) { \3841int sc = TypeArrayKlass::cast(src->klass())->log2_element_size(); \3842memcpy((u_char*) buf, \3843(u_char*) src->Tag##_at_addr(start), \3844len << sc); \3845} \3846} \3847JNI_END38483849DEFINE_GETSCALARARRAYREGION(T_BOOLEAN, jboolean,Boolean, bool3850, HOTSPOT_JNI_GETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),3851HOTSPOT_JNI_GETBOOLEANARRAYREGION_RETURN());3852DEFINE_GETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte3853, HOTSPOT_JNI_GETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),3854HOTSPOT_JNI_GETBYTEARRAYREGION_RETURN());3855DEFINE_GETSCALARARRAYREGION(T_SHORT, jshort, Short, short3856, HOTSPOT_JNI_GETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),3857HOTSPOT_JNI_GETSHORTARRAYREGION_RETURN());3858DEFINE_GETSCALARARRAYREGION(T_CHAR, jchar, Char, char3859, HOTSPOT_JNI_GETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t*) buf),3860HOTSPOT_JNI_GETCHARARRAYREGION_RETURN());3861DEFINE_GETSCALARARRAYREGION(T_INT, jint, Int, int3862, HOTSPOT_JNI_GETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t*) buf),3863HOTSPOT_JNI_GETINTARRAYREGION_RETURN());3864DEFINE_GETSCALARARRAYREGION(T_LONG, jlong, Long, long3865, HOTSPOT_JNI_GETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),3866HOTSPOT_JNI_GETLONGARRAYREGION_RETURN());3867DEFINE_GETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float3868, HOTSPOT_JNI_GETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),3869HOTSPOT_JNI_GETFLOATARRAYREGION_RETURN());3870DEFINE_GETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double3871, HOTSPOT_JNI_GETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),3872HOTSPOT_JNI_GETDOUBLEARRAYREGION_RETURN());3873#endif /* USDT2 */38743875#ifndef USDT23876#define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag) \3877DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion);\3878\3879JNI_ENTRY(void, \3880jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \3881jsize len, const ElementType *buf)) \3882JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \3883DTRACE_PROBE5(hotspot_jni, Set##Result##ArrayRegion__entry, env, array, start, len, buf);\3884DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \3885typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \3886if (start < 0 || len < 0 || ((unsigned int)start + (unsigned int)len > (unsigned int)dst->length())) { \3887THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \3888} else { \3889if (len > 0) { \3890int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \3891memcpy((u_char*) dst->Tag##_at_addr(start), \3892(u_char*) buf, \3893len << sc); \3894} \3895} \3896JNI_END38973898DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool)3899DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte)3900DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short)3901DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char)3902DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int)3903DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long)3904DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float)3905DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double)39063907#else /* USDT2 */39083909#define DEFINE_SETSCALARARRAYREGION(ElementTag,ElementType,Result, Tag \3910, EntryProbe, ReturnProbe); \3911DT_VOID_RETURN_MARK_DECL(Set##Result##ArrayRegion \3912,ReturnProbe); \3913\3914JNI_ENTRY(void, \3915jni_Set##Result##ArrayRegion(JNIEnv *env, ElementType##Array array, jsize start, \3916jsize len, const ElementType *buf)) \3917JNIWrapper("Set" XSTR(Result) "ArrayRegion"); \3918EntryProbe; \3919DT_VOID_RETURN_MARK(Set##Result##ArrayRegion); \3920typeArrayOop dst = typeArrayOop(JNIHandles::resolve_non_null(array)); \3921if (start < 0 || len < 0 || (start > dst->length() - len)) { \3922THROW(vmSymbols::java_lang_ArrayIndexOutOfBoundsException()); \3923} else { \3924if (len > 0) { \3925int sc = TypeArrayKlass::cast(dst->klass())->log2_element_size(); \3926memcpy((u_char*) dst->Tag##_at_addr(start), \3927(u_char*) buf, \3928len << sc); \3929} \3930} \3931JNI_END39323933DEFINE_SETSCALARARRAYREGION(T_BOOLEAN, jboolean, Boolean, bool3934, HOTSPOT_JNI_SETBOOLEANARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *)buf),3935HOTSPOT_JNI_SETBOOLEANARRAYREGION_RETURN())3936DEFINE_SETSCALARARRAYREGION(T_BYTE, jbyte, Byte, byte3937, HOTSPOT_JNI_SETBYTEARRAYREGION_ENTRY(env, array, start, len, (char *) buf),3938HOTSPOT_JNI_SETBYTEARRAYREGION_RETURN())3939DEFINE_SETSCALARARRAYREGION(T_SHORT, jshort, Short, short3940, HOTSPOT_JNI_SETSHORTARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),3941HOTSPOT_JNI_SETSHORTARRAYREGION_RETURN())3942DEFINE_SETSCALARARRAYREGION(T_CHAR, jchar, Char, char3943, HOTSPOT_JNI_SETCHARARRAYREGION_ENTRY(env, array, start, len, (uint16_t *) buf),3944HOTSPOT_JNI_SETCHARARRAYREGION_RETURN())3945DEFINE_SETSCALARARRAYREGION(T_INT, jint, Int, int3946, HOTSPOT_JNI_SETINTARRAYREGION_ENTRY(env, array, start, len, (uint32_t *) buf),3947HOTSPOT_JNI_SETINTARRAYREGION_RETURN())3948DEFINE_SETSCALARARRAYREGION(T_LONG, jlong, Long, long3949, HOTSPOT_JNI_SETLONGARRAYREGION_ENTRY(env, array, start, len, (uintptr_t *) buf),3950HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())3951DEFINE_SETSCALARARRAYREGION(T_FLOAT, jfloat, Float, float3952, HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),3953HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())3954DEFINE_SETSCALARARRAYREGION(T_DOUBLE, jdouble, Double, double3955, HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),3956HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())3957#endif /* USDT2 */395839593960//3961// Interception of natives3962//39633964// The RegisterNatives call being attempted tried to register with a method that3965// is not native. Ask JVM TI what prefixes have been specified. Then check3966// to see if the native method is now wrapped with the prefixes. See the3967// SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.3968static Method* find_prefixed_native(KlassHandle k,3969Symbol* name, Symbol* signature, TRAPS) {3970#if INCLUDE_JVMTI3971ResourceMark rm(THREAD);3972Method* method;3973int name_len = name->utf8_length();3974char* name_str = name->as_utf8();3975int prefix_count;3976char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);3977for (int i = 0; i < prefix_count; i++) {3978char* prefix = prefixes[i];3979int prefix_len = (int)strlen(prefix);39803981// try adding this prefix to the method name and see if it matches another method name3982int trial_len = name_len + prefix_len;3983char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);3984strcpy(trial_name_str, prefix);3985strcat(trial_name_str, name_str);3986TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);3987if (trial_name == NULL) {3988continue; // no such symbol, so this prefix wasn't used, try the next prefix3989}3990method = k()->lookup_method(trial_name, signature);3991if (method == NULL) {3992continue; // signature doesn't match, try the next prefix3993}3994if (method->is_native()) {3995method->set_is_prefixed_native();3996return method; // wahoo, we found a prefixed version of the method, return it3997}3998// found as non-native, so prefix is good, add it, probably just need more prefixes3999name_len = trial_len;4000name_str = trial_name_str;4001}4002#endif // INCLUDE_JVMTI4003return NULL; // not found4004}40054006static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {4007Method* method = k()->lookup_method(name, signature);4008if (method == NULL) {4009ResourceMark rm;4010stringStream st;4011st.print("Method %s name or signature does not match",4012Method::name_and_sig_as_C_string(k(), name, signature));4013THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);4014}4015if (!method->is_native()) {4016// trying to register to a non-native method, see if a JVM TI agent has added prefix(es)4017method = find_prefixed_native(k, name, signature, THREAD);4018if (method == NULL) {4019ResourceMark rm;4020stringStream st;4021st.print("Method %s is not declared as native",4022Method::name_and_sig_as_C_string(k(), name, signature));4023THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);4024}4025}40264027if (entry != NULL) {4028method->set_native_function(entry,4029Method::native_bind_event_is_interesting);4030} else {4031method->clear_native_function();4032}4033if (PrintJNIResolving) {4034ResourceMark rm(THREAD);4035tty->print_cr("[Registering JNI native method %s.%s]",4036method->method_holder()->external_name(),4037method->name()->as_C_string());4038}4039return true;4040}40414042#ifndef USDT24043DT_RETURN_MARK_DECL(RegisterNatives, jint);4044#else /* USDT2 */4045DT_RETURN_MARK_DECL(RegisterNatives, jint4046, HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref));4047#endif /* USDT2 */40484049JNI_ENTRY(jint, jni_RegisterNatives(JNIEnv *env, jclass clazz,4050const JNINativeMethod *methods,4051jint nMethods))4052JNIWrapper("RegisterNatives");4053#ifndef USDT24054DTRACE_PROBE4(hotspot_jni, RegisterNatives__entry, env, clazz, methods, nMethods);4055#else /* USDT2 */4056HOTSPOT_JNI_REGISTERNATIVES_ENTRY(4057env, clazz, (void *) methods, nMethods);4058#endif /* USDT2 */4059jint ret = 0;4060DT_RETURN_MARK(RegisterNatives, jint, (const jint&)ret);40614062KlassHandle h_k(thread, java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));40634064for (int index = 0; index < nMethods; index++) {4065const char* meth_name = methods[index].name;4066const char* meth_sig = methods[index].signature;4067int meth_name_len = (int)strlen(meth_name);40684069// The class should have been loaded (we have an instance of the class4070// passed in) so the method and signature should already be in the symbol4071// table. If they're not there, the method doesn't exist.4072TempNewSymbol name = SymbolTable::probe(meth_name, meth_name_len);4073TempNewSymbol signature = SymbolTable::probe(meth_sig, (int)strlen(meth_sig));40744075if (name == NULL || signature == NULL) {4076ResourceMark rm;4077stringStream st;4078st.print("Method %s.%s%s not found", h_k()->external_name(), meth_name, meth_sig);4079// Must return negative value on failure4080THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1);4081}40824083bool res = register_native(h_k, name, signature,4084(address) methods[index].fnPtr, THREAD);4085if (!res) {4086ret = -1;4087break;4088}4089}4090return ret;4091JNI_END409240934094JNI_ENTRY(jint, jni_UnregisterNatives(JNIEnv *env, jclass clazz))4095JNIWrapper("UnregisterNatives");4096#ifndef USDT24097DTRACE_PROBE2(hotspot_jni, UnregisterNatives__entry, env, clazz);4098#else /* USDT2 */4099HOTSPOT_JNI_UNREGISTERNATIVES_ENTRY(4100env, clazz);4101#endif /* USDT2 */4102Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));4103//%note jni_24104if (k->oop_is_instance()) {4105for (int index = 0; index < InstanceKlass::cast(k)->methods()->length(); index++) {4106Method* m = InstanceKlass::cast(k)->methods()->at(index);4107if (m->is_native()) {4108m->clear_native_function();4109m->set_signature_handler(NULL);4110}4111}4112}4113#ifndef USDT24114DTRACE_PROBE1(hotspot_jni, UnregisterNatives__return, 0);4115#else /* USDT2 */4116HOTSPOT_JNI_UNREGISTERNATIVES_RETURN(41170);4118#endif /* USDT2 */4119return 0;4120JNI_END41214122//4123// Monitor functions4124//41254126#ifndef USDT24127DT_RETURN_MARK_DECL(MonitorEnter, jint);4128#else /* USDT2 */4129DT_RETURN_MARK_DECL(MonitorEnter, jint4130, HOTSPOT_JNI_MONITORENTER_RETURN(_ret_ref));4131#endif /* USDT2 */41324133JNI_ENTRY(jint, jni_MonitorEnter(JNIEnv *env, jobject jobj))4134#ifndef USDT24135DTRACE_PROBE2(hotspot_jni, MonitorEnter__entry, env, jobj);4136#else /* USDT2 */4137HOTSPOT_JNI_MONITORENTER_ENTRY(4138env, jobj);4139#endif /* USDT2 */4140jint ret = JNI_ERR;4141DT_RETURN_MARK(MonitorEnter, jint, (const jint&)ret);41424143// If the object is null, we can't do anything with it4144if (jobj == NULL) {4145THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);4146}41474148Handle obj(thread, JNIHandles::resolve_non_null(jobj));4149ObjectSynchronizer::jni_enter(obj, CHECK_(JNI_ERR));4150ret = JNI_OK;4151return ret;4152JNI_END41534154#ifndef USDT24155DT_RETURN_MARK_DECL(MonitorExit, jint);4156#else /* USDT2 */4157DT_RETURN_MARK_DECL(MonitorExit, jint4158, HOTSPOT_JNI_MONITOREXIT_RETURN(_ret_ref));4159#endif /* USDT2 */41604161JNI_ENTRY(jint, jni_MonitorExit(JNIEnv *env, jobject jobj))4162#ifndef USDT24163DTRACE_PROBE2(hotspot_jni, MonitorExit__entry, env, jobj);4164#else /* USDT2 */4165HOTSPOT_JNI_MONITOREXIT_ENTRY(4166env, jobj);4167#endif /* USDT2 */4168jint ret = JNI_ERR;4169DT_RETURN_MARK(MonitorExit, jint, (const jint&)ret);41704171// Don't do anything with a null object4172if (jobj == NULL) {4173THROW_(vmSymbols::java_lang_NullPointerException(), JNI_ERR);4174}41754176Handle obj(THREAD, JNIHandles::resolve_non_null(jobj));4177ObjectSynchronizer::jni_exit(obj(), CHECK_(JNI_ERR));41784179ret = JNI_OK;4180return ret;4181JNI_END41824183//4184// Extensions4185//41864187#ifndef USDT24188DT_VOID_RETURN_MARK_DECL(GetStringRegion);4189#else /* USDT2 */4190DT_VOID_RETURN_MARK_DECL(GetStringRegion4191, HOTSPOT_JNI_GETSTRINGREGION_RETURN());4192#endif /* USDT2 */41934194JNI_ENTRY(void, jni_GetStringRegion(JNIEnv *env, jstring string, jsize start, jsize len, jchar *buf))4195JNIWrapper("GetStringRegion");4196#ifndef USDT24197DTRACE_PROBE5(hotspot_jni, GetStringRegion__entry, env, string, start, len, buf);4198#else /* USDT2 */4199HOTSPOT_JNI_GETSTRINGREGION_ENTRY(4200env, string, start, len, buf);4201#endif /* USDT2 */4202DT_VOID_RETURN_MARK(GetStringRegion);4203oop s = JNIHandles::resolve_non_null(string);4204int s_len = java_lang_String::length(s);4205if (start < 0 || len < 0 || start > s_len - len) {4206THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());4207} else {4208if (len > 0) {4209int s_offset = java_lang_String::offset(s);4210typeArrayOop s_value = java_lang_String::value(s);4211memcpy(buf, s_value->char_at_addr(s_offset+start), sizeof(jchar)*len);4212}4213}4214JNI_END42154216#ifndef USDT24217DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion);4218#else /* USDT2 */4219DT_VOID_RETURN_MARK_DECL(GetStringUTFRegion4220, HOTSPOT_JNI_GETSTRINGUTFREGION_RETURN());4221#endif /* USDT2 */42224223JNI_ENTRY(void, jni_GetStringUTFRegion(JNIEnv *env, jstring string, jsize start, jsize len, char *buf))4224JNIWrapper("GetStringUTFRegion");4225#ifndef USDT24226DTRACE_PROBE5(hotspot_jni, GetStringUTFRegion__entry, env, string, start, len, buf);4227#else /* USDT2 */4228HOTSPOT_JNI_GETSTRINGUTFREGION_ENTRY(4229env, string, start, len, buf);4230#endif /* USDT2 */4231DT_VOID_RETURN_MARK(GetStringUTFRegion);4232oop s = JNIHandles::resolve_non_null(string);4233int s_len = java_lang_String::length(s);4234if (start < 0 || len < 0 || start > s_len - len) {4235THROW(vmSymbols::java_lang_StringIndexOutOfBoundsException());4236} else {4237//%note jni_74238if (len > 0) {4239ResourceMark rm(THREAD);4240char *utf_region = java_lang_String::as_utf8_string(s, start, len);4241int utf_len = (int)strlen(utf_region);4242memcpy(buf, utf_region, utf_len);4243buf[utf_len] = 0;4244} else {4245// JDK null-terminates the buffer even in len is zero4246if (buf != NULL) {4247buf[0] = 0;4248}4249}4250}4251JNI_END42524253static oop lock_gc_or_pin_object(JavaThread* thread, jobject obj) {4254if (Universe::heap()->supports_object_pinning()) {4255const oop o = JNIHandles::resolve_non_null(obj);4256return Universe::heap()->pin_object(thread, o);4257} else {4258GC_locker::lock_critical(thread);4259return JNIHandles::resolve_non_null(obj);4260}4261}42624263static void unlock_gc_or_unpin_object(JavaThread* thread, jobject obj) {4264if (Universe::heap()->supports_object_pinning()) {4265const oop o = JNIHandles::resolve_non_null(obj);4266return Universe::heap()->unpin_object(thread, o);4267} else {4268GC_locker::unlock_critical(thread);4269}4270}42714272JNI_ENTRY(void*, jni_GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy))4273JNIWrapper("GetPrimitiveArrayCritical");4274#ifndef USDT24275DTRACE_PROBE3(hotspot_jni, GetPrimitiveArrayCritical__entry, env, array, isCopy);4276#else /* USDT2 */4277HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_ENTRY(4278env, array, (uintptr_t *) isCopy);4279#endif /* USDT2 */4280if (isCopy != NULL) {4281*isCopy = JNI_FALSE;4282}4283oop a = lock_gc_or_pin_object(thread, array);4284assert(a->is_array(), "just checking");4285BasicType type;4286if (a->is_objArray()) {4287type = T_OBJECT;4288} else {4289type = TypeArrayKlass::cast(a->klass())->element_type();4290}4291void* ret = arrayOop(a)->base(type);4292#ifndef USDT24293DTRACE_PROBE1(hotspot_jni, GetPrimitiveArrayCritical__return, ret);4294#else /* USDT2 */4295HOTSPOT_JNI_GETPRIMITIVEARRAYCRITICAL_RETURN(4296ret);4297#endif /* USDT2 */4298return ret;4299JNI_END430043014302JNI_ENTRY(void, jni_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray, jint mode))4303JNIWrapper("ReleasePrimitiveArrayCritical");4304#ifndef USDT24305DTRACE_PROBE4(hotspot_jni, ReleasePrimitiveArrayCritical__entry, env, array, carray, mode);4306#else /* USDT2 */4307HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_ENTRY(4308env, array, carray, mode);4309#endif /* USDT2 */4310// The array, carray and mode arguments are ignored4311unlock_gc_or_unpin_object(thread, array);4312#ifndef USDT24313DTRACE_PROBE(hotspot_jni, ReleasePrimitiveArrayCritical__return);4314#else /* USDT2 */4315HOTSPOT_JNI_RELEASEPRIMITIVEARRAYCRITICAL_RETURN(4316);4317#endif /* USDT2 */4318JNI_END431943204321JNI_ENTRY(const jchar*, jni_GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy))4322JNIWrapper("GetStringCritical");4323#ifndef USDT24324DTRACE_PROBE3(hotspot_jni, GetStringCritical__entry, env, string, isCopy);4325#else /* USDT2 */4326HOTSPOT_JNI_GETSTRINGCRITICAL_ENTRY(4327env, string, (uintptr_t *) isCopy);4328#endif /* USDT2 */4329if (isCopy != NULL) {4330*isCopy = JNI_FALSE;4331}4332oop s = lock_gc_or_pin_object(thread, string);4333int s_len = java_lang_String::length(s);4334typeArrayOop s_value = java_lang_String::value(s);4335int s_offset = java_lang_String::offset(s);4336const jchar* ret;4337if (s_len > 0) {4338ret = s_value->char_at_addr(s_offset);4339} else {4340ret = (jchar*) s_value->base(T_CHAR);4341}4342#ifndef USDT24343DTRACE_PROBE1(hotspot_jni, GetStringCritical__return, ret);4344#else /* USDT2 */4345HOTSPOT_JNI_GETSTRINGCRITICAL_RETURN(4346(uint16_t *) ret);4347#endif /* USDT2 */4348return ret;4349JNI_END435043514352JNI_ENTRY(void, jni_ReleaseStringCritical(JNIEnv *env, jstring str, const jchar *chars))4353JNIWrapper("ReleaseStringCritical");4354#ifndef USDT24355DTRACE_PROBE3(hotspot_jni, ReleaseStringCritical__entry, env, str, chars);4356#else /* USDT2 */4357HOTSPOT_JNI_RELEASESTRINGCRITICAL_ENTRY(4358env, str, (uint16_t *) chars);4359#endif /* USDT2 */4360// The str and chars arguments are ignored4361unlock_gc_or_unpin_object(thread, str);4362#ifndef USDT24363DTRACE_PROBE(hotspot_jni, ReleaseStringCritical__return);4364#else /* USDT2 */4365HOTSPOT_JNI_RELEASESTRINGCRITICAL_RETURN(4366);4367#endif /* USDT2 */4368JNI_END436943704371JNI_ENTRY(jweak, jni_NewWeakGlobalRef(JNIEnv *env, jobject ref))4372JNIWrapper("jni_NewWeakGlobalRef");4373#ifndef USDT24374DTRACE_PROBE2(hotspot_jni, NewWeakGlobalRef__entry, env, ref);4375#else /* USDT2 */4376HOTSPOT_JNI_NEWWEAKGLOBALREF_ENTRY(4377env, ref);4378#endif /* USDT2 */4379Handle ref_handle(thread, JNIHandles::resolve(ref));4380jweak ret = JNIHandles::make_weak_global(ref_handle);4381#ifndef USDT24382DTRACE_PROBE1(hotspot_jni, NewWeakGlobalRef__return, ret);4383#else /* USDT2 */4384HOTSPOT_JNI_NEWWEAKGLOBALREF_RETURN(4385ret);4386#endif /* USDT2 */4387return ret;4388JNI_END43894390// Must be JNI_ENTRY (with HandleMark)4391JNI_ENTRY(void, jni_DeleteWeakGlobalRef(JNIEnv *env, jweak ref))4392JNIWrapper("jni_DeleteWeakGlobalRef");4393#ifndef USDT24394DTRACE_PROBE2(hotspot_jni, DeleteWeakGlobalRef__entry, env, ref);4395#else /* USDT2 */4396HOTSPOT_JNI_DELETEWEAKGLOBALREF_ENTRY(4397env, ref);4398#endif /* USDT2 */4399JNIHandles::destroy_weak_global(ref);4400#ifndef USDT24401DTRACE_PROBE(hotspot_jni, DeleteWeakGlobalRef__return);4402#else /* USDT2 */4403HOTSPOT_JNI_DELETEWEAKGLOBALREF_RETURN(4404);4405#endif /* USDT2 */4406JNI_END440744084409JNI_QUICK_ENTRY(jboolean, jni_ExceptionCheck(JNIEnv *env))4410JNIWrapper("jni_ExceptionCheck");4411#ifndef USDT24412DTRACE_PROBE1(hotspot_jni, ExceptionCheck__entry, env);4413#else /* USDT2 */4414HOTSPOT_JNI_EXCEPTIONCHECK_ENTRY(4415env);4416#endif /* USDT2 */4417jni_check_async_exceptions(thread);4418jboolean ret = (thread->has_pending_exception()) ? JNI_TRUE : JNI_FALSE;4419#ifndef USDT24420DTRACE_PROBE1(hotspot_jni, ExceptionCheck__return, ret);4421#else /* USDT2 */4422HOTSPOT_JNI_EXCEPTIONCHECK_RETURN(4423ret);4424#endif /* USDT2 */4425return ret;4426JNI_END442744284429// Initialization state for three routines below relating to4430// java.nio.DirectBuffers4431static jint directBufferSupportInitializeStarted = 0;4432static volatile jint directBufferSupportInitializeEnded = 0;4433static volatile jint directBufferSupportInitializeFailed = 0;4434static jclass bufferClass = NULL;4435static jclass directBufferClass = NULL;4436static jclass directByteBufferClass = NULL;4437static jmethodID directByteBufferConstructor = NULL;4438static jfieldID directBufferAddressField = NULL;4439static jfieldID bufferCapacityField = NULL;44404441static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) {4442Handle loader; // null (bootstrap) loader4443Handle protection_domain; // null protection domain44444445TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);4446jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);44474448if (TraceClassResolution && result != NULL) {4449trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result)));4450}4451return result;4452}44534454// These lookups are done with the NULL (bootstrap) ClassLoader to4455// circumvent any security checks that would be done by jni_FindClass.4456JNI_ENTRY(bool, lookupDirectBufferClasses(JNIEnv* env))4457{4458if ((bufferClass = lookupOne(env, "java/nio/Buffer", thread)) == NULL) { return false; }4459if ((directBufferClass = lookupOne(env, "sun/nio/ch/DirectBuffer", thread)) == NULL) { return false; }4460if ((directByteBufferClass = lookupOne(env, "java/nio/DirectByteBuffer", thread)) == NULL) { return false; }4461return true;4462}4463JNI_END446444654466static bool initializeDirectBufferSupport(JNIEnv* env, JavaThread* thread) {4467if (directBufferSupportInitializeFailed) {4468return false;4469}44704471if (Atomic::cmpxchg(1, &directBufferSupportInitializeStarted, 0) == 0) {4472if (!lookupDirectBufferClasses(env)) {4473directBufferSupportInitializeFailed = 1;4474return false;4475}44764477// Make global references for these4478bufferClass = (jclass) env->NewGlobalRef(bufferClass);4479directBufferClass = (jclass) env->NewGlobalRef(directBufferClass);4480directByteBufferClass = (jclass) env->NewGlobalRef(directByteBufferClass);44814482// Get needed field and method IDs4483directByteBufferConstructor = env->GetMethodID(directByteBufferClass, "<init>", "(JI)V");4484if (env->ExceptionCheck()) {4485env->ExceptionClear();4486directBufferSupportInitializeFailed = 1;4487return false;4488}4489directBufferAddressField = env->GetFieldID(bufferClass, "address", "J");4490if (env->ExceptionCheck()) {4491env->ExceptionClear();4492directBufferSupportInitializeFailed = 1;4493return false;4494}4495bufferCapacityField = env->GetFieldID(bufferClass, "capacity", "I");4496if (env->ExceptionCheck()) {4497env->ExceptionClear();4498directBufferSupportInitializeFailed = 1;4499return false;4500}45014502if ((directByteBufferConstructor == NULL) ||4503(directBufferAddressField == NULL) ||4504(bufferCapacityField == NULL)) {4505directBufferSupportInitializeFailed = 1;4506return false;4507}45084509directBufferSupportInitializeEnded = 1;4510} else {4511while (!directBufferSupportInitializeEnded && !directBufferSupportInitializeFailed) {4512// Set state as yield_all can call os:sleep. On Solaris, yield_all calls4513// os::sleep which requires the VM state transition. On other platforms, it4514// is not necessary. The following call to change the VM state is purposely4515// put inside the loop to avoid potential deadlock when multiple threads4516// try to call this method. See 6791815 for more details.4517ThreadInVMfromNative tivn(thread);4518os::yield_all();4519}4520}45214522return !directBufferSupportInitializeFailed;4523}45244525extern "C" jobject JNICALL jni_NewDirectByteBuffer(JNIEnv *env, void* address, jlong capacity)4526{4527// thread_from_jni_environment() will block if VM is gone.4528JavaThread* thread = JavaThread::thread_from_jni_environment(env);45294530JNIWrapper("jni_NewDirectByteBuffer");4531#ifndef USDT24532DTRACE_PROBE3(hotspot_jni, NewDirectByteBuffer__entry, env, address, capacity);4533#else /* USDT2 */4534HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_ENTRY(4535env, address, capacity);4536#endif /* USDT2 */45374538if (!directBufferSupportInitializeEnded) {4539if (!initializeDirectBufferSupport(env, thread)) {4540#ifndef USDT24541DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, NULL);4542#else /* USDT2 */4543HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(4544NULL);4545#endif /* USDT2 */4546return NULL;4547}4548}45494550// Being paranoid about accidental sign extension on address4551jlong addr = (jlong) ((uintptr_t) address);4552// NOTE that package-private DirectByteBuffer constructor currently4553// takes int capacity4554jint cap = (jint) capacity;4555jobject ret = env->NewObject(directByteBufferClass, directByteBufferConstructor, addr, cap);4556#ifndef USDT24557DTRACE_PROBE1(hotspot_jni, NewDirectByteBuffer__return, ret);4558#else /* USDT2 */4559HOTSPOT_JNI_NEWDIRECTBYTEBUFFER_RETURN(4560ret);4561#endif /* USDT2 */4562return ret;4563}45644565#ifndef USDT24566DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*);4567#else /* USDT2 */4568DT_RETURN_MARK_DECL(GetDirectBufferAddress, void*4569, HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_RETURN((void*) _ret_ref));4570#endif /* USDT2 */45714572extern "C" void* JNICALL jni_GetDirectBufferAddress(JNIEnv *env, jobject buf)4573{4574// thread_from_jni_environment() will block if VM is gone.4575JavaThread* thread = JavaThread::thread_from_jni_environment(env);45764577JNIWrapper("jni_GetDirectBufferAddress");4578#ifndef USDT24579DTRACE_PROBE2(hotspot_jni, GetDirectBufferAddress__entry, env, buf);4580#else /* USDT2 */4581HOTSPOT_JNI_GETDIRECTBUFFERADDRESS_ENTRY(4582env, buf);4583#endif /* USDT2 */4584void* ret = NULL;4585DT_RETURN_MARK(GetDirectBufferAddress, void*, (const void*&)ret);45864587if (!directBufferSupportInitializeEnded) {4588if (!initializeDirectBufferSupport(env, thread)) {4589return 0;4590}4591}45924593if ((buf != NULL) && (!env->IsInstanceOf(buf, directBufferClass))) {4594return 0;4595}45964597ret = (void*)(intptr_t)env->GetLongField(buf, directBufferAddressField);4598return ret;4599}46004601#ifndef USDT24602DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong);4603#else /* USDT2 */4604DT_RETURN_MARK_DECL(GetDirectBufferCapacity, jlong4605, HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_RETURN(_ret_ref));4606#endif /* USDT2 */46074608extern "C" jlong JNICALL jni_GetDirectBufferCapacity(JNIEnv *env, jobject buf)4609{4610// thread_from_jni_environment() will block if VM is gone.4611JavaThread* thread = JavaThread::thread_from_jni_environment(env);46124613JNIWrapper("jni_GetDirectBufferCapacity");4614#ifndef USDT24615DTRACE_PROBE2(hotspot_jni, GetDirectBufferCapacity__entry, env, buf);4616#else /* USDT2 */4617HOTSPOT_JNI_GETDIRECTBUFFERCAPACITY_ENTRY(4618env, buf);4619#endif /* USDT2 */4620jlong ret = -1;4621DT_RETURN_MARK(GetDirectBufferCapacity, jlong, (const jlong&)ret);46224623if (!directBufferSupportInitializeEnded) {4624if (!initializeDirectBufferSupport(env, thread)) {4625ret = 0;4626return ret;4627}4628}46294630if (buf == NULL) {4631return -1;4632}46334634if (!env->IsInstanceOf(buf, directBufferClass)) {4635return -1;4636}46374638// NOTE that capacity is currently an int in the implementation4639ret = env->GetIntField(buf, bufferCapacityField);4640return ret;4641}464246434644JNI_LEAF(jint, jni_GetVersion(JNIEnv *env))4645JNIWrapper("GetVersion");4646#ifndef USDT24647DTRACE_PROBE1(hotspot_jni, GetVersion__entry, env);4648#else /* USDT2 */4649HOTSPOT_JNI_GETVERSION_ENTRY(4650env);4651#endif /* USDT2 */4652#ifndef USDT24653DTRACE_PROBE1(hotspot_jni, GetVersion__return, CurrentVersion);4654#else /* USDT2 */4655HOTSPOT_JNI_GETVERSION_RETURN(4656CurrentVersion);4657#endif /* USDT2 */4658return CurrentVersion;4659JNI_END46604661extern struct JavaVM_ main_vm;46624663JNI_LEAF(jint, jni_GetJavaVM(JNIEnv *env, JavaVM **vm))4664JNIWrapper("jni_GetJavaVM");4665#ifndef USDT24666DTRACE_PROBE2(hotspot_jni, GetJavaVM__entry, env, vm);4667#else /* USDT2 */4668HOTSPOT_JNI_GETJAVAVM_ENTRY(4669env, (void **) vm);4670#endif /* USDT2 */4671*vm = (JavaVM *)(&main_vm);4672#ifndef USDT24673DTRACE_PROBE1(hotspot_jni, GetJavaVM__return, JNI_OK);4674#else /* USDT2 */4675HOTSPOT_JNI_GETJAVAVM_RETURN(4676JNI_OK);4677#endif /* USDT2 */4678return JNI_OK;4679JNI_END46804681// Structure containing all jni functions4682struct JNINativeInterface_ jni_NativeInterface = {4683NULL,4684NULL,4685NULL,46864687NULL,46884689jni_GetVersion,46904691jni_DefineClass,4692jni_FindClass,46934694jni_FromReflectedMethod,4695jni_FromReflectedField,46964697jni_ToReflectedMethod,46984699jni_GetSuperclass,4700jni_IsAssignableFrom,47014702jni_ToReflectedField,47034704jni_Throw,4705jni_ThrowNew,4706jni_ExceptionOccurred,4707jni_ExceptionDescribe,4708jni_ExceptionClear,4709jni_FatalError,47104711jni_PushLocalFrame,4712jni_PopLocalFrame,47134714jni_NewGlobalRef,4715jni_DeleteGlobalRef,4716jni_DeleteLocalRef,4717jni_IsSameObject,47184719jni_NewLocalRef,4720jni_EnsureLocalCapacity,47214722jni_AllocObject,4723jni_NewObject,4724jni_NewObjectV,4725jni_NewObjectA,47264727jni_GetObjectClass,4728jni_IsInstanceOf,47294730jni_GetMethodID,47314732jni_CallObjectMethod,4733jni_CallObjectMethodV,4734jni_CallObjectMethodA,4735jni_CallBooleanMethod,4736jni_CallBooleanMethodV,4737jni_CallBooleanMethodA,4738jni_CallByteMethod,4739jni_CallByteMethodV,4740jni_CallByteMethodA,4741jni_CallCharMethod,4742jni_CallCharMethodV,4743jni_CallCharMethodA,4744jni_CallShortMethod,4745jni_CallShortMethodV,4746jni_CallShortMethodA,4747jni_CallIntMethod,4748jni_CallIntMethodV,4749jni_CallIntMethodA,4750jni_CallLongMethod,4751jni_CallLongMethodV,4752jni_CallLongMethodA,4753jni_CallFloatMethod,4754jni_CallFloatMethodV,4755jni_CallFloatMethodA,4756jni_CallDoubleMethod,4757jni_CallDoubleMethodV,4758jni_CallDoubleMethodA,4759jni_CallVoidMethod,4760jni_CallVoidMethodV,4761jni_CallVoidMethodA,47624763jni_CallNonvirtualObjectMethod,4764jni_CallNonvirtualObjectMethodV,4765jni_CallNonvirtualObjectMethodA,4766jni_CallNonvirtualBooleanMethod,4767jni_CallNonvirtualBooleanMethodV,4768jni_CallNonvirtualBooleanMethodA,4769jni_CallNonvirtualByteMethod,4770jni_CallNonvirtualByteMethodV,4771jni_CallNonvirtualByteMethodA,4772jni_CallNonvirtualCharMethod,4773jni_CallNonvirtualCharMethodV,4774jni_CallNonvirtualCharMethodA,4775jni_CallNonvirtualShortMethod,4776jni_CallNonvirtualShortMethodV,4777jni_CallNonvirtualShortMethodA,4778jni_CallNonvirtualIntMethod,4779jni_CallNonvirtualIntMethodV,4780jni_CallNonvirtualIntMethodA,4781jni_CallNonvirtualLongMethod,4782jni_CallNonvirtualLongMethodV,4783jni_CallNonvirtualLongMethodA,4784jni_CallNonvirtualFloatMethod,4785jni_CallNonvirtualFloatMethodV,4786jni_CallNonvirtualFloatMethodA,4787jni_CallNonvirtualDoubleMethod,4788jni_CallNonvirtualDoubleMethodV,4789jni_CallNonvirtualDoubleMethodA,4790jni_CallNonvirtualVoidMethod,4791jni_CallNonvirtualVoidMethodV,4792jni_CallNonvirtualVoidMethodA,47934794jni_GetFieldID,47954796jni_GetObjectField,4797jni_GetBooleanField,4798jni_GetByteField,4799jni_GetCharField,4800jni_GetShortField,4801jni_GetIntField,4802jni_GetLongField,4803jni_GetFloatField,4804jni_GetDoubleField,48054806jni_SetObjectField,4807jni_SetBooleanField,4808jni_SetByteField,4809jni_SetCharField,4810jni_SetShortField,4811jni_SetIntField,4812jni_SetLongField,4813jni_SetFloatField,4814jni_SetDoubleField,48154816jni_GetStaticMethodID,48174818jni_CallStaticObjectMethod,4819jni_CallStaticObjectMethodV,4820jni_CallStaticObjectMethodA,4821jni_CallStaticBooleanMethod,4822jni_CallStaticBooleanMethodV,4823jni_CallStaticBooleanMethodA,4824jni_CallStaticByteMethod,4825jni_CallStaticByteMethodV,4826jni_CallStaticByteMethodA,4827jni_CallStaticCharMethod,4828jni_CallStaticCharMethodV,4829jni_CallStaticCharMethodA,4830jni_CallStaticShortMethod,4831jni_CallStaticShortMethodV,4832jni_CallStaticShortMethodA,4833jni_CallStaticIntMethod,4834jni_CallStaticIntMethodV,4835jni_CallStaticIntMethodA,4836jni_CallStaticLongMethod,4837jni_CallStaticLongMethodV,4838jni_CallStaticLongMethodA,4839jni_CallStaticFloatMethod,4840jni_CallStaticFloatMethodV,4841jni_CallStaticFloatMethodA,4842jni_CallStaticDoubleMethod,4843jni_CallStaticDoubleMethodV,4844jni_CallStaticDoubleMethodA,4845jni_CallStaticVoidMethod,4846jni_CallStaticVoidMethodV,4847jni_CallStaticVoidMethodA,48484849jni_GetStaticFieldID,48504851jni_GetStaticObjectField,4852jni_GetStaticBooleanField,4853jni_GetStaticByteField,4854jni_GetStaticCharField,4855jni_GetStaticShortField,4856jni_GetStaticIntField,4857jni_GetStaticLongField,4858jni_GetStaticFloatField,4859jni_GetStaticDoubleField,48604861jni_SetStaticObjectField,4862jni_SetStaticBooleanField,4863jni_SetStaticByteField,4864jni_SetStaticCharField,4865jni_SetStaticShortField,4866jni_SetStaticIntField,4867jni_SetStaticLongField,4868jni_SetStaticFloatField,4869jni_SetStaticDoubleField,48704871jni_NewString,4872jni_GetStringLength,4873jni_GetStringChars,4874jni_ReleaseStringChars,48754876jni_NewStringUTF,4877jni_GetStringUTFLength,4878jni_GetStringUTFChars,4879jni_ReleaseStringUTFChars,48804881jni_GetArrayLength,48824883jni_NewObjectArray,4884jni_GetObjectArrayElement,4885jni_SetObjectArrayElement,48864887jni_NewBooleanArray,4888jni_NewByteArray,4889jni_NewCharArray,4890jni_NewShortArray,4891jni_NewIntArray,4892jni_NewLongArray,4893jni_NewFloatArray,4894jni_NewDoubleArray,48954896jni_GetBooleanArrayElements,4897jni_GetByteArrayElements,4898jni_GetCharArrayElements,4899jni_GetShortArrayElements,4900jni_GetIntArrayElements,4901jni_GetLongArrayElements,4902jni_GetFloatArrayElements,4903jni_GetDoubleArrayElements,49044905jni_ReleaseBooleanArrayElements,4906jni_ReleaseByteArrayElements,4907jni_ReleaseCharArrayElements,4908jni_ReleaseShortArrayElements,4909jni_ReleaseIntArrayElements,4910jni_ReleaseLongArrayElements,4911jni_ReleaseFloatArrayElements,4912jni_ReleaseDoubleArrayElements,49134914jni_GetBooleanArrayRegion,4915jni_GetByteArrayRegion,4916jni_GetCharArrayRegion,4917jni_GetShortArrayRegion,4918jni_GetIntArrayRegion,4919jni_GetLongArrayRegion,4920jni_GetFloatArrayRegion,4921jni_GetDoubleArrayRegion,49224923jni_SetBooleanArrayRegion,4924jni_SetByteArrayRegion,4925jni_SetCharArrayRegion,4926jni_SetShortArrayRegion,4927jni_SetIntArrayRegion,4928jni_SetLongArrayRegion,4929jni_SetFloatArrayRegion,4930jni_SetDoubleArrayRegion,49314932jni_RegisterNatives,4933jni_UnregisterNatives,49344935jni_MonitorEnter,4936jni_MonitorExit,49374938jni_GetJavaVM,49394940jni_GetStringRegion,4941jni_GetStringUTFRegion,49424943jni_GetPrimitiveArrayCritical,4944jni_ReleasePrimitiveArrayCritical,49454946jni_GetStringCritical,4947jni_ReleaseStringCritical,49484949jni_NewWeakGlobalRef,4950jni_DeleteWeakGlobalRef,49514952jni_ExceptionCheck,49534954jni_NewDirectByteBuffer,4955jni_GetDirectBufferAddress,4956jni_GetDirectBufferCapacity,49574958// New 1_6 features49594960jni_GetObjectRefType4961};496249634964// For jvmti use to modify jni function table.4965// Java threads in native contiues to run until it is transitioned4966// to VM at safepoint. Before the transition or before it is blocked4967// for safepoint it may access jni function table. VM could crash if4968// any java thread access the jni function table in the middle of memcpy.4969// To avoid this each function pointers are copied automically.4970void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {4971assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");4972intptr_t *a = (intptr_t *) jni_functions();4973intptr_t *b = (intptr_t *) new_jni_NativeInterface;4974for (uint i=0; i < sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {4975Atomic::store_ptr(*b++, a++);4976}4977}49784979void quicken_jni_functions() {4980// Replace Get<Primitive>Field with fast versions4981if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access()4982&& !VerifyJNIFields && !TraceJNICalls && !CountJNICalls && !CheckJNICalls4983#if defined(_WINDOWS) && defined(IA32) && defined(COMPILER2)4984// windows x86 currently needs SEH wrapper and the gain of the fast4985// versions currently isn't certain for server vm on uniprocessor.4986&& os::is_MP()4987#endif4988) {4989address func;4990func = JNI_FastGetField::generate_fast_get_boolean_field();4991if (func != (address)-1) {4992jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;4993}4994func = JNI_FastGetField::generate_fast_get_byte_field();4995if (func != (address)-1) {4996jni_NativeInterface.GetByteField = (GetByteField_t)func;4997}4998func = JNI_FastGetField::generate_fast_get_char_field();4999if (func != (address)-1) {5000jni_NativeInterface.GetCharField = (GetCharField_t)func;5001}5002func = JNI_FastGetField::generate_fast_get_short_field();5003if (func != (address)-1) {5004jni_NativeInterface.GetShortField = (GetShortField_t)func;5005}5006func = JNI_FastGetField::generate_fast_get_int_field();5007if (func != (address)-1) {5008jni_NativeInterface.GetIntField = (GetIntField_t)func;5009}5010func = JNI_FastGetField::generate_fast_get_long_field();5011if (func != (address)-1) {5012jni_NativeInterface.GetLongField = (GetLongField_t)func;5013}5014func = JNI_FastGetField::generate_fast_get_float_field();5015if (func != (address)-1) {5016jni_NativeInterface.GetFloatField = (GetFloatField_t)func;5017}5018func = JNI_FastGetField::generate_fast_get_double_field();5019if (func != (address)-1) {5020jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;5021}5022}5023}50245025// Returns the function structure5026struct JNINativeInterface_* jni_functions() {5027#if INCLUDE_JNI_CHECK5028if (CheckJNICalls) return jni_functions_check();5029#endif // INCLUDE_JNI_CHECK5030return &jni_NativeInterface;5031}50325033// Returns the function structure5034struct JNINativeInterface_* jni_functions_nocheck() {5035return &jni_NativeInterface;5036}50375038static void post_thread_start_event(const JavaThread* jt) {5039assert(jt != NULL, "invariant");5040EventThreadStart event;5041if (event.should_commit()) {5042event.set_thread(JFR_THREAD_ID(jt));5043event.commit();5044}5045}50465047// Invocation API504850495050// Forward declaration5051extern const struct JNIInvokeInterface_ jni_InvokeInterface;50525053// Global invocation API vars5054volatile jint vm_created = 0;5055// Indicate whether it is safe to recreate VM5056volatile jint safe_to_recreate_vm = 1;5057struct JavaVM_ main_vm = {&jni_InvokeInterface};505850595060#define JAVASTACKSIZE (400 * 1024) /* Default size of a thread java stack */5061enum { VERIFY_NONE, VERIFY_REMOTE, VERIFY_ALL };50625063#ifndef USDT25064HS_DTRACE_PROBE_DECL1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, void*);5065DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint);5066#else /* USDT2 */5067DT_RETURN_MARK_DECL(GetDefaultJavaVMInitArgs, jint5068, HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_RETURN(_ret_ref));5069#endif /* USDT2 */50705071_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *args_) {5072#ifndef USDT25073HS_DTRACE_PROBE1(hotspot_jni, GetDefaultJavaVMInitArgs__entry, args_);5074#else /* USDT2 */5075HOTSPOT_JNI_GETDEFAULTJAVAVMINITARGS_ENTRY(5076args_);5077#endif /* USDT2 */5078JDK1_1InitArgs *args = (JDK1_1InitArgs *)args_;5079jint ret = JNI_ERR;5080DT_RETURN_MARK(GetDefaultJavaVMInitArgs, jint, (const jint&)ret);50815082if (Threads::is_supported_jni_version(args->version)) {5083ret = JNI_OK;5084}5085// 1.1 style no longer supported in hotspot.5086// According the JNI spec, we should update args->version on return.5087// We also use the structure to communicate with launcher about default5088// stack size.5089if (args->version == JNI_VERSION_1_1) {5090args->version = JNI_VERSION_1_2;5091// javaStackSize is int in arguments structure5092assert(jlong(ThreadStackSize) * K < INT_MAX, "integer overflow");5093args->javaStackSize = (jint)(ThreadStackSize * K);5094}5095return ret;5096}50975098#ifndef PRODUCT50995100#include "gc_implementation/shared/gcTimer.hpp"5101#include "gc_interface/collectedHeap.hpp"5102#if INCLUDE_ALL_GCS5103#include "gc_implementation/g1/heapRegionRemSet.hpp"5104#endif5105#include "memory/guardedMemory.hpp"5106#include "utilities/quickSort.hpp"5107#include "utilities/ostream.hpp"5108#if INCLUDE_VM_STRUCTS5109#include "runtime/vmStructs.hpp"5110#endif51115112#define run_unit_test(unit_test_function_call) \5113tty->print_cr("Running test: " #unit_test_function_call); \5114unit_test_function_call51155116// Forward declaration5117void TestOS_test();5118void TestReservedSpace_test();5119void TestReserveMemorySpecial_test();5120void TestVirtualSpace_test();5121void TestMetaspaceAux_test();5122void SpaceManager_test_adjust_initial_chunk_size();5123void TestMetachunk_test();5124void TestVirtualSpaceNode_test();5125void TestNewSize_test();5126void TestKlass_test();5127void Test_linked_list();5128void TestResourcehash_test();5129void TestChunkedList_test();5130#if INCLUDE_ALL_GCS5131void TestOldFreeSpaceCalculation_test();5132void TestG1BiasedArray_test();5133void TestBufferingOopClosure_test();5134void TestCodeCacheRemSet_test();5135void FreeRegionList_test();5136void ChunkManager_test_list_index();5137#endif51385139void execute_internal_vm_tests() {5140if (ExecuteInternalVMTests) {5141tty->print_cr("Running internal VM tests");5142run_unit_test(TestOS_test());5143run_unit_test(TestReservedSpace_test());5144run_unit_test(TestReserveMemorySpecial_test());5145run_unit_test(TestVirtualSpace_test());5146run_unit_test(TestMetaspaceAux_test());5147run_unit_test(TestMetachunk_test());5148run_unit_test(TestVirtualSpaceNode_test());5149run_unit_test(GlobalDefinitions::test_globals());5150run_unit_test(GlobalDefinitions::test_proper_unit());5151run_unit_test(GCTimerAllTest::all());5152run_unit_test(arrayOopDesc::test_max_array_length());5153run_unit_test(CollectedHeap::test_is_in());5154run_unit_test(QuickSort::test_quick_sort());5155run_unit_test(GuardedMemory::test_guarded_memory());5156run_unit_test(AltHashing::test_alt_hash());5157run_unit_test(test_loggc_filename());5158run_unit_test(test_snprintf());5159run_unit_test(TestNewSize_test());5160run_unit_test(TestKlass_test());5161run_unit_test(TestResourcehash_test());5162run_unit_test(Test_linked_list());5163run_unit_test(TestChunkedList_test());5164run_unit_test(ObjectMonitor::sanity_checks());5165#if INCLUDE_VM_STRUCTS5166run_unit_test(VMStructs::test());5167#endif5168#if INCLUDE_ALL_GCS5169run_unit_test(TestOldFreeSpaceCalculation_test());5170run_unit_test(TestG1BiasedArray_test());5171run_unit_test(HeapRegionRemSet::test_prt());5172run_unit_test(SpaceManager_test_adjust_initial_chunk_size());5173run_unit_test(ChunkManager_test_list_index());5174run_unit_test(TestBufferingOopClosure_test());5175run_unit_test(TestCodeCacheRemSet_test());5176if (UseG1GC) {5177run_unit_test(FreeRegionList_test());5178}5179#endif5180tty->print_cr("All internal VM tests passed");5181}5182}51835184#undef run_unit_test51855186#endif51875188#ifndef USDT25189HS_DTRACE_PROBE_DECL3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);5190DT_RETURN_MARK_DECL(CreateJavaVM, jint);5191#else /* USDT2 */5192DT_RETURN_MARK_DECL(CreateJavaVM, jint5193, HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));5194#endif /* USDT2 */51955196_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) {5197#ifndef USDT25198HS_DTRACE_PROBE3(hotspot_jni, CreateJavaVM__entry, vm, penv, args);5199#else /* USDT2 */5200HOTSPOT_JNI_CREATEJAVAVM_ENTRY(5201(void **) vm, penv, args);5202#endif /* USDT2 */52035204jint result = JNI_ERR;5205DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);52065207// We're about to use Atomic::xchg for synchronization. Some Zero5208// platforms use the GCC builtin __sync_lock_test_and_set for this,5209// but __sync_lock_test_and_set is not guaranteed to do what we want5210// on all architectures. So we check it works before relying on it.5211#if defined(ZERO) && defined(ASSERT)5212{5213jint a = 0xcafebabe;5214jint b = Atomic::xchg(0xdeadbeef, &a);5215void *c = &a;5216void *d = Atomic::xchg_ptr(&b, &c);5217assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");5218assert(c == &b && d == &a, "Atomic::xchg_ptr() works");5219}5220#endif // ZERO && ASSERT52215222// At the moment it's only possible to have one Java VM,5223// since some of the runtime state is in global variables.52245225// We cannot use our mutex locks here, since they only work on5226// Threads. We do an atomic compare and exchange to ensure only5227// one thread can call this method at a time52285229// We use Atomic::xchg rather than Atomic::add/dec since on some platforms5230// the add/dec implementations are dependent on whether we are running5231// on a multiprocessor, and at this stage of initialization the os::is_MP5232// function used to determine this will always return false. Atomic::xchg5233// does not have this problem.5234if (Atomic::xchg(1, &vm_created) == 1) {5235return JNI_EEXIST; // already created, or create attempt in progress5236}5237if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {5238return JNI_ERR; // someone tried and failed and retry not allowed.5239}52405241assert(vm_created == 1, "vm_created is true during the creation");52425243/**5244* Certain errors during initialization are recoverable and do not5245* prevent this method from being called again at a later time5246* (perhaps with different arguments). However, at a certain5247* point during initialization if an error occurs we cannot allow5248* this function to be called again (or it will crash). In those5249* situations, the 'canTryAgain' flag is set to false, which atomically5250* sets safe_to_recreate_vm to 1, such that any new call to5251* JNI_CreateJavaVM will immediately fail using the above logic.5252*/5253bool can_try_again = true;52545255result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);5256if (result == JNI_OK) {5257JavaThread *thread = JavaThread::current();5258/* thread is thread_in_vm here */5259*vm = (JavaVM *)(&main_vm);5260*(JNIEnv**)penv = thread->jni_environment();52615262// Tracks the time application was running before GC5263RuntimeService::record_application_start();52645265// Notify JVMTI5266if (JvmtiExport::should_post_thread_life()) {5267JvmtiExport::post_thread_start(thread);5268}52695270post_thread_start_event(thread);52715272#ifndef PRODUCT5273#ifndef CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED5274#define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()5275#endif52765277// Check if we should compile all classes on bootclasspath5278if (CompileTheWorld) ClassLoader::compile_the_world();5279if (ReplayCompiles) ciReplay::replay(thread);52805281// Some platforms (like Win*) need a wrapper around these test5282// functions in order to properly handle error conditions.5283CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(test_error_handler);5284CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(execute_internal_vm_tests);5285#endif52865287// Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.5288ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);5289MACOS_AARCH64_ONLY(thread->enable_wx(WXExec));5290} else {5291if (can_try_again) {5292// reset safe_to_recreate_vm to 1 so that retrial would be possible5293safe_to_recreate_vm = 1;5294}52955296// Creation failed. We must reset vm_created5297*vm = 0;5298*(JNIEnv**)penv = 0;5299// reset vm_created last to avoid race condition. Use OrderAccess to5300// control both compiler and architectural-based reordering.5301OrderAccess::release_store(&vm_created, 0);5302}53035304return result;5305}53065307#ifndef USDT25308HS_DTRACE_PROBE_DECL3(hotspot_jni, GetCreatedJavaVMs__entry, \5309JavaVM**, jsize, jsize*);5310HS_DTRACE_PROBE_DECL1(hotspot_jni, GetCreatedJavaVMs__return, jint);5311#endif /* !USDT2 */53125313_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs(JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {5314// See bug 4367188, the wrapper can sometimes cause VM crashes5315// JNIWrapper("GetCreatedJavaVMs");5316#ifndef USDT25317HS_DTRACE_PROBE3(hotspot_jni, GetCreatedJavaVMs__entry, \5318vm_buf, bufLen, numVMs);5319#else /* USDT2 */5320HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY(5321(void **) vm_buf, bufLen, (uintptr_t *) numVMs);5322#endif /* USDT2 */5323if (vm_created) {5324if (numVMs != NULL) *numVMs = 1;5325if (bufLen > 0) *vm_buf = (JavaVM *)(&main_vm);5326} else {5327if (numVMs != NULL) *numVMs = 0;5328}5329#ifndef USDT25330HS_DTRACE_PROBE1(hotspot_jni, GetCreatedJavaVMs__return, JNI_OK);5331#else /* USDT2 */5332HOTSPOT_JNI_GETCREATEDJAVAVMS_RETURN(5333JNI_OK);5334#endif /* USDT2 */5335return JNI_OK;5336}53375338extern "C" {53395340#ifndef USDT25341DT_RETURN_MARK_DECL(DestroyJavaVM, jint);5342#else /* USDT2 */5343DT_RETURN_MARK_DECL(DestroyJavaVM, jint5344, HOTSPOT_JNI_DESTROYJAVAVM_RETURN(_ret_ref));5345#endif /* USDT2 */53465347jint JNICALL jni_DestroyJavaVM(JavaVM *vm) {5348#ifndef USDT25349DTRACE_PROBE1(hotspot_jni, DestroyJavaVM__entry, vm);5350#else /* USDT2 */5351HOTSPOT_JNI_DESTROYJAVAVM_ENTRY(5352vm);5353#endif /* USDT2 */5354jint res = JNI_ERR;5355DT_RETURN_MARK(DestroyJavaVM, jint, (const jint&)res);53565357if (!vm_created) {5358res = JNI_ERR;5359return res;5360}53615362JNIWrapper("DestroyJavaVM");5363JNIEnv *env;5364JavaVMAttachArgs destroyargs;5365destroyargs.version = CurrentVersion;5366destroyargs.name = (char *)"DestroyJavaVM";5367destroyargs.group = NULL;5368res = vm->AttachCurrentThread((void **)&env, (void *)&destroyargs);5369if (res != JNI_OK) {5370return res;5371}53725373// Since this is not a JVM_ENTRY we have to set the thread state manually before entering.5374JavaThread* thread = JavaThread::current();53755376// We are going to VM, change W^X state to the expected one.5377MACOS_AARCH64_ONLY(WXMode oldmode = thread->enable_wx(WXWrite));53785379ThreadStateTransition::transition_from_native(thread, _thread_in_vm);5380if (Threads::destroy_vm()) {5381// Should not change thread state, VM is gone5382vm_created = false;5383res = JNI_OK;5384return res;5385} else {5386ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);5387res = JNI_ERR;5388return res;5389}5390}539153925393static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool daemon) {5394JavaVMAttachArgs *args = (JavaVMAttachArgs *) _args;53955396// Check below commented out from JDK1.2fcs as well5397/*5398if (args && (args->version != JNI_VERSION_1_1 || args->version != JNI_VERSION_1_2)) {5399return JNI_EVERSION;5400}5401*/54025403Thread* t = ThreadLocalStorage::get_thread_slow();5404if (t != NULL) {5405// If the thread has been attached this operation is a no-op5406*(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();5407return JNI_OK;5408}54095410// Create a thread and mark it as attaching so it will be skipped by the5411// ThreadsListEnumerator - see CR 64043065412JavaThread* thread = new JavaThread(true);54135414// Set correct safepoint info. The thread is going to call into Java when5415// initializing the Java level thread object. Hence, the correct state must5416// be set in order for the Safepoint code to deal with it correctly.5417thread->set_thread_state(_thread_in_vm);5418// Must do this before initialize_thread_local_storage5419thread->record_stack_base_and_size();54205421thread->initialize_thread_local_storage();54225423MACOS_AARCH64_ONLY(thread->init_wx());54245425if (!os::create_attached_thread(thread)) {5426delete thread;5427return JNI_ERR;5428}5429// Enable stack overflow checks5430thread->create_stack_guard_pages();54315432thread->initialize_tlab();54335434thread->cache_global_variables();54355436// Crucial that we do not have a safepoint check for this thread, since it has5437// not been added to the Thread list yet.5438{ Threads_lock->lock_without_safepoint_check();5439// This must be inside this lock in order to get FullGCALot to work properly, i.e., to5440// avoid this thread trying to do a GC before it is added to the thread-list5441thread->set_active_handles(JNIHandleBlock::allocate_block());5442Threads::add(thread, daemon);5443Threads_lock->unlock();5444}5445// Create thread group and name info from attach arguments5446oop group = NULL;5447char* thread_name = NULL;5448if (args != NULL && Threads::is_supported_jni_version(args->version)) {5449group = JNIHandles::resolve(args->group);5450thread_name = args->name; // may be NULL5451}5452if (group == NULL) group = Universe::main_thread_group();54535454// Create Java level thread object and attach it to this thread5455bool attach_failed = false;5456{5457EXCEPTION_MARK;5458HandleMark hm(THREAD);5459Handle thread_group(THREAD, group);5460thread->allocate_threadObj(thread_group, thread_name, daemon, THREAD);5461if (HAS_PENDING_EXCEPTION) {5462CLEAR_PENDING_EXCEPTION;5463// cleanup outside the handle mark.5464attach_failed = true;5465}5466}54675468if (attach_failed) {5469// Added missing cleanup5470thread->cleanup_failed_attach_current_thread();5471return JNI_ERR;5472}54735474// mark the thread as no longer attaching5475// this uses a fence to push the change through so we don't have5476// to regrab the threads_lock5477thread->set_done_attaching_via_jni();54785479// Set java thread status.5480java_lang_Thread::set_thread_status(thread->threadObj(),5481java_lang_Thread::RUNNABLE);54825483// Notify the debugger5484if (JvmtiExport::should_post_thread_life()) {5485JvmtiExport::post_thread_start(thread);5486}54875488post_thread_start_event(thread);54895490*(JNIEnv**)penv = thread->jni_environment();54915492// Now leaving the VM, so change thread_state. This is normally automatically taken care5493// of in the JVM_ENTRY. But in this situation we have to do it manually. Notice, that by5494// using ThreadStateTransition::transition, we do a callback to the safepoint code if5495// needed.54965497ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);5498MACOS_AARCH64_ONLY(thread->enable_wx(WXExec));54995500// Perform any platform dependent FPU setup5501os::setup_fpu();55025503return JNI_OK;5504}550555065507jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {5508#ifndef USDT25509DTRACE_PROBE3(hotspot_jni, AttachCurrentThread__entry, vm, penv, _args);5510#else /* USDT2 */5511HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY(5512vm, penv, _args);5513#endif /* USDT2 */5514if (!vm_created) {5515#ifndef USDT25516DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, JNI_ERR);5517#else /* USDT2 */5518HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(5519(uint32_t) JNI_ERR);5520#endif /* USDT2 */5521return JNI_ERR;5522}55235524JNIWrapper("AttachCurrentThread");5525jint ret = attach_current_thread(vm, penv, _args, false);5526#ifndef USDT25527DTRACE_PROBE1(hotspot_jni, AttachCurrentThread__return, ret);5528#else /* USDT2 */5529HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN(5530ret);5531#endif /* USDT2 */5532return ret;5533}553455355536jint JNICALL jni_DetachCurrentThread(JavaVM *vm) {5537#ifndef USDT25538DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__entry, vm);5539#else /* USDT2 */5540HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY(5541vm);5542#endif /* USDT2 */5543VM_Exit::block_if_vm_exited();55445545JNIWrapper("DetachCurrentThread");55465547// If the thread has been deattacted the operations is a no-op5548if (ThreadLocalStorage::thread() == NULL) {5549#ifndef USDT25550DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);5551#else /* USDT2 */5552HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(5553JNI_OK);5554#endif /* USDT2 */5555return JNI_OK;5556}55575558JavaThread* thread = JavaThread::current();5559if (thread->has_last_Java_frame()) {5560#ifndef USDT25561DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_ERR);5562#else /* USDT2 */5563HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(5564(uint32_t) JNI_ERR);5565#endif /* USDT2 */5566// Can't detach a thread that's running java, that can't work.5567return JNI_ERR;5568}55695570// We are going to VM, change W^X state to the expected one.5571MACOS_AARCH64_ONLY(thread->enable_wx(WXWrite));55725573// Safepoint support. Have to do call-back to safepoint code, if in the5574// middel of a safepoint operation5575ThreadStateTransition::transition_from_native(thread, _thread_in_vm);55765577// XXX: Note that JavaThread::exit() call below removes the guards on the5578// stack pages set up via enable_stack_{red,yellow}_zone() calls5579// above in jni_AttachCurrentThread. Unfortunately, while the setting5580// of the guards is visible in jni_AttachCurrentThread above,5581// the removal of the guards is buried below in JavaThread::exit()5582// here. The abstraction should be more symmetrically either exposed5583// or hidden (e.g. it could probably be hidden in the same5584// (platform-dependent) methods where we do alternate stack5585// maintenance work?)5586thread->exit(false, JavaThread::jni_detach);5587delete thread;55885589// Go to the execute mode, the initial state of the thread on creation.5590// Use os interface as the thread is not a JavaThread anymore.5591MACOS_AARCH64_ONLY(os::current_thread_enable_wx(WXExec));55925593#ifndef USDT25594DTRACE_PROBE1(hotspot_jni, DetachCurrentThread__return, JNI_OK);5595#else /* USDT2 */5596HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN(5597JNI_OK);5598#endif /* USDT2 */5599return JNI_OK;5600}56015602#ifndef USDT25603DT_RETURN_MARK_DECL(GetEnv, jint);5604#else /* USDT2 */5605DT_RETURN_MARK_DECL(GetEnv, jint5606, HOTSPOT_JNI_GETENV_RETURN(_ret_ref));5607#endif /* USDT2 */56085609jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {5610#ifndef USDT25611DTRACE_PROBE3(hotspot_jni, GetEnv__entry, vm, penv, version);5612#else /* USDT2 */5613HOTSPOT_JNI_GETENV_ENTRY(5614vm, penv, version);5615#endif /* USDT2 */5616jint ret = JNI_ERR;5617DT_RETURN_MARK(GetEnv, jint, (const jint&)ret);56185619if (!vm_created) {5620*penv = NULL;5621ret = JNI_EDETACHED;5622return ret;5623}56245625if (JniExportedInterface::GetExportedInterface(vm, penv, version, &ret)) {5626return ret;5627}56285629#ifndef JVMPI_VERSION_15630// need these in order to be polite about older agents5631#define JVMPI_VERSION_1 ((jint)0x10000001)5632#define JVMPI_VERSION_1_1 ((jint)0x10000002)5633#define JVMPI_VERSION_1_2 ((jint)0x10000003)5634#endif // !JVMPI_VERSION_156355636Thread* thread = ThreadLocalStorage::thread();5637if (thread != NULL && thread->is_Java_thread()) {5638if (Threads::is_supported_jni_version_including_1_1(version)) {5639*(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();5640ret = JNI_OK;5641return ret;56425643} else if (version == JVMPI_VERSION_1 ||5644version == JVMPI_VERSION_1_1 ||5645version == JVMPI_VERSION_1_2) {5646tty->print_cr("ERROR: JVMPI, an experimental interface, is no longer supported.");5647tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");5648ret = JNI_EVERSION;5649return ret;5650} else if (JvmtiExport::is_jvmdi_version(version)) {5651tty->print_cr("FATAL ERROR: JVMDI is no longer supported.");5652tty->print_cr("Please use the supported interface: the JVM Tool Interface (JVM TI).");5653ret = JNI_EVERSION;5654return ret;5655} else {5656*penv = NULL;5657ret = JNI_EVERSION;5658return ret;5659}5660} else {5661*penv = NULL;5662ret = JNI_EDETACHED;5663return ret;5664}5665}566656675668jint JNICALL jni_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *_args) {5669#ifndef USDT25670DTRACE_PROBE3(hotspot_jni, AttachCurrentThreadAsDaemon__entry, vm, penv, _args);5671#else /* USDT2 */5672HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY(5673vm, penv, _args);5674#endif /* USDT2 */5675if (!vm_created) {5676#ifndef USDT25677DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, JNI_ERR);5678#else /* USDT2 */5679HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(5680(uint32_t) JNI_ERR);5681#endif /* USDT2 */5682return JNI_ERR;5683}56845685JNIWrapper("AttachCurrentThreadAsDaemon");5686jint ret = attach_current_thread(vm, penv, _args, true);5687#ifndef USDT25688DTRACE_PROBE1(hotspot_jni, AttachCurrentThreadAsDaemon__return, ret);5689#else /* USDT2 */5690HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN(5691ret);5692#endif /* USDT2 */5693return ret;5694}569556965697} // End extern "C"56985699const struct JNIInvokeInterface_ jni_InvokeInterface = {5700NULL,5701NULL,5702NULL,57035704jni_DestroyJavaVM,5705jni_AttachCurrentThread,5706jni_DetachCurrentThread,5707jni_GetEnv,5708jni_AttachCurrentThreadAsDaemon5709};571057115712