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