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