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