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