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