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