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