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