1 /* 2 * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "classfile/symbolTable.hpp" 26 #include "interpreter/linkResolver.hpp" 27 #include "jvmci/jvmciEnv.hpp" 28 #include "jvmci/jvmciJavaClasses.hpp" 29 #include "jvmci/jvmciRuntime.hpp" 30 #include "memory/resourceArea.hpp" 31 #include "oops/oop.inline.hpp" 32 #include "runtime/jniHandles.inline.hpp" 33 #include "runtime/fieldDescriptor.inline.hpp" 34 35 // ------------------------------------------------------------------ 36 37 /** 38 * Computes the field offset of a static or instance field. 39 * It looks up the name and signature symbols without creating new ones; 40 * all the symbols of these classes need to be already loaded. 41 */ 42 void HotSpotJVMCI::compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS) { 43 InstanceKlass* ik = InstanceKlass::cast(klass); 44 Symbol* name_symbol = SymbolTable::probe(name, (int)strlen(name)); 45 Symbol* signature_symbol = SymbolTable::probe(signature, (int)strlen(signature)); 46 if (name_symbol == NULL || signature_symbol == NULL) { 47 #ifndef PRODUCT 48 ik->print_on(tty); 49 #endif 50 fatal("symbol with name %s and signature %s was not found in symbol table (klass=%s)", name, signature, klass->name()->as_C_string()); 51 } 52 53 fieldDescriptor fd; 54 if (!ik->find_field(name_symbol, signature_symbol, &fd)) { 55 ResourceMark rm; 56 fatal("Could not find field %s.%s with signature %s", ik->external_name(), name, signature); 57 } 58 guarantee(fd.is_static() == static_field, "static/instance mismatch"); 59 dest_offset = fd.offset(); 60 assert(dest_offset != 0, "must be valid offset"); 61 if (static_field) { 62 // Must ensure classes for static fields are initialized as the 63 // accessor itself does not include a class initialization check. 64 ik->initialize(CHECK); 65 } 66 } 67 68 #ifndef PRODUCT 69 static void check_resolve_method(const char* call_type, Klass* resolved_klass, Symbol* method_name, Symbol* method_signature, TRAPS) { 70 methodHandle method; 71 LinkInfo link_info(resolved_klass, method_name, method_signature, NULL, LinkInfo::skip_access_check); 72 if (strcmp(call_type, "call_static") == 0) { 73 method = LinkResolver::resolve_static_call_or_null(link_info); 74 } else if (strcmp(call_type, "call_virtual") == 0) { 75 method = LinkResolver::resolve_virtual_call_or_null(resolved_klass, link_info); 76 } else if (strcmp(call_type, "call_special") == 0) { 77 method = LinkResolver::resolve_special_call_or_null(link_info); 78 } else { 79 fatal("Unknown or unsupported call type: %s", call_type); 80 } 81 if (method.is_null()) { 82 fatal("Could not resolve %s.%s%s", resolved_klass->external_name(), method_name->as_C_string(), method_signature->as_C_string()); 83 } 84 } 85 #endif 86 87 jclass JNIJVMCI::_box_classes[T_CONFLICT+1]; 88 jclass JNIJVMCI::_byte_array; 89 jfieldID JNIJVMCI::_box_fields[T_CONFLICT+1]; 90 jmethodID JNIJVMCI::_box_constructors[T_CONFLICT+1]; 91 jmethodID JNIJVMCI::_Class_getName_method; 92 93 jmethodID JNIJVMCI::_HotSpotResolvedJavaMethodImpl_fromMetaspace_method; 94 jmethodID JNIJVMCI::_HotSpotConstantPool_fromMetaspace_method; 95 jmethodID JNIJVMCI::_HotSpotResolvedObjectTypeImpl_fromMetaspace_method; 96 jmethodID JNIJVMCI::_HotSpotResolvedPrimitiveType_fromMetaspace_method; 97 98 #define START_CLASS(className, fullClassName) { \ 99 Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::fullClassName(), true, CHECK); \ 100 className::_klass = InstanceKlass::cast(k); \ 101 className::_klass->initialize(CHECK); 102 103 #define END_CLASS } 104 105 #define FIELD(className, name, signature, static_field) compute_offset(className::_##name##_offset, className::_klass, #name, signature, static_field, CHECK); 106 #define CHAR_FIELD(className, name) FIELD(className, name, "C", false) 107 #define INT_FIELD(className, name) FIELD(className, name, "I", false) 108 #define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false) 109 #define LONG_FIELD(className, name) FIELD(className, name, "J", false) 110 #define FLOAT_FIELD(className, name) FIELD(className, name, "F", false) 111 #define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false) 112 #define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true) 113 #define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true) 114 #define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true) 115 #ifdef PRODUCT 116 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) 117 #define CONSTRUCTOR(className, signature) 118 #else 119 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \ 120 check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK); 121 #define CONSTRUCTOR(className, signature) { \ 122 TempNewSymbol sig = SymbolTable::new_symbol(signature, CHECK); \ 123 check_resolve_method("call_special", k, vmSymbols::object_initializer_name(), sig, CHECK); \ 124 } 125 #endif 126 /** 127 * Computes and initializes the offsets used by HotSpotJVMCI. 128 */ 129 void HotSpotJVMCI::compute_offsets(TRAPS) { 130 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) 131 } 132 133 #undef START_CLASS 134 #undef END_CLASS 135 #undef METHOD 136 #undef CONSTRUCTOR 137 #undef FIELD 138 #undef CHAR_FIELD 139 #undef INT_FIELD 140 #undef BOOLEAN_FIELD 141 #undef LONG_FIELD 142 #undef FLOAT_FIELD 143 #undef OBJECT_FIELD 144 #undef PRIMARRAY_FIELD 145 #undef OBJECTARRAY_FIELD 146 #undef STATIC_FIELD 147 #undef STATIC_OBJECT_FIELD 148 #undef STATIC_OBJECTARRAY_FIELD 149 #undef STATIC_INT_FIELD 150 #undef STATIC_BOOLEAN_FIELD 151 #undef EMPTY_CAST 152 153 // ------------------------------------------------------------------ 154 155 #define START_CLASS(className, fullClassName) \ 156 void HotSpotJVMCI::className::initialize(JVMCI_TRAPS) { \ 157 Thread* THREAD = Thread::current(); \ 158 className::klass()->initialize(CHECK); \ 159 } \ 160 bool HotSpotJVMCI::className::is_instance(JVMCIEnv* env, JVMCIObject object) { \ 161 return resolve(object)->is_a(className::klass()); \ 162 } \ 163 void HotSpotJVMCI::className::check(oop obj, const char* field_name, int offset) { \ 164 assert(obj != NULL, "NULL field access of %s.%s", #className, field_name); \ 165 assert(obj->is_a(className::klass()), "wrong class, " #className " expected, found %s", obj->klass()->external_name()); \ 166 assert(offset != 0, "must be valid offset"); \ 167 } \ 168 InstanceKlass* HotSpotJVMCI::className::_klass = NULL; 169 170 #define END_CLASS 171 172 #define FIELD(className, name, type, accessor, cast) \ 173 type HotSpotJVMCI::className::name(JVMCIEnv* env, oop obj) { className::check(obj, #name, className::_##name##_offset); return cast obj->accessor(className::_##name##_offset); } \ 174 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); } 175 176 #define EMPTY_CAST 177 #define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field, EMPTY_CAST) 178 #define INT_FIELD(className, name) FIELD(className, name, jint, int_field, EMPTY_CAST) 179 #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field, EMPTY_CAST) 180 #define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field, EMPTY_CAST) 181 #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field, EMPTY_CAST) 182 183 #define OBJECT_FIELD(className, name, signature) FIELD(className, name, oop, obj_field, EMPTY_CAST) 184 #define OBJECTARRAY_FIELD(className, name, signature) FIELD(className, name, objArrayOop, obj_field, (objArrayOop)) 185 #define PRIMARRAY_FIELD(className, name, signature) FIELD(className, name, typeArrayOop, obj_field, (typeArrayOop)) 186 #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, oop) 187 #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, objArrayOop) 188 #define STATIC_OOPISH_FIELD(className, name, type) \ 189 type HotSpotJVMCI::className::name(JVMCIEnv* env) { \ 190 assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \ 191 InstanceKlass* ik = className::klass(); \ 192 oop base = ik->static_field_base_raw(); \ 193 oop result = HeapAccess<>::oop_load_at(base, className::_##name##_offset); \ 194 return type(result); \ 195 } \ 196 void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, type x) { \ 197 assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \ 198 assert(className::klass() != NULL, "Class not yet loaded: " #className); \ 199 InstanceKlass* ik = className::klass(); \ 200 oop base = ik->static_field_base_raw(); \ 201 HeapAccess<>::oop_store_at(base, className::_##name##_offset, x); \ 202 } 203 #define STATIC_PRIMITIVE_FIELD(className, name, jtypename) \ 204 jtypename HotSpotJVMCI::className::get_##name(JVMCIEnv* env) { \ 205 assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \ 206 InstanceKlass* ik = className::klass(); \ 207 oop base = ik->static_field_base_raw(); \ 208 return HeapAccess<>::load_at(base, className::_##name##_offset); \ 209 } \ 210 void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, jtypename x) { \ 211 assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \ 212 InstanceKlass* ik = className::klass(); \ 213 oop base = ik->static_field_base_raw(); \ 214 HeapAccess<>::store_at(base, _##name##_offset, x); \ 215 } 216 217 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint) 218 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean) 219 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) 220 #define CONSTRUCTOR(className, signature) 221 222 /** 223 * Generates the method and field definitions for the classes in HotSpotJVMCI. For example: 224 * 225 * void HotSpotJVMCI::Architecture::initialize(JVMCIEnv* env) { ... } 226 * bool HotSpotJVMCI::Architecture::is_instance(JVMCIEnv* env, JVMCIObject object) { ... } 227 * void HotSpotJVMCI::Architecture::check(oop obj, const char* field_name, int offset) { ... } 228 * oop HotSpotJVMCI::Architecture::wordKind(JVMCIEnv* env, oop obj) { ... } 229 * void HotSpotJVMCI::Architecture::set_wordKind(JVMCIEnv* env, oop obj, oop x) { ... } 230 * 231 * InstanceKlass *HotSpotJVMCI::Architecture::_klass = NULL; 232 */ 233 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) 234 235 #undef START_CLASS 236 #undef END_CLASS 237 #undef METHOD 238 #undef CONSTRUCTOR 239 #undef FIELD 240 #undef CHAR_FIELD 241 #undef INT_FIELD 242 #undef BOOLEAN_FIELD 243 #undef LONG_FIELD 244 #undef FLOAT_FIELD 245 #undef OBJECT_FIELD 246 #undef PRIMARRAY_FIELD 247 #undef OBJECTARRAY_FIELD 248 #undef STATIC_OOPISH_FIELD 249 #undef STATIC_OBJECT_FIELD 250 #undef STATIC_OBJECTARRAY_FIELD 251 #undef STATIC_INT_FIELD 252 #undef STATIC_BOOLEAN_FIELD 253 #undef STATIC_PRIMITIVE_FIELD 254 #undef EMPTY_CAST 255 256 /** 257 * Initializes the JNI id of a field. As per the JNI specification, 258 * this ensures the declaring class is initialized. 259 */ 260 void JNIJVMCI::initialize_field_id(JNIEnv* env, jfieldID &fieldid, jclass clazz, const char* class_name, const char* name, const char* signature, bool static_field) { 261 if (JVMCILibDumpJNIConfig != NULL) { 262 fileStream* st = JVMCIGlobals::get_jni_config_file(); 263 st->print_cr("field %s %s %s", class_name, name, signature); 264 return; 265 } 266 if (env->ExceptionCheck()) { 267 return; 268 } 269 if (static_field) { 270 // Class initialization barrier 271 fieldid = env->GetStaticFieldID(clazz, name, signature); 272 } else { 273 // Class initialization barrier 274 fieldid = env->GetFieldID(clazz, name, signature); 275 } 276 277 if (env->ExceptionCheck()) { 278 env->ExceptionDescribe(); 279 env->ExceptionClear(); 280 ResourceMark rm; 281 Thread* THREAD = Thread::current(); 282 fatal("Could not find field %s.%s with signature %s", class_name, name, signature); 283 } 284 } 285 286 #define START_CLASS(className, fullClassName) { \ 287 current_class_name = vmSymbols::fullClassName()->as_C_string(); \ 288 if (JVMCILibDumpJNIConfig != NULL) { \ 289 fileStream* st = JVMCIGlobals::get_jni_config_file(); \ 290 st->print_cr("class %s", current_class_name); \ 291 } else { \ 292 jclass k = env->FindClass(current_class_name); \ 293 JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", current_class_name); \ 294 assert(k != NULL, #fullClassName " not initialized"); \ 295 className::_class = (jclass) env->NewGlobalRef(k); \ 296 } 297 298 #define END_CLASS current_class_name = NULL; } 299 300 #define FIELD(className, name, signature, static_field) initialize_field_id(env, className::_##name##_field_id, className::_class, current_class_name, #name, signature, static_field); 301 #define CHAR_FIELD(className, name) FIELD(className, name, "C", false) 302 #define INT_FIELD(className, name) FIELD(className, name, "I", false) 303 #define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false) 304 #define LONG_FIELD(className, name) FIELD(className, name, "J", false) 305 #define FLOAT_FIELD(className, name) FIELD(className, name, "F", false) 306 #define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false) 307 #define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true) 308 #define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true) 309 #define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true) 310 311 #define GET_JNI_METHOD(jniGetMethod, dst, clazz, methodName, signature) \ 312 if (JVMCILibDumpJNIConfig != NULL) { \ 313 fileStream* st = JVMCIGlobals::get_jni_config_file(); \ 314 st->print_cr("method %s %s %s", current_class_name, methodName, signature); \ 315 } else { \ 316 dst = env->jniGetMethod(clazz, methodName, signature); \ 317 JVMCI_EXCEPTION_CHECK(env, #jniGetMethod "(%s.%s%s)", current_class_name, methodName, signature); \ 318 assert(dst != NULL, "uninitialized"); \ 319 } 320 321 #define GET_JNI_CONSTRUCTOR(clazz, signature) \ 322 GET_JNI_METHOD(GetMethodID, JNIJVMCI::clazz::_constructor, clazz::_class, "<init>", signature) \ 323 324 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \ 325 GET_JNI_METHOD(jniGetMethod, \ 326 className::_##methodName##_method, \ 327 className::clazz(), \ 328 vmSymbols::methodName##_name()->as_C_string(), \ 329 vmSymbols::signatureSymbolName()->as_C_string()) 330 331 #define CONSTRUCTOR(className, signature) \ 332 GET_JNI_CONSTRUCTOR(className, signature) 333 334 extern "C" { 335 void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass); 336 jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c); 337 } 338 339 #define IN_CLASS(fullClassName) current_class_name = vmSymbols::fullClassName()->as_C_string() 340 /** 341 * Initializes the JNI method and field ids used in JNIJVMCI. 342 */ 343 void JNIJVMCI::initialize_ids(JNIEnv* env) { 344 ResourceMark rm; 345 const char* current_class_name = NULL; 346 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) 347 348 IN_CLASS(java_lang_Class); 349 GET_JNI_METHOD(GetMethodID, _Class_getName_method, Class::_class, "getName", "()Ljava/lang/String;"); 350 351 IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedPrimitiveType); 352 GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedPrimitiveType_fromMetaspace_method, HotSpotResolvedPrimitiveType::_class, 353 vmSymbols::fromMetaspace_name()->as_C_string(), 354 vmSymbols::primitive_fromMetaspace_signature()->as_C_string()); 355 IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl); 356 GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedObjectTypeImpl_fromMetaspace_method, HotSpotResolvedObjectTypeImpl::_class, 357 vmSymbols::fromMetaspace_name()->as_C_string(), 358 vmSymbols::klass_fromMetaspace_signature()->as_C_string()); 359 IN_CLASS(jdk_vm_ci_hotspot_HotSpotConstantPool); 360 GET_JNI_METHOD(GetStaticMethodID, _HotSpotConstantPool_fromMetaspace_method, HotSpotConstantPool::_class, 361 vmSymbols::fromMetaspace_name()->as_C_string(), 362 vmSymbols::constantPool_fromMetaspace_signature()->as_C_string()); 363 IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl); 364 GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedJavaMethodImpl_fromMetaspace_method, HotSpotResolvedJavaMethodImpl::_class, 365 vmSymbols::fromMetaspace_name()->as_C_string(), 366 vmSymbols::method_fromMetaspace_signature()->as_C_string()); 367 368 #define BOX_CLASSES(generate) \ 369 generate(Boolean, T_BOOLEAN, Z) \ 370 generate(Byte, T_BYTE, B) \ 371 generate(Character, T_CHAR, C) \ 372 generate(Short, T_SHORT, S) \ 373 generate(Integer, T_INT, I) \ 374 generate(Long, T_LONG, J) \ 375 generate(Float, T_FLOAT, F) \ 376 generate(Double, T_DOUBLE, D) \ 377 378 #define DO_BOX_CLASS(klass, basicType, type) \ 379 current_class_name = "java/lang/" #klass; \ 380 if (JVMCILibDumpJNIConfig == NULL) { \ 381 _box_classes[basicType] = env->FindClass("java/lang/" #klass); \ 382 JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", #klass); \ 383 _box_classes[basicType] = (jclass) env->NewGlobalRef(_box_classes[basicType]); \ 384 assert(_box_classes[basicType] != NULL, "uninitialized"); \ 385 _box_fields[basicType] = env->GetFieldID(_box_classes[basicType], "value", #type); \ 386 JVMCI_EXCEPTION_CHECK(env, "GetFieldID(%s, value, %s)", #klass, #type); \ 387 GET_JNI_METHOD(GetMethodID, _box_constructors[basicType], _box_classes[basicType], "<init>", "(" #type ")V"); \ 388 } else { \ 389 fileStream* st = JVMCIGlobals::get_jni_config_file(); \ 390 st->print_cr("field %s value %s", current_class_name, #type); \ 391 st->print_cr("method %s <init> (%s)V", current_class_name, #type); \ 392 } 393 394 BOX_CLASSES(DO_BOX_CLASS); 395 396 if (JVMCILibDumpJNIConfig == NULL) { 397 _byte_array = env->FindClass("[B"); 398 JVMCI_EXCEPTION_CHECK(env, "FindClass([B)"); 399 _byte_array = (jclass) env->NewGlobalRef(_byte_array); 400 assert(_byte_array != NULL, "uninitialized"); 401 } else { 402 fileStream* st = JVMCIGlobals::get_jni_config_file(); 403 st->print_cr("class [B"); 404 } 405 406 #define DUMP_ALL_NATIVE_METHODS(class_symbol) do { \ 407 current_class_name = class_symbol->as_C_string(); \ 408 Klass* k = SystemDictionary::resolve_or_fail(class_symbol, true, CHECK_EXIT); \ 409 InstanceKlass* iklass = InstanceKlass::cast(k); \ 410 Array<Method*>* methods = iklass->methods(); \ 411 for (int i = 0; i < methods->length(); i++) { \ 412 Method* m = methods->at(i); \ 413 if (m->is_native()) { \ 414 st->print_cr("method %s %s %s", current_class_name, m->name()->as_C_string(), m->signature()->as_C_string()); \ 415 } \ 416 } \ 417 } while(0) 418 419 if (JVMCILibDumpJNIConfig != NULL) { 420 Thread* THREAD = Thread::current(); 421 fileStream* st = JVMCIGlobals::get_jni_config_file(); 422 423 DUMP_ALL_NATIVE_METHODS(vmSymbols::jdk_vm_ci_hotspot_CompilerToVM()); 424 425 st->flush(); 426 tty->print_cr("Dumped JVMCI shared library JNI configuration to %s", JVMCILibDumpJNIConfig); 427 vm_exit(0); 428 } 429 430 #undef DUMP_ALL_NATIVE_METHODS 431 #undef DO_BOX_CLASS 432 #undef BOX_CLASSES 433 #undef IN_CLASS 434 435 #define CC (char*) /*cast a literal from (const char*)*/ 436 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f)) 437 438 if (env != JavaThread::current()->jni_environment()) { 439 jclass clazz = env->FindClass("jdk/vm/ci/hotspot/CompilerToVM"); 440 if (env->ExceptionCheck()) { 441 env->ExceptionDescribe(); 442 guarantee(false, "Could not find class jdk/vm/ci/hotspot/CompilerToVM"); 443 } 444 JNINativeMethod CompilerToVM_native_methods[] = { 445 { CC"registerNatives", CC"()V", FN_PTR(JVM_RegisterJVMCINatives) }, 446 }; 447 env->RegisterNatives(clazz, CompilerToVM_native_methods, 1); 448 if (env->ExceptionCheck()) { 449 env->ExceptionDescribe(); 450 guarantee(false, ""); 451 } 452 453 JNINativeMethod JVMCI_native_methods[] = { 454 { CC"initializeRuntime", CC"()Ljdk/vm/ci/runtime/JVMCIRuntime;", FN_PTR(JVM_GetJVMCIRuntime) }, 455 }; 456 env->RegisterNatives(JVMCI::clazz(), JVMCI_native_methods, 1); 457 if (env->ExceptionCheck()) { 458 env->ExceptionDescribe(); 459 guarantee(false, ""); 460 } 461 } 462 } 463 464 #undef METHOD 465 #undef CONSTRUCTOR 466 #undef FIELD2 467 468 #define EMPTY0 469 #define EMPTY1(x) 470 #define EMPTY2(x,y) 471 #define FIELD3(className, name, sig) FIELD2(className, name) 472 #define FIELD2(className, name) \ 473 jfieldID JNIJVMCI::className::_##name##_field_id = 0; \ 474 int HotSpotJVMCI::className::_##name##_offset = 0; 475 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) 476 #define CONSTRUCTOR(className, signature) 477 478 // Generates the definitions of static fields used by the accessors. For example: 479 // jfieldID JNIJVMCI::Architecture::_wordKind_field_id = 0; 480 // jfieldID HotSpotJVMCI::Architecture::_wordKind_offset = 0; 481 JVMCI_CLASSES_DO(EMPTY2, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2, METHOD, CONSTRUCTOR) 482 483 #undef START_CLASS 484 #undef END_CLASS 485 #undef METHOD 486 #undef CONSTRUCTOR 487 #undef FIELD 488 #undef CHAR_FIELD 489 #undef INT_FIELD 490 #undef BOOLEAN_FIELD 491 #undef LONG_FIELD 492 #undef FLOAT_FIELD 493 #undef OBJECT_FIELD 494 #undef PRIMARRAY_FIELD 495 #undef OBJECTARRAY_FIELD 496 #undef STATIC_FIELD 497 #undef STATIC_OBJECT_FIELD 498 #undef STATIC_OBJECTARRAY_FIELD 499 #undef STATIC_INT_FIELD 500 #undef STATIC_BOOLEAN_FIELD 501 #undef EMPTY_CAST 502 503 504 #define START_CLASS(className, fullClassName) \ 505 void JNIJVMCI::className::initialize(JVMCI_TRAPS) { \ 506 /* should already be initialized */ \ 507 } \ 508 bool JNIJVMCI::className::is_instance(JVMCIEnv* jvmciEnv, JVMCIObject object) { \ 509 JNIAccessMark jni(jvmciEnv); \ 510 return jni()->IsInstanceOf(object.as_jobject(), className::clazz()) != 0; \ 511 } \ 512 void JNIJVMCI::className::check(JVMCIEnv* jvmciEnv, JVMCIObject obj, const char* field_name, jfieldID offset) { \ 513 assert(obj.is_non_null(), "NULL field access of %s.%s", #className, field_name); \ 514 assert(jvmciEnv->isa_##className(obj), "wrong class, " #className " expected, found %s", jvmciEnv->klass_name(obj)); \ 515 assert(offset != 0, "must be valid offset"); \ 516 } \ 517 jclass JNIJVMCI::className::_class = NULL; 518 519 #define END_CLASS 520 521 #define FIELD(className, name, type, accessor, cast) \ 522 type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \ 523 className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \ 524 JNIAccessMark jni(jvmciEnv); \ 525 return cast jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id); \ 526 } \ 527 void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \ 528 className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \ 529 JNIAccessMark jni(jvmciEnv); \ 530 jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, x); \ 531 } \ 532 533 #define EMPTY_CAST 534 #define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST) 535 #define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST) 536 #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 537 #define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST) 538 #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST) 539 540 #define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST) 541 #define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 542 #define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray)) 543 544 #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject)) 545 #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 546 547 #define OOPISH_FIELD(className, name, type, accessor, cast) \ 548 type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \ 549 className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \ 550 JNIAccessMark jni(jvmciEnv); \ 551 return cast wrap(jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id)); \ 552 } \ 553 void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \ 554 className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \ 555 JNIAccessMark jni(jvmciEnv); \ 556 jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, resolve_handle(x)); \ 557 } 558 559 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \ 560 type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \ 561 JNIAccessMark jni(jvmciEnv); \ 562 return cast wrap(jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id)); \ 563 } \ 564 void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \ 565 JNIAccessMark jni(jvmciEnv); \ 566 jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, resolve_handle(x)); \ 567 } 568 569 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \ 570 type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \ 571 JNIAccessMark jni(jvmciEnv); \ 572 return cast jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id); \ 573 } \ 574 void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \ 575 JNIAccessMark jni(jvmciEnv); \ 576 jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, x); \ 577 } 578 579 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST) 580 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 581 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \ 582 jmethodID JNIJVMCI::className::_##methodName##_method; 583 584 #define CONSTRUCTOR(className, signature) \ 585 jmethodID JNIJVMCI::className::_constructor; 586 587 /** 588 * Generates the method definitions for the classes in HotSpotJVMCI. 589 */ 590 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) 591 592 #undef METHOD 593 #undef CONSTRUCTOR 594 #undef START_CLASS 595 #undef END_CLASS 596 #undef FIELD 597 #undef CHAR_FIELD 598 #undef INT_FIELD 599 #undef BOOLEAN_FIELD 600 #undef LONG_FIELD 601 #undef FLOAT_FIELD 602 #undef OBJECT_FIELD 603 #undef PRIMARRAY_FIELD 604 #undef OBJECTARRAY_FIELD 605 #undef STATIC_OOPISH_FIELD 606 #undef STATIC_OBJECT_FIELD 607 #undef STATIC_OBJECTARRAY_FIELD 608 #undef STATIC_INT_FIELD 609 #undef STATIC_BOOLEAN_FIELD 610 #undef STATIC_PRIMITIVE_FIELD 611 #undef OOPISH_FIELD 612 #undef EMPTY_CAST