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