24
#include "precompiled.hpp"
25
#include "classfile/symbolTable.hpp"
26
#include "classfile/systemDictionary.hpp"
27
#include "classfile/vmClasses.hpp"
28
#include "interpreter/linkResolver.hpp"
29
#include "jvmci/jniAccessMark.inline.hpp"
30
#include "jvmci/jvmciJavaClasses.hpp"
31
#include "jvmci/jvmciRuntime.hpp"
32
#include "memory/resourceArea.hpp"
33
#include "oops/instanceKlass.inline.hpp"
34
#include "runtime/fieldDescriptor.inline.hpp"
35
#include "runtime/jniHandles.inline.hpp"
36
#include "runtime/java.hpp"
40
oop HotSpotJVMCI::resolve(JVMCIObject obj) {
41
return JNIHandles::resolve(obj.as_jobject());
44
arrayOop HotSpotJVMCI::resolve(JVMCIArray obj) {
45
return (arrayOop) JNIHandles::resolve(obj.as_jobject());
48
objArrayOop HotSpotJVMCI::resolve(JVMCIObjectArray obj) {
49
return (objArrayOop) JNIHandles::resolve(obj.as_jobject());
52
typeArrayOop HotSpotJVMCI::resolve(JVMCIPrimitiveArray obj) {
53
return (typeArrayOop) JNIHandles::resolve(obj.as_jobject());
56
JVMCIObject HotSpotJVMCI::wrap(oop obj) {
57
assert(Thread::current()->is_Java_thread(), "must be");
58
return JVMCIObject(JNIHandles::make_local(obj), true);
66
void HotSpotJVMCI::compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS) {
67
InstanceKlass* ik = InstanceKlass::cast(klass);
68
Symbol* name_symbol = SymbolTable::probe(name, (int)strlen(name));
69
Symbol* signature_symbol = SymbolTable::probe(signature, (int)strlen(signature));
70
if (name_symbol == nullptr || signature_symbol == nullptr) {
74
fatal("symbol with name %s and signature %s was not found in symbol table (klass=%s)", name, signature, klass->name()->as_C_string());
78
if (!ik->find_field(name_symbol, signature_symbol, &fd)) {
80
fatal("Could not find field %s.%s with signature %s", ik->external_name(), name, signature);
82
guarantee(fd.is_static() == static_field, "static/instance mismatch");
83
assert(fd.offset() != 0, "must be valid offset");
84
if (dest_offset != fd.offset()) {
85
if (dest_offset != 0) {
86
fatal("offset for %s %s.%s re-initialized: %d -> %d", signature, ik->external_name(), name, dest_offset, fd.offset());
88
dest_offset = fd.offset();
92
ik->initialize(CHECK);
94
JVMCI_event_2(" field offset for %s %s.%s = %d", signature, ik->external_name(), name, dest_offset);
99
static void check_resolve_method(const char* call_type, Klass* resolved_klass, Symbol* method_name, Symbol* method_signature, TRAPS) {
100
Method* method = nullptr;
101
LinkInfo link_info(resolved_klass, method_name, method_signature, nullptr, LinkInfo::AccessCheck::skip, LinkInfo::LoaderConstraintCheck::skip);
102
if (strcmp(call_type, "call_static") == 0) {
103
method = LinkResolver::resolve_static_call_or_null(link_info);
104
} else if (strcmp(call_type, "call_virtual") == 0) {
105
method = LinkResolver::resolve_virtual_call_or_null(resolved_klass, link_info);
106
} else if (strcmp(call_type, "call_special") == 0) {
107
method = LinkResolver::resolve_special_call_or_null(link_info);
109
fatal("Unknown or unsupported call type: %s", call_type);
111
if (method == nullptr) {
112
fatal("Could not resolve %s.%s%s", resolved_klass->external_name(), method_name->as_C_string(), method_signature->as_C_string());
117
jclass JNIJVMCI::_box_classes[T_CONFLICT+1];
118
jclass JNIJVMCI::_byte_array;
119
jfieldID JNIJVMCI::_box_fields[T_CONFLICT+1];
120
jmethodID JNIJVMCI::_box_constructors[T_CONFLICT+1];
121
jmethodID JNIJVMCI::_Class_getName_method;
123
jmethodID JNIJVMCI::_HotSpotResolvedJavaMethodImpl_fromMetaspace_method;
124
jmethodID JNIJVMCI::_HotSpotConstantPool_fromMetaspace_method;
125
jmethodID JNIJVMCI::_HotSpotResolvedObjectTypeImpl_fromMetaspace_method;
126
jmethodID JNIJVMCI::_HotSpotResolvedPrimitiveType_fromMetaspace_method;
128
#define START_CLASS(className, fullClassName) { \
129
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::fullClassName(), true, CHECK); \
130
InstanceKlass* current = className::_klass; \
131
if (current != InstanceKlass::cast(k)) { \
132
if (current != nullptr) { \
133
fatal("klass for %s re-initialized: " PTR_FORMAT " -> " PTR_FORMAT, \
134
k->external_name(), p2i(current), p2i(k)); \
136
JVMCI_event_2(" klass for %s = " PTR_FORMAT, k->external_name(), p2i(k)); \
137
className::_klass = InstanceKlass::cast(k); \
138
className::_klass->initialize(CHECK); \
143
#define FIELD(className, name, signature, static_field) compute_offset(className::_##name##_offset, className::_klass, #name, signature, static_field, CHECK);
144
#define CHAR_FIELD(className, name) FIELD(className, name, "C", false)
145
#define INT_FIELD(className, name) FIELD(className, name, "I", false)
146
#define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false)
147
#define LONG_FIELD(className, name) FIELD(className, name, "J", false)
148
#define FLOAT_FIELD(className, name) FIELD(className, name, "F", false)
149
#define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false)
150
#define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true)
151
#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)
152
#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)
154
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
155
#define CONSTRUCTOR(className, signature)
157
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
158
check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK);
159
#define CONSTRUCTOR(className, signature) { \
160
TempNewSymbol sig = SymbolTable::new_symbol(signature); \
161
check_resolve_method("call_special", k, vmSymbols::object_initializer_name(), sig, CHECK); \
167
void HotSpotJVMCI::compute_offsets(TRAPS) {
168
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, OBJECT_FIELD, OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
182
#undef PRIMARRAY_FIELD
183
#undef OBJECTARRAY_FIELD
185
#undef STATIC_OBJECT_FIELD
186
#undef STATIC_OBJECTARRAY_FIELD
187
#undef STATIC_INT_FIELD
188
#undef STATIC_BOOLEAN_FIELD
193
#define START_CLASS(className, fullClassName) \
194
void HotSpotJVMCI::className::initialize(JVMCI_TRAPS) { \
195
JavaThread* THREAD = JavaThread::current(); \
196
className::klass()->initialize(CHECK); \
198
bool HotSpotJVMCI::className::is_instance(JVMCIEnv* env, JVMCIObject object) { \
199
return resolve(object)->is_a(className::klass()); \
201
void HotSpotJVMCI::className::check(oop obj, const char* field_name, int offset) { \
202
assert(obj != nullptr, "null field access of %s.%s", #className, field_name); \
203
assert(obj->is_a(className::klass()), "wrong class, " #className " expected, found %s", obj->klass()->external_name()); \
204
assert(offset != 0, "must be valid offset"); \
206
InstanceKlass* HotSpotJVMCI::className::_klass = nullptr;
210
#define FIELD(className, name, type, accessor, cast) \
211
type HotSpotJVMCI::className::name(JVMCIEnv* env, oop obj) { className::check(obj, #name, className::_##name##_offset); return cast obj->accessor(className::_##name##_offset); } \
212
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, oop obj, type x) { className::check(obj, #name, className::_##name##_offset); obj->accessor##_put(className::_##name##_offset, x); }
215
#define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field, EMPTY_CAST)
216
#define INT_FIELD(className, name) FIELD(className, name, jint, int_field, EMPTY_CAST)
217
#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field, EMPTY_CAST)
218
#define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field, EMPTY_CAST)
219
#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field, EMPTY_CAST)
221
#define OBJECT_FIELD(className, name, signature) FIELD(className, name, oop, obj_field, EMPTY_CAST)
222
#define OBJECTARRAY_FIELD(className, name, signature) FIELD(className, name, objArrayOop, obj_field, (objArrayOop))
223
#define PRIMARRAY_FIELD(className, name, signature) FIELD(className, name, typeArrayOop, obj_field, (typeArrayOop))
224
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, oop)
225
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, objArrayOop)
226
#define STATIC_OOPISH_FIELD(className, name, type) \
227
type HotSpotJVMCI::className::name(JVMCIEnv* env) { \
228
assert(className::klass() != nullptr && className::klass()->is_linked(), "Class not yet linked: " #className); \
229
InstanceKlass* ik = className::klass(); \
230
oop base = ik->static_field_base_raw(); \
231
oop result = HeapAccess<>::oop_load_at(base, className::_##name##_offset); \
232
return type(result); \
234
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, type x) { \
235
assert(className::klass() != nullptr && className::klass()->is_linked(), "Class not yet linked: " #className); \
236
assert(className::klass() != nullptr, "Class not yet loaded: " #className); \
237
InstanceKlass* ik = className::klass(); \
238
oop base = ik->static_field_base_raw(); \
239
HeapAccess<>::oop_store_at(base, className::_##name##_offset, x); \
241
#define STATIC_PRIMITIVE_FIELD(className, name, jtypename) \
242
jtypename HotSpotJVMCI::className::get_##name(JVMCIEnv* env) { \
243
assert(className::klass() != nullptr && className::klass()->is_linked(), "Class not yet linked: " #className); \
244
InstanceKlass* ik = className::klass(); \
245
oop base = ik->static_field_base_raw(); \
246
return *base->field_addr<jtypename>(className::_##name##_offset); \
248
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, jtypename x) { \
249
assert(className::klass() != nullptr && className::klass()->is_linked(), "Class not yet linked: " #className); \
250
InstanceKlass* ik = className::klass(); \
251
oop base = ik->static_field_base_raw(); \
252
*base->field_addr<jtypename>(className::_##name##_offset) = x; \
255
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint)
256
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean)
257
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
258
#define CONSTRUCTOR(className, signature)
271
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
284
#undef PRIMARRAY_FIELD
285
#undef OBJECTARRAY_FIELD
286
#undef STATIC_OOPISH_FIELD
287
#undef STATIC_OBJECT_FIELD
288
#undef STATIC_OBJECTARRAY_FIELD
289
#undef STATIC_INT_FIELD
290
#undef STATIC_BOOLEAN_FIELD
291
#undef STATIC_PRIMITIVE_FIELD
298
void JNIJVMCI::initialize_field_id(JNIEnv* env, jfieldID &fieldid, jclass clazz, const char* class_name, const char* name, const char* signature, bool static_field) {
299
if (JVMCILibDumpJNIConfig != nullptr) {
300
fileStream* st = JVMCIGlobals::get_jni_config_file();
301
st->print_cr("field %s %s %s", class_name, name, signature);
304
if (env->ExceptionCheck()) {
307
jfieldID current = fieldid;
310
fieldid = env->GetStaticFieldID(clazz, name, signature);
313
fieldid = env->GetFieldID(clazz, name, signature);
317
if (current != fieldid) {
318
if (current != nullptr) {
319
fatal("jfieldID for %s %s.%s re-initialized: " PTR_FORMAT " -> " PTR_FORMAT,
320
signature, class_name, name, p2i(current), p2i(fieldid));
322
JVMCI_event_2(" jfieldID for %s %s.%s = " PTR_FORMAT, signature, class_name, name, p2i(fieldid));
326
if (env->ExceptionCheck()) {
327
env->ExceptionDescribe();
328
env->ExceptionClear();
330
fatal("Could not find field %s.%s with signature %s", class_name, name, signature);
334
#define START_CLASS(className, fullClassName) { \
335
current_class_name = vmSymbols::fullClassName()->as_C_string(); \
336
if (JVMCILibDumpJNIConfig != nullptr) { \
337
fileStream* st = JVMCIGlobals::get_jni_config_file(); \
338
st->print_cr("class %s", current_class_name); \
340
jclass k = env->FindClass(current_class_name); \
341
JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", current_class_name); \
342
assert(k != nullptr, #fullClassName " not initialized"); \
343
k = (jclass) env->NewGlobalRef(k); \
344
jclass current = className::_class; \
345
if (current != k) { \
346
JVMCI_event_2(" jclass for %s = " PTR_FORMAT, current_class_name, p2i(k)); \
350
if (current != nullptr) { \
351
fatal("jclass for %s re-initialized: " PTR_FORMAT " -> " PTR_FORMAT, \
352
current_class_name, p2i(current), p2i(k)); \
354
className::_class = k; \
358
#define END_CLASS current_class_name = nullptr; }
360
#define FIELD(className, name, signature, static_field) initialize_field_id(env, className::_##name##_field_id, className::_class, current_class_name, #name, signature, static_field);
361
#define CHAR_FIELD(className, name) FIELD(className, name, "C", false)
362
#define INT_FIELD(className, name) FIELD(className, name, "I", false)
363
#define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false)
364
#define LONG_FIELD(className, name) FIELD(className, name, "J", false)
365
#define FLOAT_FIELD(className, name) FIELD(className, name, "F", false)
366
#define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false)
367
#define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true)
368
#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)
369
#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)
371
#define GET_JNI_METHOD(jniGetMethod, dst, clazz, methodName, signature) \
372
if (JVMCILibDumpJNIConfig != nullptr) { \
373
fileStream* st = JVMCIGlobals::get_jni_config_file(); \
374
st->print_cr("method %s %s %s", current_class_name, methodName, signature); \
376
jmethodID current = dst; \
377
dst = env->jniGetMethod(clazz, methodName, signature); \
378
assert(dst != nullptr, "uninitialized"); \
379
if (current != dst) { \
380
JVMCI_event_2(" jmethodID for %s.%s%s = " PTR_FORMAT, \
381
current_class_name, methodName, signature, p2i(dst)); \
384
if (current != nullptr) { \
385
fatal("jmethod for %s.%s%s re-initialized: " PTR_FORMAT " -> " PTR_FORMAT, \
386
current_class_name, methodName, signature, p2i(current), p2i(dst)); \
388
JVMCI_EXCEPTION_CHECK(env, #jniGetMethod "(%s.%s%s)", \
389
current_class_name, methodName, signature); \
393
#define GET_JNI_CONSTRUCTOR(clazz, signature) \
394
GET_JNI_METHOD(GetMethodID, JNIJVMCI::clazz::_constructor, clazz::_class, "<init>", signature) \
396
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
397
GET_JNI_METHOD(jniGetMethod, \
398
className::_##methodName##_method, \
399
className::clazz(), \
400
vmSymbols::methodName##_name()->as_C_string(), \
401
vmSymbols::signatureSymbolName()->as_C_string())
403
#define CONSTRUCTOR(className, signature) \
404
GET_JNI_CONSTRUCTOR(className, signature)
407
void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
408
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
409
jlong JNICALL JVM_ReadSystemPropertiesInfo(JNIEnv *env, jclass c, jintArray offsets_handle);
415
class ThrowableInitDumper : public SymbolClosure {
419
ThrowableInitDumper(fileStream* st) { _st = st; }
420
void do_symbol(Symbol** p) {
421
JavaThread* THREAD = JavaThread::current();
423
if (name == nullptr) {
426
Klass* k = SystemDictionary::resolve_or_null(name, CHECK_EXIT);
427
if (k != nullptr && k->is_instance_klass()) {
428
InstanceKlass* iklass = InstanceKlass::cast(k);
429
if (iklass->is_subclass_of(vmClasses::Throwable_klass()) && iklass->is_public() && !iklass->is_abstract()) {
430
const char* class_name = nullptr;
431
Array<Method*>* methods = iklass->methods();
432
for (int i = 0; i < methods->length(); i++) {
433
Method* m = methods->at(i);
434
if (m->name() == vmSymbols::object_initializer_name() &&
436
(m->signature() == vmSymbols::void_method_signature() || m->signature() == vmSymbols::string_void_signature())) {
437
if (class_name == nullptr) {
438
class_name = name->as_C_string();
439
_st->print_cr("class %s", class_name);
441
_st->print_cr("method %s %s %s", class_name, m->name()->as_C_string(), m->signature()->as_C_string());
449
#define IN_CLASS(fullClassName) current_class_name = vmSymbols::fullClassName()->as_C_string()
453
void JNIJVMCI::initialize_ids(JNIEnv* env) {
455
const char* current_class_name = nullptr;
456
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, OBJECT_FIELD, OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
458
IN_CLASS(java_lang_Class);
459
GET_JNI_METHOD(GetMethodID, _Class_getName_method, Class::_class, "getName", "()Ljava/lang/String;");
461
IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedPrimitiveType);
462
GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedPrimitiveType_fromMetaspace_method, HotSpotResolvedPrimitiveType::_class,
463
vmSymbols::fromMetaspace_name()->as_C_string(),
464
vmSymbols::primitive_fromMetaspace_signature()->as_C_string());
465
IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl);
466
GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedObjectTypeImpl_fromMetaspace_method, HotSpotResolvedObjectTypeImpl::_class,
467
vmSymbols::fromMetaspace_name()->as_C_string(),
468
vmSymbols::klass_fromMetaspace_signature()->as_C_string());
469
IN_CLASS(jdk_vm_ci_hotspot_HotSpotConstantPool);
470
GET_JNI_METHOD(GetStaticMethodID, _HotSpotConstantPool_fromMetaspace_method, HotSpotConstantPool::_class,
471
vmSymbols::fromMetaspace_name()->as_C_string(),
472
vmSymbols::constantPool_fromMetaspace_signature()->as_C_string());
473
IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl);
474
GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedJavaMethodImpl_fromMetaspace_method, HotSpotResolvedJavaMethodImpl::_class,
475
vmSymbols::fromMetaspace_name()->as_C_string(),
476
vmSymbols::method_fromMetaspace_signature()->as_C_string());
478
#define BOX_CLASSES(generate) \
479
generate(Boolean, T_BOOLEAN, Z) \
480
generate(Byte, T_BYTE, B) \
481
generate(Character, T_CHAR, C) \
482
generate(Short, T_SHORT, S) \
483
generate(Integer, T_INT, I) \
484
generate(Long, T_LONG, J) \
485
generate(Float, T_FLOAT, F) \
486
generate(Double, T_DOUBLE, D) \
488
#define DO_BOX_CLASS(klass, basicType, type) \
489
current_class_name = "java/lang/" #klass; \
490
if (JVMCILibDumpJNIConfig == nullptr) { \
491
_box_classes[basicType] = env->FindClass("java/lang/" #klass); \
492
JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", #klass); \
493
_box_classes[basicType] = (jclass) env->NewGlobalRef(_box_classes[basicType]); \
494
assert(_box_classes[basicType] != nullptr, "uninitialized"); \
495
_box_fields[basicType] = env->GetFieldID(_box_classes[basicType], "value", #type); \
496
JVMCI_EXCEPTION_CHECK(env, "GetFieldID(%s, value, %s)", #klass, #type); \
497
GET_JNI_METHOD(GetMethodID, _box_constructors[basicType], _box_classes[basicType], "<init>", "(" #type ")V"); \
499
fileStream* st = JVMCIGlobals::get_jni_config_file(); \
500
st->print_cr("field %s value %s", current_class_name, #type); \
501
st->print_cr("method %s <init> (%s)V", current_class_name, #type); \
504
BOX_CLASSES(DO_BOX_CLASS);
506
if (JVMCILibDumpJNIConfig == nullptr) {
507
_byte_array = env->FindClass("[B");
508
JVMCI_EXCEPTION_CHECK(env, "FindClass([B)");
509
_byte_array = (jclass) env->NewGlobalRef(_byte_array);
510
assert(_byte_array != nullptr, "uninitialized");
512
fileStream* st = JVMCIGlobals::get_jni_config_file();
513
st->print_cr("class [B");
516
#define DUMP_ALL_NATIVE_METHODS(class_symbol) do { \
517
current_class_name = class_symbol->as_C_string(); \
518
Klass* k = SystemDictionary::resolve_or_fail(class_symbol, true, CHECK_EXIT); \
519
InstanceKlass* iklass = InstanceKlass::cast(k); \
520
Array<Method*>* methods = iklass->methods(); \
521
for (int i = 0; i < methods->length(); i++) { \
522
Method* m = methods->at(i); \
523
if (m->is_native()) { \
524
st->print_cr("method %s %s %s", current_class_name, m->name()->as_C_string(), m->signature()->as_C_string()); \
529
if (JVMCILibDumpJNIConfig != nullptr) {
530
JavaThread* THREAD = JavaThread::current();
531
fileStream* st = JVMCIGlobals::get_jni_config_file();
533
DUMP_ALL_NATIVE_METHODS(vmSymbols::jdk_vm_ci_hotspot_CompilerToVM());
534
ThrowableInitDumper dumper(st);
535
vmSymbols::symbols_do(&dumper);
538
tty->print_cr("Dumped JVMCI shared library JNI configuration to %s", JVMCILibDumpJNIConfig);
542
#undef DUMP_ALL_NATIVE_METHODS
548
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))
551
static void register_natives_for_class(JNIEnv* env, jclass clazz, const char* name, const JNINativeMethod *methods, jint nMethods) {
552
if (clazz == nullptr) {
553
clazz = env->FindClass(name);
554
if (env->ExceptionCheck()) {
555
env->ExceptionDescribe();
556
fatal("Could not find class %s", name);
559
env->RegisterNatives(clazz, methods, nMethods);
560
if (env->ExceptionCheck()) {
561
env->ExceptionDescribe();
562
fatal("Failure registering natives for %s", name);
566
void JNIJVMCI::register_natives(JNIEnv* env) {
567
if (env != JavaThread::current()->jni_environment()) {
568
JNINativeMethod CompilerToVM_nmethods[] = {{ CC"registerNatives", CC"()V", FN_PTR(JVM_RegisterJVMCINatives) }};
569
JNINativeMethod JVMCI_nmethods[] = {{ CC"initializeRuntime", CC"()Ljdk/vm/ci/runtime/JVMCIRuntime;", FN_PTR(JVM_GetJVMCIRuntime) }};
570
JNINativeMethod Services_nmethods[] = {{ CC"readSystemPropertiesInfo", CC"([I)J", FN_PTR(JVM_ReadSystemPropertiesInfo) }};
572
register_natives_for_class(env, nullptr, "jdk/vm/ci/hotspot/CompilerToVM", CompilerToVM_nmethods, 1);
573
register_natives_for_class(env, JVMCI::clazz(), "jdk/vm/ci/runtime/JVMCI", JVMCI_nmethods, 1);
574
register_natives_for_class(env, Services::clazz(), "jdk/vm/ci/services/Services", Services_nmethods, 1);
585
#define FIELD3(className, name, sig) FIELD2(className, name)
586
#define FIELD2(className, name) \
587
jfieldID JNIJVMCI::className::_##name##_field_id = nullptr; \
588
int HotSpotJVMCI::className::_##name##_offset = 0;
589
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName)
590
#define CONSTRUCTOR(className, signature)
595
JVMCI_CLASSES_DO(EMPTY2, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2, METHOD, CONSTRUCTOR)
608
#undef PRIMARRAY_FIELD
609
#undef OBJECTARRAY_FIELD
611
#undef STATIC_OBJECT_FIELD
612
#undef STATIC_OBJECTARRAY_FIELD
613
#undef STATIC_INT_FIELD
614
#undef STATIC_BOOLEAN_FIELD
618
#define START_CLASS(className, fullClassName) \
619
void JNIJVMCI::className::initialize(JVMCI_TRAPS) { \
622
bool JNIJVMCI::className::is_instance(JVMCIEnv* jvmciEnv, JVMCIObject object) { \
623
JNIAccessMark jni(jvmciEnv); \
624
return jni()->IsInstanceOf(object.as_jobject(), className::clazz()) != 0; \
626
void JNIJVMCI::className::check(JVMCIEnv* jvmciEnv, JVMCIObject obj, const char* field_name, jfieldID offset) { \
627
assert(obj.is_non_null(), "null field access of %s.%s", #className, field_name); \
628
assert(jvmciEnv->isa_##className(obj), "wrong class, " #className " expected, found %s", jvmciEnv->klass_name(obj)); \
629
assert(offset != nullptr, "must be valid offset"); \
631
jclass JNIJVMCI::className::_class = nullptr;
635
#define FIELD(className, name, type, accessor, cast) \
636
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \
637
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
638
JNIAccessMark jni(jvmciEnv); \
639
return cast jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id); \
641
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \
642
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
643
JNIAccessMark jni(jvmciEnv); \
644
jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, x); \
648
#define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)
649
#define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)
650
#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
651
#define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)
652
#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)
654
#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
655
#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
656
#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
658
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
659
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
661
#define OOPISH_FIELD(className, name, type, accessor, cast) \
662
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \
663
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
664
JNIAccessMark jni(jvmciEnv); \
665
return cast wrap(jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id)); \
667
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \
668
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
669
JNIAccessMark jni(jvmciEnv); \
670
jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, resolve_handle(x)); \
673
#define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \
674
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \
675
JNIAccessMark jni(jvmciEnv); \
676
return cast wrap(jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id)); \
678
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \
679
JNIAccessMark jni(jvmciEnv); \
680
jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, resolve_handle(x)); \
683
#define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
684
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \
685
JNIAccessMark jni(jvmciEnv); \
686
return cast jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id); \
688
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \
689
JNIAccessMark jni(jvmciEnv); \
690
jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, x); \
693
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
694
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
695
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) \
696
jmethodID JNIJVMCI::className::_##methodName##_method;
698
#define CONSTRUCTOR(className, signature) \
699
jmethodID JNIJVMCI::className::_constructor;
704
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
717
#undef PRIMARRAY_FIELD
718
#undef OBJECTARRAY_FIELD
719
#undef STATIC_OOPISH_FIELD
720
#undef STATIC_OBJECT_FIELD
721
#undef STATIC_OBJECTARRAY_FIELD
722
#undef STATIC_INT_FIELD
723
#undef STATIC_BOOLEAN_FIELD
724
#undef STATIC_PRIMITIVE_FIELD