1 /* 2 * Copyright (c) 1999, 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 25 #include "precompiled.hpp" 26 #include "classfile/stringTable.hpp" 27 #include "code/codeCache.hpp" 28 #include "memory/oopFactory.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "oops/typeArrayOop.inline.hpp" 31 #include "runtime/jniHandles.inline.hpp" 32 #include "runtime/javaCalls.hpp" 33 #include "jvmci/jniAccessMark.inline.hpp" 34 #include "jvmci/jvmciRuntime.hpp" 35 36 JVMCICompileState::JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter): 37 _task(task), 38 _system_dictionary_modification_counter(system_dictionary_modification_counter), 39 _retryable(true), 40 _failure_reason(NULL), 41 _failure_reason_on_C_heap(false) { 42 // Get Jvmti capabilities under lock to get consistent values. 43 MutexLocker mu(JvmtiThreadState_lock); 44 _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0; 45 _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0; 46 _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0; 47 _jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0; 48 } 49 50 bool JVMCICompileState::jvmti_state_changed() const { 51 if (!jvmti_can_access_local_variables() && 52 JvmtiExport::can_access_local_variables()) { 53 return true; 54 } 55 if (!jvmti_can_hotswap_or_post_breakpoint() && 56 JvmtiExport::can_hotswap_or_post_breakpoint()) { 57 return true; 58 } 59 if (!jvmti_can_post_on_exceptions() && 60 JvmtiExport::can_post_on_exceptions()) { 61 return true; 62 } 63 if (!jvmti_can_pop_frame() && 64 JvmtiExport::can_pop_frame()) { 65 return true; 66 } 67 return false; 68 } 69 70 JavaVM* JVMCIEnv::_shared_library_javavm = NULL; 71 void* JVMCIEnv::_shared_library_handle = NULL; 72 char* JVMCIEnv::_shared_library_path = NULL; 73 74 void JVMCIEnv::copy_saved_properties() { 75 assert(!is_hotspot(), "can only copy saved properties from HotSpot to native image"); 76 77 JavaThread* THREAD = JavaThread::current(); 78 79 Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_services_Services(), Handle(), Handle(), true, THREAD); 80 if (HAS_PENDING_EXCEPTION) { 81 JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services"); 82 } 83 InstanceKlass* ik = InstanceKlass::cast(k); 84 if (ik->should_be_initialized()) { 85 ik->initialize(THREAD); 86 if (HAS_PENDING_EXCEPTION) { 87 JVMCIRuntime::exit_on_pending_exception(NULL, "Error initializing jdk.vm.ci.services.Services"); 88 } 89 } 90 91 // Get the serialized saved properties from HotSpot 92 TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties", CHECK_EXIT); 93 JavaValue result(T_OBJECT); 94 JavaCallArguments args; 95 JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD); 96 if (HAS_PENDING_EXCEPTION) { 97 JVMCIRuntime::exit_on_pending_exception(NULL, "Error calling jdk.vm.ci.services.Services.serializeSavedProperties"); 98 } 99 oop res = (oop) result.get_jobject(); 100 assert(res->is_typeArray(), "must be"); 101 assert(TypeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "must be"); 102 typeArrayOop ba = typeArrayOop(res); 103 int serialized_properties_len = ba->length(); 104 105 // Copy serialized saved properties from HotSpot object into native buffer 106 jbyte* serialized_properties = NEW_RESOURCE_ARRAY(jbyte, serialized_properties_len); 107 memcpy(serialized_properties, ba->byte_at_addr(0), serialized_properties_len); 108 109 // Copy native buffer into shared library object 110 JVMCIPrimitiveArray buf = new_byteArray(serialized_properties_len, this); 111 if (has_pending_exception()) { 112 describe_pending_exception(true); 113 fatal("Error in copy_saved_properties"); 114 } 115 copy_bytes_from(serialized_properties, buf, 0, serialized_properties_len); 116 if (has_pending_exception()) { 117 describe_pending_exception(true); 118 fatal("Error in copy_saved_properties"); 119 } 120 121 // Initialize saved properties in shared library 122 jclass servicesClass = JNIJVMCI::Services::clazz(); 123 jmethodID initializeSavedProperties = JNIJVMCI::Services::initializeSavedProperties_method(); 124 JNIAccessMark jni(this); 125 jni()->CallStaticVoidMethod(servicesClass, initializeSavedProperties, buf.as_jobject()); 126 if (jni()->ExceptionCheck()) { 127 jni()->ExceptionDescribe(); 128 fatal("Error calling jdk.vm.ci.services.Services.initializeSavedProperties"); 129 } 130 } 131 132 JNIEnv* JVMCIEnv::attach_shared_library() { 133 if (_shared_library_javavm == NULL) { 134 MutexLocker locker(JVMCI_lock); 135 if (_shared_library_javavm == NULL) { 136 137 char path[JVM_MAXPATHLEN]; 138 char ebuf[1024]; 139 if (JVMCILibPath != NULL) { 140 if (!os::dll_locate_lib(path, sizeof(path), JVMCILibPath, JVMCI_SHARED_LIBRARY_NAME)) { 141 vm_exit_during_initialization("Unable to create JVMCI shared library path from -XX:JVMCILibPath value", JVMCILibPath); 142 } 143 } else { 144 if (!os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), JVMCI_SHARED_LIBRARY_NAME)) { 145 vm_exit_during_initialization("Unable to create path to JVMCI shared library"); 146 } 147 } 148 149 void* handle = os::dll_load(path, ebuf, sizeof ebuf); 150 if (handle == NULL) { 151 vm_exit_during_initialization("Unable to load JVMCI shared library", ebuf); 152 } 153 _shared_library_handle = handle; 154 _shared_library_path = strdup(path); 155 jint (*JNI_CreateJavaVM)(JavaVM **pvm, void **penv, void *args); 156 typedef jint (*JNI_CreateJavaVM_t)(JavaVM **pvm, void **penv, void *args); 157 158 JNI_CreateJavaVM = CAST_TO_FN_PTR(JNI_CreateJavaVM_t, os::dll_lookup(handle, "JNI_CreateJavaVM")); 159 JNIEnv* env; 160 if (JNI_CreateJavaVM == NULL) { 161 vm_exit_during_initialization("Unable to find JNI_CreateJavaVM", path); 162 } 163 164 ResourceMark rm; 165 JavaVMInitArgs vm_args; 166 vm_args.version = JNI_VERSION_1_2; 167 vm_args.ignoreUnrecognized = JNI_TRUE; 168 vm_args.options = NULL; 169 vm_args.nOptions = 0; 170 171 JavaVM* the_javavm = NULL; 172 int result = (*JNI_CreateJavaVM)(&the_javavm, (void**) &env, &vm_args); 173 if (result == JNI_OK) { 174 guarantee(env != NULL, "missing env"); 175 _shared_library_javavm = the_javavm; 176 return env; 177 } else { 178 vm_exit_during_initialization(err_msg("JNI_CreateJavaVM failed with return value %d", result), path); 179 } 180 } 181 } 182 JNIEnv* env; 183 if (_shared_library_javavm->AttachCurrentThread((void**)&env, NULL) == JNI_OK) { 184 guarantee(env != NULL, "missing env"); 185 return env; 186 } 187 fatal("Error attaching current thread to JVMCI shared library JNI interface"); 188 return NULL; 189 } 190 191 void JVMCIEnv::init_env_mode_runtime(JNIEnv* parent_env) { 192 // By default there is only one runtime which is the compiler runtime. 193 _runtime = JVMCI::compiler_runtime(); 194 if (!UseJVMCINativeLibrary) { 195 // In HotSpot mode, JNI isn't used at all. 196 _is_hotspot = true; 197 _env = NULL; 198 return; 199 } 200 201 if (parent_env != NULL) { 202 // If the parent JNI environment is non-null then figure out whether it 203 // is a HotSpot or shared library JNIEnv and set the state appropriately. 204 JavaThread* thread = JavaThread::current(); 205 if (thread->jni_environment() == parent_env) { 206 // Select the Java runtime 207 _runtime = JVMCI::java_runtime(); 208 _is_hotspot = true; 209 _env = NULL; 210 return; 211 } 212 } 213 214 // Running in JVMCI shared library mode so get a shared library JNIEnv 215 _is_hotspot = false; 216 _env = attach_shared_library(); 217 assert(parent_env == NULL || _env == parent_env, "must be"); 218 219 if (parent_env == NULL) { 220 // There is no parent shared library JNI env so push 221 // a JNI local frame to release all local handles in 222 // this JVMCIEnv scope when it's closed. 223 assert(_throw_to_caller == false, "must be"); 224 JNIAccessMark jni(this); 225 jint result = _env->PushLocalFrame(32); 226 if (result != JNI_OK) { 227 char message[256]; 228 jio_snprintf(message, 256, "Uncaught exception pushing local frame for JVMCIEnv scope entered at %s:%d", _file, _line); 229 JVMCIRuntime::exit_on_pending_exception(this, message); 230 } 231 } 232 } 233 234 JVMCIEnv::JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line): 235 _throw_to_caller(false), _file(file), _line(line), _compile_state(compile_state) { 236 init_env_mode_runtime(NULL); 237 } 238 239 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line): 240 _throw_to_caller(false), _file(file), _line(line), _compile_state(NULL) { 241 init_env_mode_runtime(NULL); 242 } 243 244 JVMCIEnv::JVMCIEnv(JNIEnv* parent_env, const char* file, int line): 245 _throw_to_caller(true), _file(file), _line(line), _compile_state(NULL) { 246 init_env_mode_runtime(parent_env); 247 assert(_env == NULL || parent_env == _env, "mismatched JNIEnvironment"); 248 } 249 250 void JVMCIEnv::init(bool is_hotspot, const char* file, int line) { 251 _compile_state = NULL; 252 _throw_to_caller = false; 253 _file = file; 254 _line = line; 255 if (is_hotspot) { 256 _env = NULL; 257 _is_hotspot = true; 258 _runtime = JVMCI::java_runtime(); 259 } else { 260 init_env_mode_runtime(NULL); 261 } 262 } 263 264 // Prints a pending exception (if any) and its stack trace. 265 void JVMCIEnv::describe_pending_exception(bool clear) { 266 if (!is_hotspot()) { 267 JNIAccessMark jni(this); 268 if (jni()->ExceptionCheck()) { 269 jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL; 270 jni()->ExceptionDescribe(); 271 if (ex != NULL) { 272 jni()->Throw(ex); 273 } 274 } 275 } else { 276 Thread* THREAD = Thread::current(); 277 if (HAS_PENDING_EXCEPTION) { 278 JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear); 279 } 280 } 281 } 282 283 void JVMCIEnv::translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable) { 284 assert(!is_hotspot(), "must_be"); 285 // Resolve HotSpotJVMCIRuntime class explicitly as HotSpotJVMCI::compute_offsets 286 // may not have been called. 287 Klass* runtimeKlass = SystemDictionary::resolve_or_fail(vmSymbols::jdk_vm_ci_hotspot_HotSpotJVMCIRuntime(), true, CHECK); 288 JavaCallArguments jargs; 289 jargs.push_oop(throwable); 290 JavaValue result(T_OBJECT); 291 JavaCalls::call_static(&result, 292 runtimeKlass, 293 vmSymbols::encodeThrowable_name(), 294 vmSymbols::encodeThrowable_signature(), &jargs, THREAD); 295 if (HAS_PENDING_EXCEPTION) { 296 JVMCIRuntime::exit_on_pending_exception(this, "HotSpotJVMCIRuntime.encodeThrowable should not throw an exception"); 297 } 298 299 oop encoded_throwable_string = (oop) result.get_jobject(); 300 301 ResourceMark rm; 302 const char* encoded_throwable_chars = java_lang_String::as_utf8_string(encoded_throwable_string); 303 304 JNIAccessMark jni(this); 305 jobject jni_encoded_throwable_string = jni()->NewStringUTF(encoded_throwable_chars); 306 jthrowable jni_throwable = (jthrowable) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 307 JNIJVMCI::HotSpotJVMCIRuntime::decodeThrowable_method(), 308 jni_encoded_throwable_string); 309 jni()->Throw(jni_throwable); 310 } 311 312 JVMCIEnv::~JVMCIEnv() { 313 if (_throw_to_caller) { 314 if (is_hotspot()) { 315 // Nothing to do 316 } else { 317 if (Thread::current()->is_Java_thread()) { 318 JavaThread* THREAD = JavaThread::current(); 319 if (HAS_PENDING_EXCEPTION) { 320 Handle throwable = Handle(THREAD, PENDING_EXCEPTION); 321 CLEAR_PENDING_EXCEPTION; 322 translate_hotspot_exception_to_jni_exception(THREAD, throwable); 323 } 324 } 325 } 326 } else { 327 if (!is_hotspot()) { 328 // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope. 329 JNIAccessMark jni(this); 330 jni()->PopLocalFrame(NULL); 331 } 332 333 if (has_pending_exception()) { 334 char message[256]; 335 jio_snprintf(message, 256, "Uncaught exception exiting JVMCIEnv scope entered at %s:%d", _file, _line); 336 JVMCIRuntime::exit_on_pending_exception(this, message); 337 } 338 } 339 } 340 341 jboolean JVMCIEnv::has_pending_exception() { 342 if (is_hotspot()) { 343 Thread* THREAD = Thread::current(); 344 return HAS_PENDING_EXCEPTION; 345 } else { 346 JNIAccessMark jni(this); 347 return jni()->ExceptionCheck(); 348 } 349 } 350 351 void JVMCIEnv::clear_pending_exception() { 352 if (is_hotspot()) { 353 Thread* THREAD = Thread::current(); 354 CLEAR_PENDING_EXCEPTION; 355 } else { 356 JNIAccessMark jni(this); 357 jni()->ExceptionClear(); 358 } 359 } 360 361 int JVMCIEnv::get_length(JVMCIArray array) { 362 if (is_hotspot()) { 363 return HotSpotJVMCI::resolve(array)->length(); 364 } else { 365 JNIAccessMark jni(this); 366 return jni()->GetArrayLength(get_jarray(array)); 367 } 368 } 369 370 JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) { 371 if (is_hotspot()) { 372 oop result = HotSpotJVMCI::resolve(array)->obj_at(index); 373 return wrap(result); 374 } else { 375 JNIAccessMark jni(this); 376 jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index); 377 return wrap(result); 378 } 379 } 380 381 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) { 382 if (is_hotspot()) { 383 HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value)); 384 } else { 385 JNIAccessMark jni(this); 386 jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value)); 387 } 388 } 389 390 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) { 391 if (is_hotspot()) { 392 return HotSpotJVMCI::resolve(array)->bool_at(index); 393 } else { 394 JNIAccessMark jni(this); 395 jboolean result; 396 jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result); 397 return result; 398 } 399 } 400 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) { 401 if (is_hotspot()) { 402 HotSpotJVMCI::resolve(array)->bool_at_put(index, value); 403 } else { 404 JNIAccessMark jni(this); 405 jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value); 406 } 407 } 408 409 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) { 410 if (is_hotspot()) { 411 return HotSpotJVMCI::resolve(array)->byte_at(index); 412 } else { 413 JNIAccessMark jni(this); 414 jbyte result; 415 jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result); 416 return result; 417 } 418 } 419 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) { 420 if (is_hotspot()) { 421 HotSpotJVMCI::resolve(array)->byte_at_put(index, value); 422 } else { 423 JNIAccessMark jni(this); 424 jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value); 425 } 426 } 427 428 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) { 429 if (is_hotspot()) { 430 return HotSpotJVMCI::resolve(array)->int_at(index); 431 } else { 432 JNIAccessMark jni(this); 433 jint result; 434 jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result); 435 return result; 436 } 437 } 438 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) { 439 if (is_hotspot()) { 440 HotSpotJVMCI::resolve(array)->int_at_put(index, value); 441 } else { 442 JNIAccessMark jni(this); 443 jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value); 444 } 445 } 446 447 long JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { 448 if (is_hotspot()) { 449 return HotSpotJVMCI::resolve(array)->long_at(index); 450 } else { 451 JNIAccessMark jni(this); 452 jlong result; 453 jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result); 454 return result; 455 } 456 } 457 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) { 458 if (is_hotspot()) { 459 HotSpotJVMCI::resolve(array)->long_at_put(index, value); 460 } else { 461 JNIAccessMark jni(this); 462 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value); 463 } 464 } 465 466 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes) { 467 if (size_in_bytes == 0) { 468 return; 469 } 470 if (is_hotspot()) { 471 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), size_in_bytes); 472 } else { 473 JNIAccessMark jni(this); 474 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, size_in_bytes, dest); 475 } 476 } 477 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes) { 478 if (size_in_bytes == 0) { 479 return; 480 } 481 if (is_hotspot()) { 482 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, size_in_bytes); 483 } else { 484 JNIAccessMark jni(this); 485 jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, size_in_bytes, src); 486 } 487 } 488 489 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) { 490 if (is_hotspot()) { 491 return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type); 492 } else { 493 JNIAccessMark jni(this); 494 return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type)); 495 } 496 } 497 498 // Get the primitive value from a Java boxing object. It's hard error to 499 // pass a non-primitive BasicType. 500 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) { 501 jvalue result; 502 if (is_hotspot()) { 503 if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) { 504 ShouldNotReachHere(); 505 } 506 } else { 507 JNIAccessMark jni(this); 508 jfieldID field = JNIJVMCI::box_field(type); 509 switch (type) { 510 case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break; 511 case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break; 512 case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break; 513 case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break; 514 case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break; 515 case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break; 516 case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break; 517 case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break; 518 default: 519 ShouldNotReachHere(); 520 } 521 } 522 return result; 523 } 524 525 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL. 526 BasicType JVMCIEnv::get_box_type(JVMCIObject object) { 527 if (is_hotspot()) { 528 return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object)); 529 } else { 530 JNIAccessMark jni(this); 531 jclass clazz = jni()->GetObjectClass(get_jobject(object)); 532 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN; 533 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE; 534 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT; 535 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR; 536 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT; 537 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG; 538 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT; 539 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE; 540 return T_ILLEGAL; 541 } 542 } 543 544 // Create a boxing object of the appropriate primitive type. 545 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) { 546 switch (type) { 547 case T_BOOLEAN: 548 case T_BYTE: 549 case T_CHAR: 550 case T_SHORT: 551 case T_INT: 552 case T_LONG: 553 case T_FLOAT: 554 case T_DOUBLE: 555 break; 556 default: 557 JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject()); 558 } 559 if (is_hotspot()) { 560 JavaThread* THREAD = JavaThread::current(); 561 oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject())); 562 return HotSpotJVMCI::wrap(box); 563 } else { 564 JNIAccessMark jni(this); 565 jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value); 566 assert(box != NULL, ""); 567 return wrap(box); 568 } 569 } 570 571 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) { 572 if (is_hotspot()) { 573 return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str)); 574 } else { 575 JNIAccessMark jni(this); 576 int length = jni()->GetStringLength(str.as_jstring()); 577 char* result = NEW_RESOURCE_ARRAY(char, length + 1); 578 jni()->GetStringUTFRegion(str.as_jstring(), 0, length, result); 579 return result; 580 } 581 } 582 583 char* JVMCIEnv::as_utf8_string(JVMCIObject str, char* buf, int buflen) { 584 if (is_hotspot()) { 585 return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str), buf, buflen); 586 } else { 587 JNIAccessMark jni(this); 588 int length = jni()->GetStringLength(str.as_jstring()); 589 if (length >= buflen) { 590 length = buflen; 591 } 592 jni()->GetStringUTFRegion(str.as_jstring(), 0, length, buf); 593 return buf; 594 } 595 } 596 597 #define DO_THROW(name) \ 598 void JVMCIEnv::throw_##name(const char* msg) { \ 599 if (is_hotspot()) { \ 600 JavaThread* THREAD = JavaThread::current(); \ 601 THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \ 602 } else { \ 603 JNIAccessMark jni(this); \ 604 jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \ 605 } \ 606 } 607 608 DO_THROW(InternalError) 609 DO_THROW(ArrayIndexOutOfBoundsException) 610 DO_THROW(IllegalStateException) 611 DO_THROW(NullPointerException) 612 DO_THROW(IllegalArgumentException) 613 DO_THROW(InvalidInstalledCodeException) 614 DO_THROW(UnsatisfiedLinkError) 615 616 #undef DO_THROW 617 618 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) { 619 const int max_msg_size = 1024; 620 va_list ap; 621 va_start(ap, format); 622 char msg[max_msg_size]; 623 vsnprintf(msg, max_msg_size, format, ap); 624 msg[max_msg_size-1] = '\0'; 625 va_end(ap); 626 if (is_hotspot()) { 627 JavaThread* THREAD = JavaThread::current(); 628 Handle h_loader = Handle(); 629 Handle h_protection_domain = Handle(); 630 Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain); 631 } else { 632 JNIAccessMark jni(this); 633 jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg); 634 } 635 } 636 637 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci, 638 jlong compile_state, int id) { 639 if (is_hotspot()) { 640 Thread* THREAD = Thread::current(); 641 JavaCallArguments jargs; 642 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 643 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method))); 644 jargs.push_int(entry_bci); 645 jargs.push_long(compile_state); 646 jargs.push_int(id); 647 JavaValue result(T_OBJECT); 648 JavaCalls::call_special(&result, 649 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 650 vmSymbols::compileMethod_name(), 651 vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject())); 652 return wrap((oop) result.get_jobject()); 653 } else { 654 JNIAccessMark jni(this); 655 jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(), 656 JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 657 JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(), 658 method.as_jobject(), entry_bci, compile_state, id); 659 if (jni()->ExceptionCheck()) { 660 return JVMCIObject(); 661 } 662 return wrap(result); 663 } 664 } 665 666 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) { 667 if (is_hotspot()) { 668 Thread* THREAD = Thread::current(); 669 JavaCallArguments jargs; 670 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 671 JavaValue result(T_VOID); 672 JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK); 673 } else { 674 JNIAccessMark jni(this); 675 jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method()); 676 677 } 678 } 679 680 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) { 681 HandleMark hm; 682 JavaThread* THREAD = JavaThread::current(); 683 if (is_hotspot()) { 684 JavaCallArguments jargs; 685 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 686 JavaValue result(T_VOID); 687 JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD); 688 } else { 689 JNIAccessMark jni(this); 690 jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method()); 691 } 692 if (has_pending_exception()) { 693 // This should never happen as HotSpotJVMCIRuntime.shutdown() should 694 // handle all exceptions. 695 describe_pending_exception(true); 696 } 697 } 698 699 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) { 700 JavaThread* THREAD = JavaThread::current(); 701 if (is_hotspot()) { 702 JavaCallArguments jargs; 703 JavaValue result(T_OBJECT); 704 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject())); 705 return wrap((oop) result.get_jobject()); 706 } else { 707 JNIAccessMark jni(this); 708 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method()); 709 if (jni()->ExceptionCheck()) { 710 return JVMCIObject(); 711 } 712 return wrap(result); 713 } 714 } 715 716 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) { 717 JavaThread* THREAD = JavaThread::current(); 718 if (is_hotspot()) { 719 JavaCallArguments jargs; 720 JavaValue result(T_OBJECT); 721 JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject())); 722 return wrap((oop) result.get_jobject()); 723 } else { 724 JNIAccessMark jni(this); 725 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method()); 726 if (jni()->ExceptionCheck()) { 727 return JVMCIObject(); 728 } 729 return wrap(result); 730 } 731 } 732 733 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) { 734 JavaThread* THREAD = JavaThread::current(); 735 if (is_hotspot()) { 736 JavaCallArguments jargs; 737 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 738 JavaValue result(T_OBJECT); 739 JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject())); 740 return wrap((oop) result.get_jobject()); 741 } else { 742 JNIAccessMark jni(this); 743 jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method()); 744 if (jni()->ExceptionCheck()) { 745 return JVMCIObject(); 746 } 747 return wrap(result); 748 } 749 } 750 751 752 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) { 753 JavaThread* THREAD = JavaThread::current(); 754 if (is_hotspot()) { 755 JavaCallArguments jargs; 756 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object))); 757 JavaValue result(T_OBJECT); 758 JavaCalls::call_static(&result, 759 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 760 vmSymbols::callToString_name(), 761 vmSymbols::callToString_signature(), &jargs, CHECK_(JVMCIObject())); 762 return wrap((oop) result.get_jobject()); 763 } else { 764 JNIAccessMark jni(this); 765 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 766 JNIJVMCI::HotSpotJVMCIRuntime::callToString_method(), 767 object.as_jobject()); 768 if (jni()->ExceptionCheck()) { 769 return JVMCIObject(); 770 } 771 return wrap(result); 772 } 773 } 774 775 776 JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) { 777 JavaThread* THREAD = JavaThread::current(); 778 if (is_hotspot()) { 779 JavaCallArguments jargs; 780 jargs.push_int(kind); 781 jargs.push_long(value); 782 JavaValue result(T_OBJECT); 783 JavaCalls::call_static(&result, 784 HotSpotJVMCI::PrimitiveConstant::klass(), 785 vmSymbols::forTypeChar_name(), 786 vmSymbols::forTypeChar_signature(), &jargs, CHECK_(JVMCIObject())); 787 return wrap((oop) result.get_jobject()); 788 } else { 789 JNIAccessMark jni(this); 790 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::PrimitiveConstant::clazz(), 791 JNIJVMCI::PrimitiveConstant::forTypeChar_method(), 792 kind, value); 793 if (jni()->ExceptionCheck()) { 794 return JVMCIObject(); 795 } 796 return wrap(result); 797 } 798 } 799 800 JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) { 801 JavaThread* THREAD = JavaThread::current(); 802 if (is_hotspot()) { 803 JavaCallArguments jargs; 804 jargs.push_float(value); 805 JavaValue result(T_OBJECT); 806 JavaCalls::call_static(&result, 807 HotSpotJVMCI::JavaConstant::klass(), 808 vmSymbols::forFloat_name(), 809 vmSymbols::forFloat_signature(), &jargs, CHECK_(JVMCIObject())); 810 return wrap((oop) result.get_jobject()); 811 } else { 812 JNIAccessMark jni(this); 813 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(), 814 JNIJVMCI::JavaConstant::forFloat_method(), 815 value); 816 if (jni()->ExceptionCheck()) { 817 return JVMCIObject(); 818 } 819 return wrap(result); 820 } 821 } 822 823 JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) { 824 JavaThread* THREAD = JavaThread::current(); 825 if (is_hotspot()) { 826 JavaCallArguments jargs; 827 jargs.push_double(value); 828 JavaValue result(T_OBJECT); 829 JavaCalls::call_static(&result, 830 HotSpotJVMCI::JavaConstant::klass(), 831 vmSymbols::forDouble_name(), 832 vmSymbols::forDouble_signature(), &jargs, CHECK_(JVMCIObject())); 833 return wrap((oop) result.get_jobject()); 834 } else { 835 JNIAccessMark jni(this); 836 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(), 837 JNIJVMCI::JavaConstant::forDouble_method(), 838 value); 839 if (jni()->ExceptionCheck()) { 840 return JVMCIObject(); 841 } 842 return wrap(result); 843 } 844 } 845 846 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) { 847 JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives(); 848 JVMCIObject result = get_object_at(primitives, type); 849 return result; 850 } 851 852 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) { 853 JavaThread* THREAD = JavaThread::current(); 854 Symbol* method_name_sym; 855 Symbol* file_name_sym; 856 int line_number; 857 Handle mirror (THREAD, method->method_holder()->java_mirror()); 858 java_lang_StackTraceElement::decode(mirror, method, bci, method_name_sym, file_name_sym, line_number); 859 860 InstanceKlass* holder = method->method_holder(); 861 const char* declaring_class_str = holder->external_name(); 862 863 if (is_hotspot()) { 864 HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject())); 865 oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject())); 866 Handle obj = Handle(THREAD, objOop); 867 868 oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject())); 869 HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class); 870 871 oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject())); 872 HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name); 873 874 if (file_name_sym != NULL) { 875 oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject())); 876 HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name); 877 } 878 HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number); 879 return wrap(obj()); 880 } else { 881 JNIAccessMark jni(this); 882 jobject declaring_class = jni()->NewStringUTF(declaring_class_str); 883 if (jni()->ExceptionCheck()) { 884 return JVMCIObject(); 885 } 886 jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string()); 887 if (jni()->ExceptionCheck()) { 888 return JVMCIObject(); 889 } 890 jobject file_name = NULL; 891 if (file_name != NULL) { 892 file_name = jni()->NewStringUTF(file_name_sym->as_C_string()); 893 if (jni()->ExceptionCheck()) { 894 return JVMCIObject(); 895 } 896 } 897 898 jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(), 899 JNIJVMCI::StackTraceElement::constructor(), 900 declaring_class, method_name, file_name, line_number); 901 return wrap(result); 902 } 903 } 904 905 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) { 906 JavaThread* THREAD = JavaThread::current(); 907 908 JVMCIObject methodObject = get_jvmci_method(method(), JVMCI_CHECK_(JVMCIObject())); 909 910 if (is_hotspot()) { 911 InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass()); 912 if (ik->should_be_initialized()) { 913 ik->initialize(CHECK_(JVMCIObject())); 914 } 915 oop obj = ik->allocate_instance(CHECK_(JVMCIObject())); 916 Handle obj_h(THREAD, obj); 917 Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject())); 918 919 // Call constructor 920 JavaCallArguments jargs; 921 jargs.push_oop(obj_h); 922 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject))); 923 jargs.push_oop(nameStr); 924 jargs.push_int(isDefault); 925 jargs.push_long(compileId); 926 JavaValue result(T_VOID); 927 JavaCalls::call_special(&result, ik, 928 vmSymbols::object_initializer_name(), 929 vmSymbols::method_string_bool_long_signature(), 930 &jargs, CHECK_(JVMCIObject())); 931 return wrap(obj_h()); 932 } else { 933 JNIAccessMark jni(this); 934 jobject nameStr = name == NULL ? NULL : jni()->NewStringUTF(name); 935 if (jni()->ExceptionCheck()) { 936 return JVMCIObject(); 937 } 938 939 jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(), 940 JNIJVMCI::HotSpotNmethod::constructor(), 941 methodObject.as_jobject(), nameStr, isDefault); 942 return wrap(result); 943 } 944 } 945 946 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) { 947 if (object.is_null()) { 948 return JVMCIObject(); 949 } 950 if (is_hotspot()) { 951 return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object))); 952 } else { 953 JNIAccessMark jni(this); 954 return wrap(jni()->NewLocalRef(object.as_jobject())); 955 } 956 } 957 958 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) { 959 if (object.is_null()) { 960 return JVMCIObject(); 961 } 962 if (is_hotspot()) { 963 return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object)))); 964 } else { 965 JNIAccessMark jni(this); 966 return wrap(jni()->NewGlobalRef(object.as_jobject())); 967 } 968 } 969 970 JVMCIObject JVMCIEnv::make_weak(JVMCIObject object) { 971 if (object.is_null()) { 972 return JVMCIObject(); 973 } 974 if (is_hotspot()) { 975 return wrap(JNIHandles::make_weak_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object)))); 976 } else { 977 JNIAccessMark jni(this); 978 return wrap(jni()->NewWeakGlobalRef(object.as_jobject())); 979 } 980 } 981 982 void JVMCIEnv::destroy_local(JVMCIObject object) { 983 if (is_hotspot()) { 984 JNIHandles::destroy_local(object.as_jobject()); 985 } else { 986 JNIAccessMark jni(this); 987 jni()->DeleteLocalRef(object.as_jobject()); 988 } 989 } 990 991 void JVMCIEnv::destroy_global(JVMCIObject object) { 992 if (is_hotspot()) { 993 JNIHandles::destroy_global(object.as_jobject()); 994 } else { 995 JNIAccessMark jni(this); 996 jni()->DeleteGlobalRef(object.as_jobject()); 997 } 998 } 999 1000 void JVMCIEnv::destroy_weak(JVMCIObject object) { 1001 if (is_hotspot()) { 1002 JNIHandles::destroy_weak_global(object.as_jweak()); 1003 } else { 1004 JNIAccessMark jni(this); 1005 jni()->DeleteWeakGlobalRef(object.as_jweak()); 1006 } 1007 } 1008 1009 const char* JVMCIEnv::klass_name(JVMCIObject object) { 1010 if (is_hotspot()) { 1011 return HotSpotJVMCI::resolve(object)->klass()->signature_name(); 1012 } else { 1013 JVMCIObject name; 1014 { 1015 JNIAccessMark jni(this); 1016 jclass jcl = jni()->GetObjectClass(object.as_jobject()); 1017 jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method()); 1018 name = JVMCIObject::create(result, is_hotspot()); 1019 } 1020 return as_utf8_string(name); 1021 } 1022 } 1023 1024 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) { 1025 JVMCIObject method_object; 1026 if (method() == NULL) { 1027 return method_object; 1028 } 1029 1030 Thread* THREAD = Thread::current(); 1031 jmetadata handle = JVMCI::allocate_handle(method); 1032 jboolean exception = false; 1033 if (is_hotspot()) { 1034 JavaValue result(T_OBJECT); 1035 JavaCallArguments args; 1036 args.push_long((jlong) handle); 1037 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(), 1038 vmSymbols::fromMetaspace_name(), 1039 vmSymbols::method_fromMetaspace_signature(), &args, THREAD); 1040 if (HAS_PENDING_EXCEPTION) { 1041 exception = true; 1042 } else { 1043 method_object = wrap((oop)result.get_jobject()); 1044 } 1045 } else { 1046 JNIAccessMark jni(this); 1047 method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(), 1048 JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(), 1049 (jlong) handle)); 1050 exception = jni()->ExceptionCheck(); 1051 } 1052 1053 if (exception) { 1054 JVMCI::release_handle(handle); 1055 return JVMCIObject(); 1056 } 1057 1058 assert(asMethod(method_object) == method(), "must be"); 1059 if (get_HotSpotResolvedJavaMethodImpl_metadataHandle(method_object) != (jlong) handle) { 1060 JVMCI::release_handle(handle); 1061 } 1062 assert(!method_object.is_null(), "must be"); 1063 return method_object; 1064 } 1065 1066 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) { 1067 JVMCIObject type; 1068 if (klass.is_null()) { 1069 return type; 1070 } 1071 #ifdef INCLUDE_ALL_GCS 1072 if (UseG1GC) { 1073 // The klass might have come from a weak location so enqueue 1074 // the Class to make sure it's noticed by G1 1075 G1SATBCardTableModRefBS::enqueue(klass()->java_mirror()); 1076 } 1077 #endif // Klass* don't require tracking as Metadata* 1078 1079 jlong pointer = (jlong) klass(); 1080 JavaThread* THREAD = JavaThread::current(); 1081 JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject())); 1082 jboolean exception = false; 1083 if (is_hotspot()) { 1084 JavaValue result(T_OBJECT); 1085 JavaCallArguments args; 1086 args.push_long(pointer); 1087 args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(signature))); 1088 JavaCalls::call_static(&result, 1089 HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(), 1090 vmSymbols::fromMetaspace_name(), 1091 vmSymbols::klass_fromMetaspace_signature(), &args, THREAD); 1092 1093 if (HAS_PENDING_EXCEPTION) { 1094 exception = true; 1095 } else { 1096 type = wrap((oop)result.get_jobject()); 1097 } 1098 } else { 1099 JNIAccessMark jni(this); 1100 1101 HandleMark hm(THREAD); 1102 type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(), 1103 JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(), 1104 pointer, signature.as_jstring())); 1105 exception = jni()->ExceptionCheck(); 1106 } 1107 if (exception) { 1108 return JVMCIObject(); 1109 } 1110 1111 assert(type.is_non_null(), "must have result"); 1112 return type; 1113 } 1114 1115 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) { 1116 JVMCIObject cp_object; 1117 jmetadata handle = JVMCI::allocate_handle(cp); 1118 jboolean exception = false; 1119 if (is_hotspot()) { 1120 JavaThread* THREAD = JavaThread::current(); 1121 JavaValue result(T_OBJECT); 1122 JavaCallArguments args; 1123 args.push_long((jlong) handle); 1124 JavaCalls::call_static(&result, 1125 HotSpotJVMCI::HotSpotConstantPool::klass(), 1126 vmSymbols::fromMetaspace_name(), 1127 vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD); 1128 if (HAS_PENDING_EXCEPTION) { 1129 exception = true; 1130 } else { 1131 cp_object = wrap((oop)result.get_jobject()); 1132 } 1133 } else { 1134 JNIAccessMark jni(this); 1135 cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(), 1136 JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(), 1137 (jlong) handle)); 1138 exception = jni()->ExceptionCheck(); 1139 } 1140 1141 if (exception) { 1142 JVMCI::release_handle(handle); 1143 return JVMCIObject(); 1144 } 1145 1146 assert(!cp_object.is_null(), "must be"); 1147 // Constant pools aren't cached so this is always a newly created object using the handle 1148 assert(get_HotSpotConstantPool_metadataHandle(cp_object) == (jlong) handle, "must use same handle"); 1149 return cp_object; 1150 } 1151 1152 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) { 1153 if (is_hotspot()) { 1154 JavaThread* THREAD = JavaThread::current(); 1155 typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject())); 1156 return wrap(result); 1157 } else { 1158 JNIAccessMark jni(this); 1159 jbooleanArray result = jni()->NewBooleanArray(length); 1160 return wrap(result); 1161 } 1162 } 1163 1164 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) { 1165 if (is_hotspot()) { 1166 JavaThread* THREAD = JavaThread::current(); 1167 typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject())); 1168 return wrap(result); 1169 } else { 1170 JNIAccessMark jni(this); 1171 jbyteArray result = jni()->NewByteArray(length); 1172 return wrap(result); 1173 } 1174 } 1175 1176 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) { 1177 if (is_hotspot()) { 1178 JavaThread* THREAD = JavaThread::current(); 1179 Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlassObj ())->array_klass(CHECK_(JVMCIObject())); 1180 objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject())); 1181 return wrap(result); 1182 } else { 1183 JNIAccessMark jni(this); 1184 jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), NULL); 1185 return wrap(result); 1186 } 1187 } 1188 1189 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) { 1190 if (is_hotspot()) { 1191 JavaThread* THREAD = JavaThread::current(); 1192 typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject())); 1193 return wrap(result); 1194 } else { 1195 JNIAccessMark jni(this); 1196 jintArray result = jni()->NewIntArray(length); 1197 return wrap(result); 1198 } 1199 } 1200 1201 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) { 1202 if (is_hotspot()) { 1203 JavaThread* THREAD = JavaThread::current(); 1204 typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject())); 1205 return wrap(result); 1206 } else { 1207 JNIAccessMark jni(this); 1208 jlongArray result = jni()->NewLongArray(length); 1209 return wrap(result); 1210 } 1211 } 1212 1213 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) { 1214 if (is_hotspot()) { 1215 JavaThread* THREAD = JavaThread::current(); 1216 HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject())); 1217 oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject())); 1218 HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1219 HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type)); 1220 HotSpotJVMCI::VMField::set_offset(this, obj, offset); 1221 HotSpotJVMCI::VMField::set_address(this, obj, address); 1222 HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value)); 1223 return wrap(obj); 1224 } else { 1225 JNIAccessMark jni(this); 1226 jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(), 1227 JNIJVMCI::VMField::constructor(), 1228 get_jobject(name), get_jobject(type), offset, address, get_jobject(value)); 1229 return wrap(result); 1230 } 1231 } 1232 1233 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) { 1234 if (is_hotspot()) { 1235 JavaThread* THREAD = JavaThread::current(); 1236 HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject())); 1237 oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject())); 1238 HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1239 HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type)); 1240 HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value)); 1241 return wrap(obj); 1242 } else { 1243 JNIAccessMark jni(this); 1244 jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(), 1245 JNIJVMCI::VMFlag::constructor(), 1246 get_jobject(name), get_jobject(type), get_jobject(value)); 1247 return wrap(result); 1248 } 1249 } 1250 1251 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS) { 1252 if (is_hotspot()) { 1253 JavaThread* THREAD = JavaThread::current(); 1254 HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject())); 1255 oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject())); 1256 HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass)); 1257 HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1258 HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor)); 1259 HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id); 1260 return wrap(obj); 1261 } else { 1262 JNIAccessMark jni(this); 1263 jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(), 1264 JNIJVMCI::VMIntrinsicMethod::constructor(), 1265 get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id); 1266 return wrap(result); 1267 } 1268 } 1269 1270 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) { 1271 if (is_hotspot()) { 1272 JavaThread* THREAD = JavaThread::current(); 1273 HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject())); 1274 oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject())); 1275 return wrap(obj); 1276 } else { 1277 ShouldNotReachHere(); 1278 return JVMCIObject(); 1279 } 1280 } 1281 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) { 1282 if (is_hotspot()) { 1283 JavaThread* THREAD = JavaThread::current(); 1284 HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject())); 1285 oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject())); 1286 return wrap(obj); 1287 } else { 1288 ShouldNotReachHere(); 1289 return JVMCIObject(); 1290 } 1291 } 1292 1293 1294 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) { 1295 JavaThread* THREAD = JavaThread::current(); 1296 Handle obj = Handle(THREAD, objOop); 1297 if (obj.is_null()) { 1298 return JVMCIObject(); 1299 } 1300 if (is_hotspot()) { 1301 HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject())); 1302 oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject())); 1303 HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj()); 1304 HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed); 1305 return wrap(constant); 1306 } else { 1307 jlong handle = make_handle(obj); 1308 JNIAccessMark jni(this); 1309 jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(), 1310 JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(), 1311 handle, compressed, dont_register); 1312 return wrap(result); 1313 } 1314 } 1315 1316 1317 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) { 1318 if (constant.is_null()) { 1319 return Handle(); 1320 } 1321 JavaThread* THREAD = JavaThread::current(); 1322 if (is_hotspot()) { 1323 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type"); 1324 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant)); 1325 return Handle(THREAD, obj); 1326 } else { 1327 assert(isa_IndirectHotSpotObjectConstantImpl(constant), "wrong type"); 1328 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant); 1329 oop result = resolve_handle(object_handle); 1330 if (result == NULL) { 1331 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly NULL", Handle()); 1332 } 1333 return Handle(THREAD, result); 1334 } 1335 } 1336 1337 JVMCIObject JVMCIEnv::wrap(jobject object) { 1338 return JVMCIObject::create(object, is_hotspot()); 1339 } 1340 1341 jlong JVMCIEnv::make_handle(const Handle& obj) { 1342 assert(!obj.is_null(), "should only create handle for non-NULL oops"); 1343 jobject handle = JVMCI::make_global(obj); 1344 return (jlong) handle; 1345 } 1346 1347 oop JVMCIEnv::resolve_handle(jlong objectHandle) { 1348 assert(objectHandle != 0, "should be a valid handle"); 1349 oop obj = *((oopDesc**)objectHandle); 1350 if (obj != NULL) { 1351 oopDesc::verify(obj); 1352 } 1353 return obj; 1354 } 1355 1356 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) { 1357 if (is_hotspot()) { 1358 JavaThread* THREAD = JavaThread::current(); 1359 Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject())); 1360 return HotSpotJVMCI::wrap(result()); 1361 } else { 1362 jobject result; 1363 jboolean exception = false; 1364 { 1365 JNIAccessMark jni(this); 1366 result = jni()->NewStringUTF(str); 1367 exception = jni()->ExceptionCheck(); 1368 } 1369 return wrap(result); 1370 } 1371 } 1372 1373 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) { 1374 if (is_hotspot()) { 1375 return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b); 1376 } else { 1377 JNIAccessMark jni(this); 1378 return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0; 1379 } 1380 } 1381 1382 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) { 1383 if (kind.is_null()) { 1384 JVMCI_THROW_(NullPointerException, T_ILLEGAL); 1385 } 1386 jchar ch = get_JavaKind_typeChar(kind); 1387 switch(ch) { 1388 case 'Z': return T_BOOLEAN; 1389 case 'B': return T_BYTE; 1390 case 'S': return T_SHORT; 1391 case 'C': return T_CHAR; 1392 case 'I': return T_INT; 1393 case 'F': return T_FLOAT; 1394 case 'J': return T_LONG; 1395 case 'D': return T_DOUBLE; 1396 case 'A': return T_OBJECT; 1397 case '-': return T_ILLEGAL; 1398 default: 1399 JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch); 1400 } 1401 } 1402 1403 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) { 1404 // Ensure that all updates to the InstalledCode fields are consistent. 1405 if (get_InstalledCode_address(installed_code) != 0) { 1406 JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use"); 1407 } 1408 if (!isa_HotSpotInstalledCode(installed_code)) { 1409 JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode"); 1410 } 1411 1412 // Ignore the version which can stay at 0 1413 if (cb->is_nmethod()) { 1414 nmethod* nm = cb->as_nmethod_or_null(); 1415 if (!nm->is_alive()) { 1416 JVMCI_THROW_MSG(InternalError, "nmethod has been reclaimed"); 1417 } 1418 if (nm->is_in_use()) { 1419 set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point()); 1420 } 1421 } else { 1422 set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin()); 1423 } 1424 set_InstalledCode_address(installed_code, (jlong) cb); 1425 set_HotSpotInstalledCode_size(installed_code, cb->size()); 1426 set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin()); 1427 set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size()); 1428 } 1429 1430 1431 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS) { 1432 if (mirror.is_null()) { 1433 JVMCI_THROW(NullPointerException); 1434 } 1435 1436 jlong nativeMethod = get_InstalledCode_address(mirror); 1437 nmethod* nm = JVMCIENV->asNmethod(mirror); 1438 if (nm == NULL) { 1439 // Nothing to do 1440 return; 1441 } 1442 1443 Thread* THREAD = Thread::current(); 1444 if (!mirror.is_hotspot() && !THREAD->is_Java_thread()) { 1445 // Calling back into native might cause the execution to block, so only allow this when calling 1446 // from a JavaThread, which is the normal case anyway. 1447 JVMCI_THROW_MSG(IllegalArgumentException, 1448 "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread"); 1449 } 1450 1451 nmethodLocker nml(nm); 1452 if (nm->is_alive()) { 1453 // Invalidating the HotSpotNmethod means we want the nmethod 1454 // to be deoptimized. 1455 nm->mark_for_deoptimization(); 1456 VM_Deoptimize op; 1457 VMThread::execute(&op); 1458 } 1459 1460 // A HotSpotNmethod instance can only reference a single nmethod 1461 // during its lifetime so simply clear it here. 1462 set_InstalledCode_address(mirror, 0); 1463 } 1464 1465 Klass* JVMCIEnv::asKlass(JVMCIObject obj) { 1466 return (Klass*) get_HotSpotResolvedObjectTypeImpl_metadataPointer(obj); 1467 } 1468 1469 Method* JVMCIEnv::asMethod(JVMCIObject obj) { 1470 Method** metadataHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_metadataHandle(obj); 1471 return *metadataHandle; 1472 } 1473 1474 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) { 1475 ConstantPool** metadataHandle = (ConstantPool**) get_HotSpotConstantPool_metadataHandle(obj); 1476 return *metadataHandle; 1477 } 1478 1479 1480 CodeBlob* JVMCIEnv::asCodeBlob(JVMCIObject obj) { 1481 address code = (address) get_InstalledCode_address(obj); 1482 if (code == NULL) { 1483 return NULL; 1484 } 1485 if (isa_HotSpotNmethod(obj)) { 1486 jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj); 1487 if (compile_id_snapshot != 0L) { 1488 // A HotSpotNMethod not in an nmethod's oops table so look up 1489 // the nmethod and then update the fields based on its state. 1490 CodeBlob* cb = CodeCache::find_blob_unsafe(code); 1491 if (cb == (CodeBlob*) code) { 1492 // Found a live CodeBlob with the same address, make sure it's the same nmethod 1493 nmethod* nm = cb->as_nmethod_or_null(); 1494 if (nm != NULL && nm->compile_id() == compile_id_snapshot) { 1495 if (!nm->is_alive()) { 1496 // Break the links from the mirror to the nmethod 1497 set_InstalledCode_address(obj, 0); 1498 set_InstalledCode_entryPoint(obj, 0); 1499 } else if (nm->is_not_entrant()) { 1500 // Zero the entry point so that the nmethod 1501 // cannot be invoked by the mirror but can 1502 // still be deoptimized. 1503 set_InstalledCode_entryPoint(obj, 0); 1504 } 1505 return cb; 1506 } 1507 } 1508 // Clear the InstalledCode fields of this HotSpotNmethod 1509 // that no longer refers to an nmethod in the code cache. 1510 set_InstalledCode_address(obj, 0); 1511 set_InstalledCode_entryPoint(obj, 0); 1512 return NULL; 1513 } 1514 } 1515 return (CodeBlob*) code; 1516 } 1517 1518 1519 // Generate implementations for the initialize, new, isa, get and set methods for all the types and 1520 // fields declared in the JVMCI_CLASSES_DO macro. 1521 1522 #define START_CLASS(className, fullClassName) \ 1523 void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \ 1524 if (is_hotspot()) { \ 1525 HotSpotJVMCI::className::initialize(JVMCI_CHECK); \ 1526 } else { \ 1527 JNIJVMCI::className::initialize(JVMCI_CHECK); \ 1528 } \ 1529 } \ 1530 JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \ 1531 if (is_hotspot()) { \ 1532 Thread* THREAD = Thread::current(); \ 1533 objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \ 1534 return (JVMCIObjectArray) wrap(array); \ 1535 } else { \ 1536 JNIAccessMark jni(this); \ 1537 jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), NULL); \ 1538 return wrap(result); \ 1539 } \ 1540 } \ 1541 bool JVMCIEnv::isa_##className(JVMCIObject object) { \ 1542 if (is_hotspot()) { \ 1543 return HotSpotJVMCI::className::is_instance(this, object); \ 1544 } else { \ 1545 return JNIJVMCI::className::is_instance(this, object); \ 1546 } \ 1547 } 1548 1549 #define END_CLASS 1550 1551 #define FIELD(className, name, type, accessor, cast) \ 1552 type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \ 1553 if (is_hotspot()) { \ 1554 return HotSpotJVMCI::className::get_##name(this, obj); \ 1555 } else { \ 1556 return JNIJVMCI::className::get_##name(this, obj); \ 1557 } \ 1558 } \ 1559 void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \ 1560 if (is_hotspot()) { \ 1561 HotSpotJVMCI::className::set_##name(this, obj, x); \ 1562 } else { \ 1563 JNIJVMCI::className::set_##name(this, obj, x); \ 1564 } \ 1565 } 1566 1567 #define EMPTY_CAST 1568 #define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST) 1569 #define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST) 1570 #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 1571 #define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST) 1572 #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST) 1573 1574 #define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST) 1575 #define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 1576 #define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray)) 1577 1578 #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject)) 1579 #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 1580 1581 #define OOPISH_FIELD(className, name, type, accessor, cast) \ 1582 type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \ 1583 if (is_hotspot()) { \ 1584 return HotSpotJVMCI::className::get_##name(this, obj); \ 1585 } else { \ 1586 return JNIJVMCI::className::get_##name(this, obj); \ 1587 } \ 1588 } \ 1589 void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \ 1590 if (is_hotspot()) { \ 1591 HotSpotJVMCI::className::set_##name(this, obj, x); \ 1592 } else { \ 1593 JNIJVMCI::className::set_##name(this, obj, x); \ 1594 } \ 1595 } 1596 1597 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \ 1598 type JVMCIEnv::get_##className##_##name() { \ 1599 if (is_hotspot()) { \ 1600 return HotSpotJVMCI::className::get_##name(this); \ 1601 } else { \ 1602 return JNIJVMCI::className::get_##name(this); \ 1603 } \ 1604 } \ 1605 void JVMCIEnv::set_##className##_##name(type x) { \ 1606 if (is_hotspot()) { \ 1607 HotSpotJVMCI::className::set_##name(this, x); \ 1608 } else { \ 1609 JNIJVMCI::className::set_##name(this, x); \ 1610 } \ 1611 } 1612 1613 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \ 1614 type JVMCIEnv::get_##className##_##name() { \ 1615 if (is_hotspot()) { \ 1616 return HotSpotJVMCI::className::get_##name(this); \ 1617 } else { \ 1618 return JNIJVMCI::className::get_##name(this); \ 1619 } \ 1620 } \ 1621 void JVMCIEnv::set_##className##_##name(type x) { \ 1622 if (is_hotspot()) { \ 1623 HotSpotJVMCI::className::set_##name(this, x); \ 1624 } else { \ 1625 JNIJVMCI::className::set_##name(this, x); \ 1626 } \ 1627 } 1628 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST) 1629 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 1630 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) 1631 #define CONSTRUCTOR(className, signature) 1632 1633 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) 1634 1635 #undef START_CLASS 1636 #undef END_CLASS 1637 #undef METHOD 1638 #undef CONSTRUCTOR 1639 #undef FIELD 1640 #undef CHAR_FIELD 1641 #undef INT_FIELD 1642 #undef BOOLEAN_FIELD 1643 #undef LONG_FIELD 1644 #undef FLOAT_FIELD 1645 #undef OBJECT_FIELD 1646 #undef PRIMARRAY_FIELD 1647 #undef OBJECTARRAY_FIELD 1648 #undef STATIC_OOPISH_FIELD 1649 #undef STATIC_OBJECT_FIELD 1650 #undef STATIC_OBJECTARRAY_FIELD 1651 #undef STATIC_INT_FIELD 1652 #undef STATIC_BOOLEAN_FIELD 1653 #undef EMPTY_CAST