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