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