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