Path: blob/master/src/hotspot/share/jvmci/jvmciJavaClasses.cpp
40949 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223#include "precompiled.hpp"24#include "classfile/symbolTable.hpp"25#include "classfile/systemDictionary.hpp"26#include "classfile/vmClasses.hpp"27#include "interpreter/linkResolver.hpp"28#include "jvmci/jniAccessMark.inline.hpp"29#include "jvmci/jvmciJavaClasses.hpp"30#include "jvmci/jvmciRuntime.hpp"31#include "memory/resourceArea.hpp"32#include "oops/instanceKlass.inline.hpp"33#include "runtime/fieldDescriptor.inline.hpp"34#include "runtime/jniHandles.inline.hpp"35#include "runtime/java.hpp"3637// ------------------------------------------------------------------3839oop HotSpotJVMCI::resolve(JVMCIObject obj) {40return JNIHandles::resolve(obj.as_jobject());41}4243arrayOop HotSpotJVMCI::resolve(JVMCIArray obj) {44return (arrayOop) JNIHandles::resolve(obj.as_jobject());45}4647objArrayOop HotSpotJVMCI::resolve(JVMCIObjectArray obj) {48return (objArrayOop) JNIHandles::resolve(obj.as_jobject());49}5051typeArrayOop HotSpotJVMCI::resolve(JVMCIPrimitiveArray obj) {52return (typeArrayOop) JNIHandles::resolve(obj.as_jobject());53}5455JVMCIObject HotSpotJVMCI::wrap(oop obj) {56assert(Thread::current()->is_Java_thread(), "must be");57return JVMCIObject(JNIHandles::make_local(obj), true);58}5960/**61* Computes the field offset of a static or instance field.62* It looks up the name and signature symbols without creating new ones;63* all the symbols of these classes need to be already loaded.64*/65void HotSpotJVMCI::compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS) {66InstanceKlass* ik = InstanceKlass::cast(klass);67Symbol* name_symbol = SymbolTable::probe(name, (int)strlen(name));68Symbol* signature_symbol = SymbolTable::probe(signature, (int)strlen(signature));69if (name_symbol == NULL || signature_symbol == NULL) {70#ifndef PRODUCT71ik->print_on(tty);72#endif73fatal("symbol with name %s and signature %s was not found in symbol table (klass=%s)", name, signature, klass->name()->as_C_string());74}7576fieldDescriptor fd;77if (!ik->find_field(name_symbol, signature_symbol, &fd)) {78ResourceMark rm;79fatal("Could not find field %s.%s with signature %s", ik->external_name(), name, signature);80}81guarantee(fd.is_static() == static_field, "static/instance mismatch");82dest_offset = fd.offset();83assert(dest_offset != 0, "must be valid offset");84if (static_field) {85// Must ensure classes for static fields are initialized as the86// accessor itself does not include a class initialization check.87ik->initialize(CHECK);88}89JVMCI_event_2(" field offset for %s %s.%s = %d", signature, ik->external_name(), name, dest_offset);90}9192#ifndef PRODUCT93static void check_resolve_method(const char* call_type, Klass* resolved_klass, Symbol* method_name, Symbol* method_signature, TRAPS) {94Method* method = NULL;95LinkInfo link_info(resolved_klass, method_name, method_signature, NULL, LinkInfo::AccessCheck::skip, LinkInfo::LoaderConstraintCheck::skip);96if (strcmp(call_type, "call_static") == 0) {97method = LinkResolver::resolve_static_call_or_null(link_info);98} else if (strcmp(call_type, "call_virtual") == 0) {99method = LinkResolver::resolve_virtual_call_or_null(resolved_klass, link_info);100} else if (strcmp(call_type, "call_special") == 0) {101method = LinkResolver::resolve_special_call_or_null(link_info);102} else {103fatal("Unknown or unsupported call type: %s", call_type);104}105if (method == NULL) {106fatal("Could not resolve %s.%s%s", resolved_klass->external_name(), method_name->as_C_string(), method_signature->as_C_string());107}108}109#endif110111jclass JNIJVMCI::_box_classes[T_CONFLICT+1];112jclass JNIJVMCI::_byte_array;113jfieldID JNIJVMCI::_box_fields[T_CONFLICT+1];114jmethodID JNIJVMCI::_box_constructors[T_CONFLICT+1];115jmethodID JNIJVMCI::_Class_getName_method;116117jmethodID JNIJVMCI::_HotSpotResolvedJavaMethodImpl_fromMetaspace_method;118jmethodID JNIJVMCI::_HotSpotConstantPool_fromMetaspace_method;119jmethodID JNIJVMCI::_HotSpotResolvedObjectTypeImpl_fromMetaspace_method;120jmethodID JNIJVMCI::_HotSpotResolvedPrimitiveType_fromMetaspace_method;121122#define START_CLASS(className, fullClassName) { \123Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::fullClassName(), true, CHECK); \124className::_klass = InstanceKlass::cast(k); \125JVMCI_event_2(" klass for %s = " PTR_FORMAT, k->external_name(), p2i(k)); \126className::_klass->initialize(CHECK);127128#define END_CLASS }129130#define FIELD(className, name, signature, static_field) compute_offset(className::_##name##_offset, className::_klass, #name, signature, static_field, CHECK);131#define CHAR_FIELD(className, name) FIELD(className, name, "C", false)132#define INT_FIELD(className, name) FIELD(className, name, "I", false)133#define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false)134#define LONG_FIELD(className, name) FIELD(className, name, "J", false)135#define FLOAT_FIELD(className, name) FIELD(className, name, "F", false)136#define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false)137#define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true)138#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)139#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)140#ifdef PRODUCT141#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)142#define CONSTRUCTOR(className, signature)143#else144#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \145check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK);146#define CONSTRUCTOR(className, signature) { \147TempNewSymbol sig = SymbolTable::new_symbol(signature); \148check_resolve_method("call_special", k, vmSymbols::object_initializer_name(), sig, CHECK); \149}150#endif151/**152* Computes and initializes the offsets used by HotSpotJVMCI.153*/154void HotSpotJVMCI::compute_offsets(TRAPS) {155JVMCI_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)156}157158#undef START_CLASS159#undef END_CLASS160#undef METHOD161#undef CONSTRUCTOR162#undef FIELD163#undef CHAR_FIELD164#undef INT_FIELD165#undef BOOLEAN_FIELD166#undef LONG_FIELD167#undef FLOAT_FIELD168#undef OBJECT_FIELD169#undef PRIMARRAY_FIELD170#undef OBJECTARRAY_FIELD171#undef STATIC_FIELD172#undef STATIC_OBJECT_FIELD173#undef STATIC_OBJECTARRAY_FIELD174#undef STATIC_INT_FIELD175#undef STATIC_BOOLEAN_FIELD176#undef EMPTY_CAST177178// ------------------------------------------------------------------179180#define START_CLASS(className, fullClassName) \181void HotSpotJVMCI::className::initialize(JVMCI_TRAPS) { \182JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \183className::klass()->initialize(CHECK); \184} \185bool HotSpotJVMCI::className::is_instance(JVMCIEnv* env, JVMCIObject object) { \186return resolve(object)->is_a(className::klass()); \187} \188void HotSpotJVMCI::className::check(oop obj, const char* field_name, int offset) { \189assert(obj != NULL, "NULL field access of %s.%s", #className, field_name); \190assert(obj->is_a(className::klass()), "wrong class, " #className " expected, found %s", obj->klass()->external_name()); \191assert(offset != 0, "must be valid offset"); \192} \193InstanceKlass* HotSpotJVMCI::className::_klass = NULL;194195#define END_CLASS196197#define FIELD(className, name, type, accessor, cast) \198type HotSpotJVMCI::className::name(JVMCIEnv* env, oop obj) { className::check(obj, #name, className::_##name##_offset); return cast obj->accessor(className::_##name##_offset); } \199void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, oop obj, type x) { className::check(obj, #name, className::_##name##_offset); obj->accessor##_put(className::_##name##_offset, x); }200201#define EMPTY_CAST202#define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field, EMPTY_CAST)203#define INT_FIELD(className, name) FIELD(className, name, jint, int_field, EMPTY_CAST)204#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field, EMPTY_CAST)205#define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field, EMPTY_CAST)206#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field, EMPTY_CAST)207208#define OBJECT_FIELD(className, name, signature) FIELD(className, name, oop, obj_field, EMPTY_CAST)209#define OBJECTARRAY_FIELD(className, name, signature) FIELD(className, name, objArrayOop, obj_field, (objArrayOop))210#define PRIMARRAY_FIELD(className, name, signature) FIELD(className, name, typeArrayOop, obj_field, (typeArrayOop))211#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, oop)212#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, objArrayOop)213#define STATIC_OOPISH_FIELD(className, name, type) \214type HotSpotJVMCI::className::name(JVMCIEnv* env) { \215assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \216InstanceKlass* ik = className::klass(); \217oop base = ik->static_field_base_raw(); \218oop result = HeapAccess<>::oop_load_at(base, className::_##name##_offset); \219return type(result); \220} \221void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, type x) { \222assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \223assert(className::klass() != NULL, "Class not yet loaded: " #className); \224InstanceKlass* ik = className::klass(); \225oop base = ik->static_field_base_raw(); \226HeapAccess<>::oop_store_at(base, className::_##name##_offset, x); \227}228#define STATIC_PRIMITIVE_FIELD(className, name, jtypename) \229jtypename HotSpotJVMCI::className::get_##name(JVMCIEnv* env) { \230assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \231InstanceKlass* ik = className::klass(); \232oop base = ik->static_field_base_raw(); \233return HeapAccess<>::load_at(base, className::_##name##_offset); \234} \235void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, jtypename x) { \236assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \237InstanceKlass* ik = className::klass(); \238oop base = ik->static_field_base_raw(); \239HeapAccess<>::store_at(base, _##name##_offset, x); \240}241242#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint)243#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean)244#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)245#define CONSTRUCTOR(className, signature)246247/**248* Generates the method and field definitions for the classes in HotSpotJVMCI. For example:249*250* void HotSpotJVMCI::Architecture::initialize(JVMCIEnv* env) { ... }251* bool HotSpotJVMCI::Architecture::is_instance(JVMCIEnv* env, JVMCIObject object) { ... }252* void HotSpotJVMCI::Architecture::check(oop obj, const char* field_name, int offset) { ... }253* oop HotSpotJVMCI::Architecture::wordKind(JVMCIEnv* env, oop obj) { ... }254* void HotSpotJVMCI::Architecture::set_wordKind(JVMCIEnv* env, oop obj, oop x) { ... }255*256* InstanceKlass *HotSpotJVMCI::Architecture::_klass = NULL;257*/258JVMCI_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)259260#undef START_CLASS261#undef END_CLASS262#undef METHOD263#undef CONSTRUCTOR264#undef FIELD265#undef CHAR_FIELD266#undef INT_FIELD267#undef BOOLEAN_FIELD268#undef LONG_FIELD269#undef FLOAT_FIELD270#undef OBJECT_FIELD271#undef PRIMARRAY_FIELD272#undef OBJECTARRAY_FIELD273#undef STATIC_OOPISH_FIELD274#undef STATIC_OBJECT_FIELD275#undef STATIC_OBJECTARRAY_FIELD276#undef STATIC_INT_FIELD277#undef STATIC_BOOLEAN_FIELD278#undef STATIC_PRIMITIVE_FIELD279#undef EMPTY_CAST280281/**282* Initializes the JNI id of a field. As per the JNI specification,283* this ensures the declaring class is initialized.284*/285void JNIJVMCI::initialize_field_id(JNIEnv* env, jfieldID &fieldid, jclass clazz, const char* class_name, const char* name, const char* signature, bool static_field) {286if (JVMCILibDumpJNIConfig != NULL) {287fileStream* st = JVMCIGlobals::get_jni_config_file();288st->print_cr("field %s %s %s", class_name, name, signature);289return;290}291if (env->ExceptionCheck()) {292return;293}294jfieldID current = fieldid;295if (static_field) {296// Class initialization barrier297fieldid = env->GetStaticFieldID(clazz, name, signature);298} else {299// Class initialization barrier300fieldid = env->GetFieldID(clazz, name, signature);301}302JVMCI_event_2(" jfieldID for %s %s.%s = " PTR_FORMAT, signature, class_name, name, p2i(fieldid));303304if (env->ExceptionCheck()) {305env->ExceptionDescribe();306env->ExceptionClear();307ResourceMark rm;308fatal("Could not find field %s.%s with signature %s", class_name, name, signature);309}310}311312#define START_CLASS(className, fullClassName) { \313current_class_name = vmSymbols::fullClassName()->as_C_string(); \314if (JVMCILibDumpJNIConfig != NULL) { \315fileStream* st = JVMCIGlobals::get_jni_config_file(); \316st->print_cr("class %s", current_class_name); \317} else { \318jclass k = env->FindClass(current_class_name); \319JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", current_class_name); \320assert(k != NULL, #fullClassName " not initialized"); \321k = (jclass) env->NewGlobalRef(k); \322JVMCI_event_2(" jclass for %s = " PTR_FORMAT, current_class_name, p2i(k)); \323className::_class = k; \324}325326#define END_CLASS current_class_name = NULL; }327328#define FIELD(className, name, signature, static_field) initialize_field_id(env, className::_##name##_field_id, className::_class, current_class_name, #name, signature, static_field);329#define CHAR_FIELD(className, name) FIELD(className, name, "C", false)330#define INT_FIELD(className, name) FIELD(className, name, "I", false)331#define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false)332#define LONG_FIELD(className, name) FIELD(className, name, "J", false)333#define FLOAT_FIELD(className, name) FIELD(className, name, "F", false)334#define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false)335#define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true)336#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)337#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)338339#define GET_JNI_METHOD(jniGetMethod, dst, clazz, methodName, signature) \340if (JVMCILibDumpJNIConfig != NULL) { \341fileStream* st = JVMCIGlobals::get_jni_config_file(); \342st->print_cr("method %s %s %s", current_class_name, methodName, signature); \343} else { \344jmethodID current = dst; \345dst = env->jniGetMethod(clazz, methodName, signature); \346JVMCI_EXCEPTION_CHECK(env, #jniGetMethod "(%s.%s%s)", \347current_class_name, methodName, signature); \348assert(dst != NULL, "uninitialized"); \349JVMCI_event_2(" jmethodID for %s.%s%s = " PTR_FORMAT, \350current_class_name, methodName, signature, p2i(dst)); \351}352353#define GET_JNI_CONSTRUCTOR(clazz, signature) \354GET_JNI_METHOD(GetMethodID, JNIJVMCI::clazz::_constructor, clazz::_class, "<init>", signature) \355356#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \357GET_JNI_METHOD(jniGetMethod, \358className::_##methodName##_method, \359className::clazz(), \360vmSymbols::methodName##_name()->as_C_string(), \361vmSymbols::signatureSymbolName()->as_C_string())362363#define CONSTRUCTOR(className, signature) \364GET_JNI_CONSTRUCTOR(className, signature)365366extern "C" {367void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);368jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);369}370371// Dumps symbols for public <init>() and <init>(String) methods of372// non-abstract Throwable subtypes known by the VM. This is to373// support the use of reflection in jdk.vm.ci.hotspot.TranslatedException.create().374class ThrowableInitDumper : public SymbolClosure {375private:376fileStream* _st;377public:378ThrowableInitDumper(fileStream* st) { _st = st; }379void do_symbol(Symbol** p) {380JavaThread* THREAD = JavaThread::current(); // For exception macros.381Symbol* name = *p;382if (name == NULL) {383return;384}385Klass* k = SystemDictionary::resolve_or_null(name, CHECK_EXIT);386if (k != NULL && k->is_instance_klass()) {387InstanceKlass* iklass = InstanceKlass::cast(k);388if (iklass->is_subclass_of(vmClasses::Throwable_klass()) && iklass->is_public() && !iklass->is_abstract()) {389const char* class_name = NULL;390Array<Method*>* methods = iklass->methods();391for (int i = 0; i < methods->length(); i++) {392Method* m = methods->at(i);393if (m->name() == vmSymbols::object_initializer_name() &&394m->is_public() &&395(m->signature() == vmSymbols::void_method_signature() || m->signature() == vmSymbols::string_void_signature())) {396if (class_name == NULL) {397class_name = name->as_C_string();398_st->print_cr("class %s", class_name);399}400_st->print_cr("method %s %s %s", class_name, m->name()->as_C_string(), m->signature()->as_C_string());401}402}403}404}405}406};407408#define IN_CLASS(fullClassName) current_class_name = vmSymbols::fullClassName()->as_C_string()409/**410* Initializes the JNI method and field ids used in JNIJVMCI.411*/412void JNIJVMCI::initialize_ids(JNIEnv* env) {413ResourceMark rm;414const char* current_class_name = NULL;415JVMCI_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)416417IN_CLASS(java_lang_Class);418GET_JNI_METHOD(GetMethodID, _Class_getName_method, Class::_class, "getName", "()Ljava/lang/String;");419420IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedPrimitiveType);421GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedPrimitiveType_fromMetaspace_method, HotSpotResolvedPrimitiveType::_class,422vmSymbols::fromMetaspace_name()->as_C_string(),423vmSymbols::primitive_fromMetaspace_signature()->as_C_string());424IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl);425GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedObjectTypeImpl_fromMetaspace_method, HotSpotResolvedObjectTypeImpl::_class,426vmSymbols::fromMetaspace_name()->as_C_string(),427vmSymbols::klass_fromMetaspace_signature()->as_C_string());428IN_CLASS(jdk_vm_ci_hotspot_HotSpotConstantPool);429GET_JNI_METHOD(GetStaticMethodID, _HotSpotConstantPool_fromMetaspace_method, HotSpotConstantPool::_class,430vmSymbols::fromMetaspace_name()->as_C_string(),431vmSymbols::constantPool_fromMetaspace_signature()->as_C_string());432IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl);433GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedJavaMethodImpl_fromMetaspace_method, HotSpotResolvedJavaMethodImpl::_class,434vmSymbols::fromMetaspace_name()->as_C_string(),435vmSymbols::method_fromMetaspace_signature()->as_C_string());436437#define BOX_CLASSES(generate) \438generate(Boolean, T_BOOLEAN, Z) \439generate(Byte, T_BYTE, B) \440generate(Character, T_CHAR, C) \441generate(Short, T_SHORT, S) \442generate(Integer, T_INT, I) \443generate(Long, T_LONG, J) \444generate(Float, T_FLOAT, F) \445generate(Double, T_DOUBLE, D) \446447#define DO_BOX_CLASS(klass, basicType, type) \448current_class_name = "java/lang/" #klass; \449if (JVMCILibDumpJNIConfig == NULL) { \450_box_classes[basicType] = env->FindClass("java/lang/" #klass); \451JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", #klass); \452_box_classes[basicType] = (jclass) env->NewGlobalRef(_box_classes[basicType]); \453assert(_box_classes[basicType] != NULL, "uninitialized"); \454_box_fields[basicType] = env->GetFieldID(_box_classes[basicType], "value", #type); \455JVMCI_EXCEPTION_CHECK(env, "GetFieldID(%s, value, %s)", #klass, #type); \456GET_JNI_METHOD(GetMethodID, _box_constructors[basicType], _box_classes[basicType], "<init>", "(" #type ")V"); \457} else { \458fileStream* st = JVMCIGlobals::get_jni_config_file(); \459st->print_cr("field %s value %s", current_class_name, #type); \460st->print_cr("method %s <init> (%s)V", current_class_name, #type); \461}462463BOX_CLASSES(DO_BOX_CLASS);464465if (JVMCILibDumpJNIConfig == NULL) {466_byte_array = env->FindClass("[B");467JVMCI_EXCEPTION_CHECK(env, "FindClass([B)");468_byte_array = (jclass) env->NewGlobalRef(_byte_array);469assert(_byte_array != NULL, "uninitialized");470} else {471fileStream* st = JVMCIGlobals::get_jni_config_file();472st->print_cr("class [B");473}474475#define DUMP_ALL_NATIVE_METHODS(class_symbol) do { \476current_class_name = class_symbol->as_C_string(); \477Klass* k = SystemDictionary::resolve_or_fail(class_symbol, true, CHECK_EXIT); \478InstanceKlass* iklass = InstanceKlass::cast(k); \479Array<Method*>* methods = iklass->methods(); \480for (int i = 0; i < methods->length(); i++) { \481Method* m = methods->at(i); \482if (m->is_native()) { \483st->print_cr("method %s %s %s", current_class_name, m->name()->as_C_string(), m->signature()->as_C_string()); \484} \485} \486} while(0)487488if (JVMCILibDumpJNIConfig != NULL) {489JavaThread* THREAD = JavaThread::current(); // For exception macros.490fileStream* st = JVMCIGlobals::get_jni_config_file();491492DUMP_ALL_NATIVE_METHODS(vmSymbols::jdk_vm_ci_hotspot_CompilerToVM());493ThrowableInitDumper dumper(st);494vmSymbols::symbols_do(&dumper);495496st->flush();497tty->print_cr("Dumped JVMCI shared library JNI configuration to %s", JVMCILibDumpJNIConfig);498vm_exit(0);499}500501#undef DUMP_ALL_NATIVE_METHODS502#undef DO_BOX_CLASS503#undef BOX_CLASSES504#undef IN_CLASS505506#define CC (char*) /*cast a literal from (const char*)*/507#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))508}509510static void register_natives_for_class(JNIEnv* env, jclass clazz, const char* name, const JNINativeMethod *methods, jint nMethods) {511if (clazz == NULL) {512clazz = env->FindClass(name);513if (env->ExceptionCheck()) {514env->ExceptionDescribe();515fatal("Could not find class %s", name);516}517}518env->RegisterNatives(clazz, methods, nMethods);519if (env->ExceptionCheck()) {520env->ExceptionDescribe();521fatal("Failure registering natives for %s", name);522}523}524525void JNIJVMCI::register_natives(JNIEnv* env) {526if (env != JavaThread::current()->jni_environment()) {527JNINativeMethod CompilerToVM_nmethods[] = {{ CC"registerNatives", CC"()V", FN_PTR(JVM_RegisterJVMCINatives) }};528JNINativeMethod JVMCI_nmethods[] = {{ CC"initializeRuntime", CC"()Ljdk/vm/ci/runtime/JVMCIRuntime;", FN_PTR(JVM_GetJVMCIRuntime) }};529530register_natives_for_class(env, NULL, "jdk/vm/ci/hotspot/CompilerToVM", CompilerToVM_nmethods, 1);531register_natives_for_class(env, JVMCI::clazz(), "jdk/vm/ci/runtime/JVMCI", JVMCI_nmethods, 1);532}533}534535#undef METHOD536#undef CONSTRUCTOR537#undef FIELD2538539#define EMPTY0540#define EMPTY1(x)541#define EMPTY2(x,y)542#define FIELD3(className, name, sig) FIELD2(className, name)543#define FIELD2(className, name) \544jfieldID JNIJVMCI::className::_##name##_field_id = 0; \545int HotSpotJVMCI::className::_##name##_offset = 0;546#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)547#define CONSTRUCTOR(className, signature)548549// Generates the definitions of static fields used by the accessors. For example:550// jfieldID JNIJVMCI::Architecture::_wordKind_field_id = 0;551// jfieldID HotSpotJVMCI::Architecture::_wordKind_offset = 0;552JVMCI_CLASSES_DO(EMPTY2, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2, METHOD, CONSTRUCTOR)553554#undef START_CLASS555#undef END_CLASS556#undef METHOD557#undef CONSTRUCTOR558#undef FIELD559#undef CHAR_FIELD560#undef INT_FIELD561#undef BOOLEAN_FIELD562#undef LONG_FIELD563#undef FLOAT_FIELD564#undef OBJECT_FIELD565#undef PRIMARRAY_FIELD566#undef OBJECTARRAY_FIELD567#undef STATIC_FIELD568#undef STATIC_OBJECT_FIELD569#undef STATIC_OBJECTARRAY_FIELD570#undef STATIC_INT_FIELD571#undef STATIC_BOOLEAN_FIELD572#undef EMPTY_CAST573574575#define START_CLASS(className, fullClassName) \576void JNIJVMCI::className::initialize(JVMCI_TRAPS) { \577/* should already be initialized */ \578} \579bool JNIJVMCI::className::is_instance(JVMCIEnv* jvmciEnv, JVMCIObject object) { \580JNIAccessMark jni(jvmciEnv); \581return jni()->IsInstanceOf(object.as_jobject(), className::clazz()) != 0; \582} \583void JNIJVMCI::className::check(JVMCIEnv* jvmciEnv, JVMCIObject obj, const char* field_name, jfieldID offset) { \584assert(obj.is_non_null(), "NULL field access of %s.%s", #className, field_name); \585assert(jvmciEnv->isa_##className(obj), "wrong class, " #className " expected, found %s", jvmciEnv->klass_name(obj)); \586assert(offset != 0, "must be valid offset"); \587} \588jclass JNIJVMCI::className::_class = NULL;589590#define END_CLASS591592#define FIELD(className, name, type, accessor, cast) \593type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \594className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \595JNIAccessMark jni(jvmciEnv); \596return cast jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id); \597} \598void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \599className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \600JNIAccessMark jni(jvmciEnv); \601jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, x); \602} \603604#define EMPTY_CAST605#define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)606#define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)607#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)608#define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)609#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)610611#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)612#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))613#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))614615#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))616#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))617618#define OOPISH_FIELD(className, name, type, accessor, cast) \619type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \620className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \621JNIAccessMark jni(jvmciEnv); \622return cast wrap(jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id)); \623} \624void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \625className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \626JNIAccessMark jni(jvmciEnv); \627jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, resolve_handle(x)); \628}629630#define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \631type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \632JNIAccessMark jni(jvmciEnv); \633return cast wrap(jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id)); \634} \635void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \636JNIAccessMark jni(jvmciEnv); \637jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, resolve_handle(x)); \638}639640#define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \641type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \642JNIAccessMark jni(jvmciEnv); \643return cast jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id); \644} \645void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \646JNIAccessMark jni(jvmciEnv); \647jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, x); \648}649650#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)651#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)652#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \653jmethodID JNIJVMCI::className::_##methodName##_method;654655#define CONSTRUCTOR(className, signature) \656jmethodID JNIJVMCI::className::_constructor;657658/**659* Generates the method definitions for the classes in HotSpotJVMCI.660*/661JVMCI_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)662663#undef METHOD664#undef CONSTRUCTOR665#undef START_CLASS666#undef END_CLASS667#undef FIELD668#undef CHAR_FIELD669#undef INT_FIELD670#undef BOOLEAN_FIELD671#undef LONG_FIELD672#undef FLOAT_FIELD673#undef OBJECT_FIELD674#undef PRIMARRAY_FIELD675#undef OBJECTARRAY_FIELD676#undef STATIC_OOPISH_FIELD677#undef STATIC_OBJECT_FIELD678#undef STATIC_OBJECTARRAY_FIELD679#undef STATIC_INT_FIELD680#undef STATIC_BOOLEAN_FIELD681#undef STATIC_PRIMITIVE_FIELD682#undef OOPISH_FIELD683#undef EMPTY_CAST684685686