1 /* 2 * Copyright (c) 1999, 2025, 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 "classfile/stringTable.hpp" 26 #include "classfile/symbolTable.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "code/codeCache.hpp" 29 #include "compiler/compilerOracle.hpp" 30 #include "compiler/compileTask.hpp" 31 #include "gc/shared/barrierSet.hpp" 32 #include "gc/shared/barrierSetNMethod.hpp" 33 #include "jvm_io.h" 34 #include "jvmci/jniAccessMark.inline.hpp" 35 #include "jvmci/jvmciCompiler.hpp" 36 #include "jvmci/jvmciRuntime.hpp" 37 #include "memory/oopFactory.hpp" 38 #include "memory/resourceArea.hpp" 39 #include "memory/universe.hpp" 40 #include "oops/objArrayKlass.hpp" 41 #include "oops/typeArrayOop.inline.hpp" 42 #include "prims/jvmtiExport.hpp" 43 #include "runtime/arguments.hpp" 44 #include "runtime/deoptimization.hpp" 45 #include "runtime/fieldDescriptor.inline.hpp" 46 #include "runtime/javaCalls.hpp" 47 #include "runtime/jniHandles.inline.hpp" 48 #include "runtime/os.hpp" 49 #include "utilities/permitForbiddenFunctions.hpp" 50 51 JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler): 52 _task(task), 53 _compiler(compiler), 54 _retryable(true), 55 _failure_reason(nullptr), 56 _failure_reason_on_C_heap(false) { 57 // Get Jvmti capabilities under lock to get consistent values. 58 MutexLocker mu(JvmtiThreadState_lock); 59 _jvmti_redefinition_count = JvmtiExport::redefinition_count(); 60 _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint() ? 1 : 0; 61 _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables() ? 1 : 0; 62 _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions() ? 1 : 0; 63 _jvmti_can_pop_frame = JvmtiExport::can_pop_frame() ? 1 : 0; 64 _target_method_is_old = _task != nullptr && _task->method()->is_old(); 65 if (task->is_blocking()) { 66 task->set_blocking_jvmci_compile_state(this); 67 } 68 } 69 70 void JVMCICompileState::set_failure(bool retryable, const char* reason, bool reason_on_C_heap) { 71 if (_failure_reason != nullptr && _failure_reason_on_C_heap) { 72 os::free((void*) _failure_reason); 73 } 74 _failure_reason = reason; 75 _failure_reason_on_C_heap = reason_on_C_heap; 76 _retryable = retryable; 77 } 78 79 void JVMCICompileState::notify_libjvmci_oome() { 80 const char* msg = "Out of memory initializing libjvmci or attaching it to the current thread"; 81 set_failure(true, msg); 82 _compiler->on_upcall(msg); 83 } 84 85 // Update global JVMCI compilation ticks after 512 thread-local JVMCI compilation ticks. 86 // This mitigates the overhead of the atomic operation used for the global update. 87 #define THREAD_TICKS_PER_GLOBAL_TICKS (2 << 9) 88 #define THREAD_TICKS_PER_GLOBAL_TICKS_MASK (THREAD_TICKS_PER_GLOBAL_TICKS - 1) 89 90 void JVMCICompileState::inc_compilation_ticks() { 91 if ((++_compilation_ticks & THREAD_TICKS_PER_GLOBAL_TICKS_MASK) == 0) { 92 _compiler->inc_global_compilation_ticks(); 93 } 94 } 95 96 bool JVMCICompileState::jvmti_state_changed() const { 97 // Some classes were redefined 98 if (jvmti_redefinition_count() != JvmtiExport::redefinition_count()) { 99 return true; 100 } 101 if (!jvmti_can_access_local_variables() && 102 JvmtiExport::can_access_local_variables()) { 103 return true; 104 } 105 if (!jvmti_can_hotswap_or_post_breakpoint() && 106 JvmtiExport::can_hotswap_or_post_breakpoint()) { 107 return true; 108 } 109 if (!jvmti_can_post_on_exceptions() && 110 JvmtiExport::can_post_on_exceptions()) { 111 return true; 112 } 113 if (!jvmti_can_pop_frame() && 114 JvmtiExport::can_pop_frame()) { 115 return true; 116 } 117 return false; 118 } 119 120 void JVMCIEnv::init_env_mode_runtime(JavaThread* thread, JNIEnv* parent_env) { 121 assert(thread != nullptr, "npe"); 122 _env = nullptr; 123 _pop_frame_on_close = false; 124 _detach_on_close = false; 125 if (!UseJVMCINativeLibrary) { 126 // In HotSpot mode, JNI isn't used at all. 127 _runtime = JVMCI::java_runtime(); 128 _is_hotspot = true; 129 return; 130 } 131 132 if (parent_env != nullptr) { 133 // If the parent JNI environment is non-null then figure out whether it 134 // is a HotSpot or shared library JNIEnv and set the state appropriately. 135 _is_hotspot = thread->jni_environment() == parent_env; 136 if (_is_hotspot) { 137 // Select the Java runtime 138 _runtime = JVMCI::java_runtime(); 139 return; 140 } 141 _runtime = thread->libjvmci_runtime(); 142 assert(_runtime != nullptr, "npe"); 143 _env = parent_env; 144 return; 145 } 146 147 // Running in JVMCI shared library mode so ensure the shared library 148 // is loaded and initialized and get a shared library JNIEnv 149 _is_hotspot = false; 150 151 _runtime = JVMCI::compiler_runtime(thread); 152 _env = _runtime->init_shared_library_javavm(&_init_error, &_init_error_msg); 153 if (_env != nullptr) { 154 // Creating the JVMCI shared library VM also attaches the current thread 155 _detach_on_close = true; 156 } else if (_init_error != JNI_OK) { 157 // Caller creating this JVMCIEnv must handle the error. 158 JVMCI_event_1("[%s:%d] Error creating libjvmci (err: %d, %s)", _file, _line, 159 _init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg); 160 return; 161 } else { 162 _runtime->GetEnv(thread, (void**)&parent_env, JNI_VERSION_1_2); 163 if (parent_env != nullptr) { 164 // Even though there's a parent JNI env, there's no guarantee 165 // it was opened by a JVMCIEnv scope and thus may not have 166 // pushed a local JNI frame. As such, we use a new JNI local 167 // frame in this scope to ensure local JNI refs are collected 168 // in a timely manner after leaving this scope. 169 _env = parent_env; 170 } else { 171 ResourceMark rm; // Thread name is resource allocated 172 JavaVMAttachArgs attach_args; 173 attach_args.version = JNI_VERSION_1_2; 174 attach_args.name = const_cast<char*>(thread->name()); 175 attach_args.group = nullptr; 176 _init_error = _runtime->AttachCurrentThread(thread, (void**) &_env, &attach_args); 177 if (_init_error == JNI_OK) { 178 _detach_on_close = true; 179 } else { 180 // Caller creating this JVMCIEnv must handle the error. 181 _env = nullptr; 182 JVMCI_event_1("[%s:%d] Error attaching to libjvmci (err: %d)", _file, _line, _init_error); 183 return; 184 } 185 } 186 } 187 188 assert(_env != nullptr, "missing env"); 189 assert(_throw_to_caller == false, "must be"); 190 191 JNIAccessMark jni(this, thread); 192 jint result = _env->PushLocalFrame(32); 193 if (result != JNI_OK) { 194 JVMCI_event_1("[%s:%d] Error pushing local JNI frame (err: %d)", _file, _line, result); 195 return; 196 } 197 _pop_frame_on_close = true; 198 } 199 200 JVMCIEnv::JVMCIEnv(JavaThread* thread, JVMCICompileState* compile_state, const char* file, int line): 201 _throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(compile_state) { 202 init_env_mode_runtime(thread, nullptr); 203 } 204 205 JVMCIEnv::JVMCIEnv(JavaThread* thread, const char* file, int line): 206 _throw_to_caller(false), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(nullptr) { 207 init_env_mode_runtime(thread, nullptr); 208 } 209 210 JVMCIEnv::JVMCIEnv(JavaThread* thread, JNIEnv* parent_env, const char* file, int line): 211 _throw_to_caller(true), _file(file), _line(line), _init_error(JNI_OK), _init_error_msg(nullptr), _compile_state(nullptr) { 212 assert(parent_env != nullptr, "npe"); 213 init_env_mode_runtime(thread, parent_env); 214 assert(_env == nullptr || parent_env == _env, "mismatched JNIEnvironment"); 215 assert(_init_error == JNI_OK, "err: %d", _init_error); 216 } 217 218 void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int line) { 219 _compile_state = nullptr; 220 _throw_to_caller = false; 221 _file = file; 222 _line = line; 223 _init_error = JNI_OK; 224 _init_error_msg = nullptr; 225 if (is_hotspot) { 226 _env = nullptr; 227 _pop_frame_on_close = false; 228 _detach_on_close = false; 229 _is_hotspot = true; 230 _runtime = JVMCI::java_runtime(); 231 } else { 232 init_env_mode_runtime(thread, nullptr); 233 } 234 } 235 236 void JVMCIEnv::check_init(JVMCI_TRAPS) { 237 guarantee(JVMCIENV != this, "must be"); 238 if (_init_error == JNI_OK) { 239 return; 240 } 241 if (_init_error == JNI_ENOMEM) { 242 JVMCI_THROW_MSG(OutOfMemoryError, "JNI_ENOMEM creating or attaching to libjvmci"); 243 } 244 stringStream st; 245 st.print("Error creating or attaching to libjvmci (err: %d, description: %s)", 246 _init_error, _init_error_msg == nullptr ? "unknown" : _init_error_msg); 247 JVMCI_THROW_MSG(InternalError, st.freeze()); 248 } 249 250 void JVMCIEnv::check_init(TRAPS) { 251 if (_init_error == JNI_OK) { 252 return; 253 } 254 stringStream st; 255 st.print("Error creating or attaching to libjvmci (err: %d, description: %s)", 256 _init_error, _init_error_msg != nullptr ? _init_error_msg : (_init_error == JNI_ENOMEM ? "JNI_ENOMEM" : "none")); 257 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), st.freeze()); 258 } 259 260 // Prints a pending exception (if any) and its stack trace to st. 261 // Also partially logs the stack trace to the JVMCI event log. 262 void JVMCIEnv::describe_pending_exception(outputStream* st) { 263 ResourceMark rm; 264 char* stack_trace = nullptr; 265 if (pending_exception_as_string(nullptr, (const char**) &stack_trace)) { 266 st->print_raw_cr(stack_trace); 267 268 // Use up to half the lines of the JVMCI event log to 269 // show the stack trace. 270 char* cursor = stack_trace; 271 int line = 0; 272 const int max_lines = LogEventsBufferEntries / 2; 273 char* last_line = nullptr; 274 while (*cursor != '\0') { 275 char* eol = strchr(cursor, '\n'); 276 if (eol == nullptr) { 277 if (line == max_lines - 1) { 278 last_line = cursor; 279 } else if (line < max_lines) { 280 JVMCI_event_1("%s", cursor); 281 } 282 cursor = cursor + strlen(cursor); 283 } else { 284 *eol = '\0'; 285 if (line == max_lines - 1) { 286 last_line = cursor; 287 } else if (line < max_lines) { 288 JVMCI_event_1("%s", cursor); 289 } 290 cursor = eol + 1; 291 } 292 line++; 293 } 294 if (last_line != nullptr) { 295 if (line > max_lines) { 296 JVMCI_event_1("%s [elided %d more stack trace lines]", last_line, line - max_lines); 297 } else { 298 JVMCI_event_1("%s", last_line); 299 } 300 } 301 } 302 } 303 304 bool JVMCIEnv::pending_exception_as_string(const char** to_string, const char** stack_trace) { 305 JavaThread* THREAD = JavaThread::current(); // For exception macros. 306 JVMCIObject to_string_obj; 307 JVMCIObject stack_trace_obj; 308 bool had_nested_exception = false; 309 if (!is_hotspot()) { 310 JNIAccessMark jni(this, THREAD); 311 jthrowable ex = jni()->ExceptionOccurred(); 312 if (ex != nullptr) { 313 jni()->ExceptionClear(); 314 jobjectArray pair = (jobjectArray) jni()->CallStaticObjectMethod( 315 JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 316 JNIJVMCI::HotSpotJVMCIRuntime::exceptionToString_method(), 317 ex, to_string != nullptr, stack_trace != nullptr); 318 if (jni()->ExceptionCheck()) { 319 // As last resort, dump nested exception 320 jni()->ExceptionDescribe(); 321 had_nested_exception = true; 322 } else { 323 guarantee(pair != nullptr, "pair is null"); 324 int len = jni()->GetArrayLength(pair); 325 guarantee(len == 2, "bad len is %d", len); 326 if (to_string != nullptr) { 327 to_string_obj = JVMCIObject::create(jni()->GetObjectArrayElement(pair, 0), false); 328 } 329 if (stack_trace != nullptr) { 330 stack_trace_obj = JVMCIObject::create(jni()->GetObjectArrayElement(pair, 1), false); 331 } 332 } 333 } else { 334 return false; 335 } 336 } else { 337 if (HAS_PENDING_EXCEPTION) { 338 Handle exception(THREAD, PENDING_EXCEPTION); 339 CLEAR_PENDING_EXCEPTION; 340 JavaCallArguments jargs; 341 jargs.push_oop(exception); 342 jargs.push_int(to_string != nullptr); 343 jargs.push_int(stack_trace != nullptr); 344 JavaValue result(T_OBJECT); 345 JavaCalls::call_static(&result, 346 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 347 vmSymbols::exceptionToString_name(), 348 vmSymbols::exceptionToString_signature(), &jargs, THREAD); 349 if (HAS_PENDING_EXCEPTION) { 350 Handle nested_exception(THREAD, PENDING_EXCEPTION); 351 CLEAR_PENDING_EXCEPTION; 352 java_lang_Throwable::print_stack_trace(nested_exception, tty); 353 // Clear and ignore any exceptions raised during printing 354 CLEAR_PENDING_EXCEPTION; 355 had_nested_exception = true; 356 } else { 357 oop pair = result.get_oop(); 358 guarantee(pair->is_objArray(), "must be"); 359 objArrayOop pair_arr = objArrayOop(pair); 360 int len = pair_arr->length(); 361 guarantee(len == 2, "bad len is %d", len); 362 if (to_string != nullptr) { 363 to_string_obj = HotSpotJVMCI::wrap(pair_arr->obj_at(0)); 364 } 365 if (stack_trace != nullptr) { 366 stack_trace_obj = HotSpotJVMCI::wrap(pair_arr->obj_at(1)); 367 } 368 } 369 } else { 370 return false; 371 } 372 } 373 if (had_nested_exception) { 374 if (to_string != nullptr) { 375 *to_string = "nested exception occurred converting exception to string"; 376 } 377 if (stack_trace != nullptr) { 378 *stack_trace = "nested exception occurred converting exception stack to string"; 379 } 380 } else { 381 if (to_string_obj.is_non_null()) { 382 *to_string = as_utf8_string(to_string_obj); 383 } 384 if (stack_trace_obj.is_non_null()) { 385 *stack_trace = as_utf8_string(stack_trace_obj); 386 } 387 } 388 return true; 389 } 390 391 392 // Shared code for translating an exception from HotSpot to libjvmci or vice versa. 393 class ExceptionTranslation: public StackObj { 394 protected: 395 enum DecodeFormat { 396 _encoded_ok = 0, // exception was successfully encoded into buffer 397 _buffer_alloc_fail = 1, // native memory for buffer could not be allocated 398 _encode_oome_fail = 2, // OutOfMemoryError thrown during encoding 399 _encode_fail = 3, // some other problem occured during encoding. If buffer != 0, 400 // buffer contains a `struct { u4 len; char[len] desc}` 401 // describing the problem 402 _encode_oome_in_vm = 4 // an OutOfMemoryError thrown from within VM code on a 403 // thread that cannot call Java (OOME has no stack trace) 404 }; 405 406 JVMCIEnv* _from_env; // Source of translation. Can be null. 407 JVMCIEnv* _to_env; // Destination of translation. Never null. 408 409 ExceptionTranslation(JVMCIEnv* from_env, JVMCIEnv* to_env) : _from_env(from_env), _to_env(to_env) {} 410 411 // Encodes the exception in `_from_env` into `buffer`. 412 // Where N is the number of bytes needed for the encoding, returns N if N <= `buffer_size` 413 // and the encoding was written to `buffer` otherwise returns -N. 414 virtual int encode(JavaThread* THREAD, jlong buffer, int buffer_size) = 0; 415 416 // Decodes the exception in `buffer` in `_to_env` and throws it. 417 virtual void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) = 0; 418 419 static bool debug_translated_exception() { 420 const char* prop_value = Arguments::get_property("jdk.internal.vm.TranslatedException.debug"); 421 return prop_value != nullptr && strcmp("true", prop_value) == 0; 422 } 423 424 public: 425 void doit(JavaThread* THREAD) { 426 int buffer_size = 2048; 427 while (true) { 428 ResourceMark rm; 429 jlong buffer = (jlong) NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, jbyte, buffer_size); 430 if (buffer == 0L) { 431 JVMCI_event_1("error translating exception: translation buffer allocation failed"); 432 decode(THREAD, _buffer_alloc_fail, 0L); 433 return; 434 } 435 int res = encode(THREAD, buffer, buffer_size); 436 if (_to_env->has_pending_exception()) { 437 // Propagate pending exception 438 return; 439 } 440 if (res < 0) { 441 int required_buffer_size = -res; 442 if (required_buffer_size > buffer_size) { 443 buffer_size = required_buffer_size; 444 } 445 } else { 446 decode(THREAD, _encoded_ok, buffer); 447 if (!_to_env->has_pending_exception()) { 448 _to_env->throw_InternalError("decodeAndThrowThrowable should have thrown an exception"); 449 } 450 return; 451 } 452 } 453 } 454 }; 455 456 // Translates an exception on the HotSpot heap to an exception on the shared library heap. 457 class HotSpotToSharedLibraryExceptionTranslation : public ExceptionTranslation { 458 private: 459 const Handle& _throwable; 460 461 char* print_throwable_to_buffer(Handle throwable, jlong buffer, int buffer_size) { 462 char* char_buffer = (char*) buffer + 4; 463 stringStream st(char_buffer, (size_t) buffer_size - 4); 464 java_lang_Throwable::print_stack_trace(throwable, &st); 465 u4 len = (u4) st.size(); 466 *((u4*) buffer) = len; 467 return char_buffer; 468 } 469 470 bool handle_pending_exception(JavaThread* THREAD, jlong buffer, int buffer_size) { 471 if (HAS_PENDING_EXCEPTION) { 472 Handle throwable = Handle(THREAD, PENDING_EXCEPTION); 473 Symbol *ex_name = throwable->klass()->name(); 474 CLEAR_PENDING_EXCEPTION; 475 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { 476 JVMCI_event_1("error translating exception: OutOfMemoryError"); 477 decode(THREAD, _encode_oome_fail, 0L); 478 } else { 479 char* char_buffer = print_throwable_to_buffer(throwable, buffer, buffer_size); 480 JVMCI_event_1("error translating exception: %s", char_buffer); 481 decode(THREAD, _encode_fail, buffer); 482 } 483 return true; 484 } 485 return false; 486 } 487 488 int encode(JavaThread* THREAD, jlong buffer, int buffer_size) { 489 if (!THREAD->can_call_java()) { 490 Symbol *ex_name = _throwable->klass()->name(); 491 if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) { 492 JVMCI_event_1("translating exception: OutOfMemoryError within VM code"); 493 decode(THREAD, _encode_oome_in_vm, 0L); 494 return 0; 495 } 496 char* char_buffer = print_throwable_to_buffer(_throwable, buffer, buffer_size); 497 const char* detail = log_is_enabled(Info, exceptions) ? "" : " (-Xlog:exceptions may give more detail)"; 498 JVMCI_event_1("cannot call Java to translate exception%s: %s", detail, char_buffer); 499 decode(THREAD, _encode_fail, buffer); 500 return 0; 501 } 502 Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, THREAD); 503 if (handle_pending_exception(THREAD, buffer, buffer_size)) { 504 return 0; 505 } 506 JavaCallArguments jargs; 507 jargs.push_oop(_throwable); 508 jargs.push_long(buffer); 509 jargs.push_int(buffer_size); 510 JavaValue result(T_INT); 511 JavaCalls::call_static(&result, 512 vmSupport, 513 vmSymbols::encodeThrowable_name(), 514 vmSymbols::encodeThrowable_signature(), &jargs, THREAD); 515 if (handle_pending_exception(THREAD, buffer, buffer_size)) { 516 return 0; 517 } 518 return result.get_jint(); 519 } 520 521 void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) { 522 JVMCI_event_1("decoding exception from JVM heap (format: %d, buffer[%d]) ", format, buffer == 0L ? -1 : *((u4*) buffer)); 523 JNIAccessMark jni(_to_env, THREAD); 524 jni()->CallStaticVoidMethod(JNIJVMCI::VMSupport::clazz(), 525 JNIJVMCI::VMSupport::decodeAndThrowThrowable_method(), 526 format, buffer, false, debug_translated_exception()); 527 } 528 public: 529 HotSpotToSharedLibraryExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, const Handle& throwable) : 530 ExceptionTranslation(hotspot_env, jni_env), _throwable(throwable) {} 531 }; 532 533 // Translates an exception on the shared library heap to an exception on the HotSpot heap. 534 class SharedLibraryToHotSpotExceptionTranslation : public ExceptionTranslation { 535 private: 536 jthrowable _throwable; 537 538 int encode(JavaThread* THREAD, jlong buffer, int buffer_size) { 539 JNIAccessMark jni(_from_env, THREAD); 540 int res = jni()->CallStaticIntMethod(JNIJVMCI::VMSupport::clazz(), 541 JNIJVMCI::VMSupport::encodeThrowable_method(), 542 _throwable, buffer, buffer_size); 543 if (jni()->ExceptionCheck()) { 544 // Cannot get name of exception thrown as that can raise another exception. 545 jni()->ExceptionClear(); 546 JVMCI_event_1("error translating exception: unknown error"); 547 decode(THREAD, _encode_fail, 0L); 548 return 0; 549 } 550 return res; 551 } 552 553 void decode(JavaThread* THREAD, DecodeFormat format, jlong buffer) { 554 JVMCI_event_1("decoding exception to JVM heap (format: %d, buffer[%d]) ", format, buffer == 0L ? -1 : *((u4*) buffer)); 555 Klass* vmSupport = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_vm_VMSupport(), true, CHECK); 556 JavaCallArguments jargs; 557 jargs.push_int(format); 558 jargs.push_long(buffer); 559 jargs.push_int(true); 560 jargs.push_int(debug_translated_exception()); 561 JavaValue result(T_VOID); 562 JavaCalls::call_static(&result, 563 vmSupport, 564 vmSymbols::decodeAndThrowThrowable_name(), 565 vmSymbols::decodeAndThrowThrowable_signature(), &jargs, THREAD); 566 } 567 public: 568 SharedLibraryToHotSpotExceptionTranslation(JVMCIEnv* hotspot_env, JVMCIEnv* jni_env, jthrowable throwable) : 569 ExceptionTranslation(jni_env, hotspot_env), _throwable(throwable) {} 570 }; 571 572 void JVMCIEnv::translate_to_jni_exception(JavaThread* THREAD, const Handle& throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) { 573 HotSpotToSharedLibraryExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD); 574 } 575 576 void JVMCIEnv::translate_from_jni_exception(JavaThread* THREAD, jthrowable throwable, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) { 577 SharedLibraryToHotSpotExceptionTranslation(hotspot_env, jni_env, throwable).doit(THREAD); 578 } 579 580 jboolean JVMCIEnv::transfer_pending_exception_to_jni(JavaThread* THREAD, JVMCIEnv* hotspot_env, JVMCIEnv* jni_env) { 581 if (HAS_PENDING_EXCEPTION) { 582 Handle throwable = Handle(THREAD, PENDING_EXCEPTION); 583 CLEAR_PENDING_EXCEPTION; 584 translate_to_jni_exception(THREAD, throwable, hotspot_env, jni_env); 585 return true; 586 } 587 return false; 588 } 589 590 jboolean JVMCIEnv::transfer_pending_exception(JavaThread* THREAD, JVMCIEnv* peer_env) { 591 if (is_hotspot()) { 592 return transfer_pending_exception_to_jni(THREAD, this, peer_env); 593 } 594 jthrowable ex = nullptr; 595 { 596 JNIAccessMark jni(this, THREAD); 597 ex = jni()->ExceptionOccurred(); 598 if (ex != nullptr) { 599 jni()->ExceptionClear(); 600 } 601 } 602 if (ex != nullptr) { 603 translate_from_jni_exception(THREAD, ex, peer_env, this); 604 return true; 605 } 606 return false; 607 } 608 609 JVMCIEnv::~JVMCIEnv() { 610 if (_init_error_msg != nullptr) { 611 // The memory allocated in libjvmci was not allocated with os::malloc 612 // so must not be freed with os::free. 613 permit_forbidden_function::free((void*)_init_error_msg); 614 } 615 if (_init_error != JNI_OK) { 616 return; 617 } 618 if (_throw_to_caller) { 619 if (is_hotspot()) { 620 // Nothing to do 621 } else { 622 Thread* thread = Thread::current(); 623 if (thread->is_Java_thread()) { 624 JavaThread* THREAD = JavaThread::cast(thread); // For exception macros. 625 if (HAS_PENDING_EXCEPTION) { 626 Handle throwable = Handle(THREAD, PENDING_EXCEPTION); 627 CLEAR_PENDING_EXCEPTION; 628 translate_to_jni_exception(THREAD, throwable, nullptr, this); 629 } 630 } 631 } 632 } else { 633 if (_pop_frame_on_close) { 634 // Pop the JNI local frame that was pushed when entering this JVMCIEnv scope. 635 JNIAccessMark jni(this); 636 jni()->PopLocalFrame(nullptr); 637 } 638 639 if (has_pending_exception()) { 640 char message[256]; 641 jio_snprintf(message, 256, "Uncaught exception exiting %s JVMCIEnv scope entered at %s:%d", 642 is_hotspot() ? "HotSpot" : "libjvmci", _file, _line); 643 JVMCIRuntime::fatal_exception(this, message); 644 } 645 646 if (_detach_on_close) { 647 _runtime->DetachCurrentThread(JavaThread::current()); 648 } 649 } 650 } 651 652 jboolean JVMCIEnv::has_pending_exception() { 653 if (is_hotspot()) { 654 JavaThread* THREAD = JavaThread::current(); // For exception macros. 655 return HAS_PENDING_EXCEPTION; 656 } else { 657 JNIAccessMark jni(this); 658 return jni()->ExceptionCheck(); 659 } 660 } 661 662 void JVMCIEnv::clear_pending_exception() { 663 if (is_hotspot()) { 664 JavaThread* THREAD = JavaThread::current(); // For exception macros. 665 CLEAR_PENDING_EXCEPTION; 666 } else { 667 JNIAccessMark jni(this); 668 jni()->ExceptionClear(); 669 } 670 } 671 672 int JVMCIEnv::get_length(JVMCIArray array) { 673 if (is_hotspot()) { 674 return HotSpotJVMCI::resolve(array)->length(); 675 } else { 676 JNIAccessMark jni(this); 677 return jni()->GetArrayLength(get_jarray(array)); 678 } 679 } 680 681 JVMCIObject JVMCIEnv::get_object_at(JVMCIObjectArray array, int index) { 682 if (is_hotspot()) { 683 oop result = HotSpotJVMCI::resolve(array)->obj_at(index); 684 return wrap(result); 685 } else { 686 JNIAccessMark jni(this); 687 jobject result = jni()->GetObjectArrayElement(get_jobjectArray(array), index); 688 return wrap(result); 689 } 690 } 691 692 void JVMCIEnv::put_object_at(JVMCIObjectArray array, int index, JVMCIObject value) { 693 if (is_hotspot()) { 694 HotSpotJVMCI::resolve(array)->obj_at_put(index, HotSpotJVMCI::resolve(value)); 695 } else { 696 JNIAccessMark jni(this); 697 jni()->SetObjectArrayElement(get_jobjectArray(array), index, get_jobject(value)); 698 } 699 } 700 701 jboolean JVMCIEnv::get_bool_at(JVMCIPrimitiveArray array, int index) { 702 if (is_hotspot()) { 703 return HotSpotJVMCI::resolve(array)->bool_at(index); 704 } else { 705 JNIAccessMark jni(this); 706 jboolean result; 707 jni()->GetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &result); 708 return result; 709 } 710 } 711 void JVMCIEnv::put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value) { 712 if (is_hotspot()) { 713 HotSpotJVMCI::resolve(array)->bool_at_put(index, value); 714 } else { 715 JNIAccessMark jni(this); 716 jni()->SetBooleanArrayRegion(array.as_jbooleanArray(), index, 1, &value); 717 } 718 } 719 720 jbyte JVMCIEnv::get_byte_at(JVMCIPrimitiveArray array, int index) { 721 if (is_hotspot()) { 722 return HotSpotJVMCI::resolve(array)->byte_at(index); 723 } else { 724 JNIAccessMark jni(this); 725 jbyte result; 726 jni()->GetByteArrayRegion(array.as_jbyteArray(), index, 1, &result); 727 return result; 728 } 729 } 730 void JVMCIEnv::put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value) { 731 if (is_hotspot()) { 732 HotSpotJVMCI::resolve(array)->byte_at_put(index, value); 733 } else { 734 JNIAccessMark jni(this); 735 jni()->SetByteArrayRegion(array.as_jbyteArray(), index, 1, &value); 736 } 737 } 738 739 jint JVMCIEnv::get_int_at(JVMCIPrimitiveArray array, int index) { 740 if (is_hotspot()) { 741 return HotSpotJVMCI::resolve(array)->int_at(index); 742 } else { 743 JNIAccessMark jni(this); 744 jint result; 745 jni()->GetIntArrayRegion(array.as_jintArray(), index, 1, &result); 746 return result; 747 } 748 } 749 void JVMCIEnv::put_int_at(JVMCIPrimitiveArray array, int index, jint value) { 750 if (is_hotspot()) { 751 HotSpotJVMCI::resolve(array)->int_at_put(index, value); 752 } else { 753 JNIAccessMark jni(this); 754 jni()->SetIntArrayRegion(array.as_jintArray(), index, 1, &value); 755 } 756 } 757 758 jlong JVMCIEnv::get_long_at(JVMCIPrimitiveArray array, int index) { 759 if (is_hotspot()) { 760 return HotSpotJVMCI::resolve(array)->long_at(index); 761 } else { 762 JNIAccessMark jni(this); 763 jlong result; 764 jni()->GetLongArrayRegion(array.as_jlongArray(), index, 1, &result); 765 return result; 766 } 767 } 768 void JVMCIEnv::put_long_at(JVMCIPrimitiveArray array, int index, jlong value) { 769 if (is_hotspot()) { 770 HotSpotJVMCI::resolve(array)->long_at_put(index, value); 771 } else { 772 JNIAccessMark jni(this); 773 jni()->SetLongArrayRegion(array.as_jlongArray(), index, 1, &value); 774 } 775 } 776 777 void JVMCIEnv::copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, jsize length) { 778 if (length == 0) { 779 return; 780 } 781 if (is_hotspot()) { 782 memcpy(dest, HotSpotJVMCI::resolve(src)->byte_at_addr(offset), length); 783 } else { 784 JNIAccessMark jni(this); 785 jni()->GetByteArrayRegion(src.as_jbyteArray(), offset, length, dest); 786 } 787 } 788 void JVMCIEnv::copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, jsize length) { 789 if (length == 0) { 790 return; 791 } 792 if (is_hotspot()) { 793 memcpy(HotSpotJVMCI::resolve(dest)->byte_at_addr(offset), src, length); 794 } else { 795 JNIAccessMark jni(this); 796 jni()->SetByteArrayRegion(dest.as_jbyteArray(), offset, length, src); 797 } 798 } 799 800 void JVMCIEnv::copy_longs_from(jlong* src, JVMCIPrimitiveArray dest, int offset, jsize length) { 801 if (length == 0) { 802 return; 803 } 804 if (is_hotspot()) { 805 memcpy(HotSpotJVMCI::resolve(dest)->long_at_addr(offset), src, length * sizeof(jlong)); 806 } else { 807 JNIAccessMark jni(this); 808 jni()->SetLongArrayRegion(dest.as_jlongArray(), offset, length, src); 809 } 810 } 811 812 jboolean JVMCIEnv::is_boxing_object(BasicType type, JVMCIObject object) { 813 if (is_hotspot()) { 814 return java_lang_boxing_object::is_instance(HotSpotJVMCI::resolve(object), type); 815 } else { 816 JNIAccessMark jni(this); 817 return jni()->IsInstanceOf(get_jobject(object), JNIJVMCI::box_class(type)); 818 } 819 } 820 821 // Get the primitive value from a Java boxing object. It's hard error to 822 // pass a non-primitive BasicType. 823 jvalue JVMCIEnv::get_boxed_value(BasicType type, JVMCIObject object) { 824 jvalue result; 825 if (is_hotspot()) { 826 if (java_lang_boxing_object::get_value(HotSpotJVMCI::resolve(object), &result) == T_ILLEGAL) { 827 ShouldNotReachHere(); 828 } 829 } else { 830 JNIAccessMark jni(this); 831 jfieldID field = JNIJVMCI::box_field(type); 832 switch (type) { 833 case T_BOOLEAN: result.z = jni()->GetBooleanField(get_jobject(object), field); break; 834 case T_BYTE: result.b = jni()->GetByteField(get_jobject(object), field); break; 835 case T_SHORT: result.s = jni()->GetShortField(get_jobject(object), field); break; 836 case T_CHAR: result.c = jni()->GetCharField(get_jobject(object), field); break; 837 case T_INT: result.i = jni()->GetIntField(get_jobject(object), field); break; 838 case T_LONG: result.j = jni()->GetLongField(get_jobject(object), field); break; 839 case T_FLOAT: result.f = jni()->GetFloatField(get_jobject(object), field); break; 840 case T_DOUBLE: result.d = jni()->GetDoubleField(get_jobject(object), field); break; 841 default: 842 ShouldNotReachHere(); 843 } 844 } 845 return result; 846 } 847 848 // Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL. 849 BasicType JVMCIEnv::get_box_type(JVMCIObject object) { 850 if (is_hotspot()) { 851 return java_lang_boxing_object::basic_type(HotSpotJVMCI::resolve(object)); 852 } else { 853 JNIAccessMark jni(this); 854 jclass clazz = jni()->GetObjectClass(get_jobject(object)); 855 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BOOLEAN))) return T_BOOLEAN; 856 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_BYTE))) return T_BYTE; 857 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_SHORT))) return T_SHORT; 858 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_CHAR))) return T_CHAR; 859 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_INT))) return T_INT; 860 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_LONG))) return T_LONG; 861 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_FLOAT))) return T_FLOAT; 862 if (jni()->IsSameObject(clazz, JNIJVMCI::box_class(T_DOUBLE))) return T_DOUBLE; 863 return T_ILLEGAL; 864 } 865 } 866 867 // Create a boxing object of the appropriate primitive type. 868 JVMCIObject JVMCIEnv::create_box(BasicType type, jvalue* value, JVMCI_TRAPS) { 869 switch (type) { 870 case T_BOOLEAN: 871 case T_BYTE: 872 case T_CHAR: 873 case T_SHORT: 874 case T_INT: 875 case T_LONG: 876 case T_FLOAT: 877 case T_DOUBLE: 878 break; 879 default: 880 JVMCI_THROW_MSG_(IllegalArgumentException, "Only boxes for primitive values can be created", JVMCIObject()); 881 } 882 JavaThread* THREAD = JavaThread::current(); // For exception macros. 883 if (is_hotspot()) { 884 oop box = java_lang_boxing_object::create(type, value, CHECK_(JVMCIObject())); 885 return HotSpotJVMCI::wrap(box); 886 } else { 887 JNIAccessMark jni(this, THREAD); 888 jobject box = jni()->NewObjectA(JNIJVMCI::box_class(type), JNIJVMCI::box_constructor(type), value); 889 assert(box != nullptr, ""); 890 return wrap(box); 891 } 892 } 893 894 const char* JVMCIEnv::as_utf8_string(JVMCIObject str) { 895 if (is_hotspot()) { 896 return java_lang_String::as_utf8_string(HotSpotJVMCI::resolve(str)); 897 } else { 898 JNIAccessMark jni(this); 899 jstring jstr = str.as_jstring(); 900 int length = jni()->GetStringLength(jstr); 901 int utf8_length = jni()->GetStringUTFLength(jstr); 902 char* result = NEW_RESOURCE_ARRAY(char, utf8_length + 1); 903 jni()->GetStringUTFRegion(jstr, 0, length, result); 904 return result; 905 } 906 } 907 908 #define DO_THROW(name) \ 909 void JVMCIEnv::throw_##name(const char* msg) { \ 910 if (is_hotspot()) { \ 911 JavaThread* THREAD = JavaThread::current(); \ 912 THROW_MSG(HotSpotJVMCI::name::symbol(), msg); \ 913 } else { \ 914 JNIAccessMark jni(this); \ 915 jni()->ThrowNew(JNIJVMCI::name::clazz(), msg); \ 916 } \ 917 } 918 919 DO_THROW(InternalError) 920 DO_THROW(ArrayIndexOutOfBoundsException) 921 DO_THROW(IllegalStateException) 922 DO_THROW(NullPointerException) 923 DO_THROW(IllegalArgumentException) 924 DO_THROW(InvalidInstalledCodeException) 925 DO_THROW(UnsatisfiedLinkError) 926 DO_THROW(UnsupportedOperationException) 927 DO_THROW(OutOfMemoryError) 928 DO_THROW(NoClassDefFoundError) 929 930 #undef DO_THROW 931 932 void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) { 933 const int max_msg_size = 1024; 934 va_list ap; 935 va_start(ap, format); 936 char msg[max_msg_size]; 937 os::vsnprintf(msg, max_msg_size, format, ap); 938 va_end(ap); 939 JavaThread* THREAD = JavaThread::current(); 940 if (is_hotspot()) { 941 Handle h_loader; 942 Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader ); 943 } else { 944 JNIAccessMark jni(this, THREAD); 945 jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg); 946 } 947 } 948 949 jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isGCSupported (JVMCIObject runtime, jint gcIdentifier) { 950 JavaThread* THREAD = JavaThread::current(); // For exception macros. 951 if (is_hotspot()) { 952 JavaCallArguments jargs; 953 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 954 jargs.push_int(gcIdentifier); 955 JavaValue result(T_BOOLEAN); 956 JavaCalls::call_special(&result, 957 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 958 vmSymbols::isGCSupported_name(), 959 vmSymbols::int_bool_signature(), &jargs, CHECK_0); 960 return result.get_jboolean(); 961 } else { 962 JNIAccessMark jni(this, THREAD); 963 jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(), 964 JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 965 JNIJVMCI::HotSpotJVMCIRuntime::isGCSupported_method(), 966 gcIdentifier); 967 if (jni()->ExceptionCheck()) { 968 return false; 969 } 970 return result; 971 } 972 } 973 974 jboolean JVMCIEnv::call_HotSpotJVMCIRuntime_isIntrinsicSupported (JVMCIObject runtime, jint intrinsicIdentifier) { 975 JavaThread* THREAD = JavaThread::current(); // For exception macros. 976 if (is_hotspot()) { 977 JavaCallArguments jargs; 978 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 979 jargs.push_int(intrinsicIdentifier); 980 JavaValue result(T_BOOLEAN); 981 JavaCalls::call_special(&result, 982 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 983 vmSymbols::isIntrinsicSupported_name(), 984 vmSymbols::int_bool_signature(), &jargs, CHECK_0); 985 return result.get_jboolean(); 986 } else { 987 JNIAccessMark jni(this, THREAD); 988 jboolean result = jni()->CallNonvirtualBooleanMethod(runtime.as_jobject(), 989 JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 990 JNIJVMCI::HotSpotJVMCIRuntime::isIntrinsicSupported_method(), 991 intrinsicIdentifier); 992 if (jni()->ExceptionCheck()) { 993 return false; 994 } 995 return result; 996 } 997 } 998 999 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci, 1000 jlong compile_state, int id) { 1001 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1002 if (is_hotspot()) { 1003 JavaCallArguments jargs; 1004 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 1005 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method))); 1006 jargs.push_int(entry_bci); 1007 jargs.push_long(compile_state); 1008 jargs.push_int(id); 1009 JavaValue result(T_OBJECT); 1010 JavaCalls::call_special(&result, 1011 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 1012 vmSymbols::compileMethod_name(), 1013 vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject())); 1014 return wrap(result.get_oop()); 1015 } else { 1016 JNIAccessMark jni(this, THREAD); 1017 jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(), 1018 JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 1019 JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(), 1020 method.as_jobject(), entry_bci, compile_state, id); 1021 if (jni()->ExceptionCheck()) { 1022 return JVMCIObject(); 1023 } 1024 return wrap(result); 1025 } 1026 } 1027 1028 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) { 1029 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1030 if (is_hotspot()) { 1031 JavaCallArguments jargs; 1032 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 1033 JavaValue result(T_VOID); 1034 JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK); 1035 } else { 1036 JNIAccessMark jni(this, THREAD); 1037 jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method()); 1038 1039 } 1040 } 1041 1042 void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) { 1043 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1044 HandleMark hm(THREAD); 1045 if (is_hotspot()) { 1046 JavaCallArguments jargs; 1047 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 1048 JavaValue result(T_VOID); 1049 JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::shutdown_name(), vmSymbols::void_method_signature(), &jargs, THREAD); 1050 } else { 1051 JNIAccessMark jni(this, THREAD); 1052 jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::shutdown_method()); 1053 } 1054 if (has_pending_exception()) { 1055 // This should never happen as HotSpotJVMCIRuntime.shutdown() should 1056 // handle all exceptions. 1057 describe_pending_exception(tty); 1058 } 1059 } 1060 1061 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) { 1062 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1063 if (is_hotspot()) { 1064 JavaCallArguments jargs; 1065 JavaValue result(T_OBJECT); 1066 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::runtime_name(), vmSymbols::runtime_signature(), &jargs, CHECK_(JVMCIObject())); 1067 return wrap(result.get_oop()); 1068 } else { 1069 JNIAccessMark jni(this, THREAD); 1070 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::runtime_method()); 1071 if (jni()->ExceptionCheck()) { 1072 return JVMCIObject(); 1073 } 1074 return wrap(result); 1075 } 1076 } 1077 1078 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) { 1079 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1080 if (is_hotspot()) { 1081 JavaCallArguments jargs; 1082 JavaValue result(T_OBJECT); 1083 JavaCalls::call_static(&result, HotSpotJVMCI::JVMCI::klass(), vmSymbols::getRuntime_name(), vmSymbols::getRuntime_signature(), &jargs, CHECK_(JVMCIObject())); 1084 return wrap(result.get_oop()); 1085 } else { 1086 JNIAccessMark jni(this, THREAD); 1087 jobject result = jni()->CallStaticObjectMethod(JNIJVMCI::JVMCI::clazz(), JNIJVMCI::JVMCI::getRuntime_method()); 1088 if (jni()->ExceptionCheck()) { 1089 return JVMCIObject(); 1090 } 1091 return wrap(result); 1092 } 1093 } 1094 1095 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) { 1096 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1097 if (is_hotspot()) { 1098 JavaCallArguments jargs; 1099 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime))); 1100 JavaValue result(T_OBJECT); 1101 JavaCalls::call_virtual(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::getCompiler_name(), vmSymbols::getCompiler_signature(), &jargs, CHECK_(JVMCIObject())); 1102 return wrap(result.get_oop()); 1103 } else { 1104 JNIAccessMark jni(this, THREAD); 1105 jobject result = jni()->CallObjectMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::getCompiler_method()); 1106 if (jni()->ExceptionCheck()) { 1107 return JVMCIObject(); 1108 } 1109 return wrap(result); 1110 } 1111 } 1112 1113 void JVMCIEnv::call_HotSpotJVMCIRuntime_postTranslation(JVMCIObject object, JVMCIEnv* JVMCIENV) { 1114 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1115 if (is_hotspot()) { 1116 JavaCallArguments jargs; 1117 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object))); 1118 JavaValue result(T_VOID); 1119 JavaCalls::call_static(&result, 1120 HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), 1121 vmSymbols::postTranslation_name(), 1122 vmSymbols::object_void_signature(), &jargs, CHECK); 1123 } else { 1124 JNIAccessMark jni(this, THREAD); 1125 jni()->CallStaticVoidMethod(JNIJVMCI::HotSpotJVMCIRuntime::clazz(), 1126 JNIJVMCI::HotSpotJVMCIRuntime::postTranslation_method(), 1127 object.as_jobject()); 1128 } 1129 } 1130 1131 JVMCIObject JVMCIEnv::call_JavaConstant_forPrimitive(jchar type_char, jlong value, JVMCI_TRAPS) { 1132 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1133 if (is_hotspot()) { 1134 JavaCallArguments jargs; 1135 jargs.push_int(type_char); 1136 jargs.push_long(value); 1137 JavaValue result(T_OBJECT); 1138 JavaCalls::call_static(&result, 1139 HotSpotJVMCI::JavaConstant::klass(), 1140 vmSymbols::forPrimitive_name(), 1141 vmSymbols::forPrimitive_signature(), &jargs, CHECK_(JVMCIObject())); 1142 return wrap(result.get_oop()); 1143 } else { 1144 JNIAccessMark jni(this, THREAD); 1145 jobject result = (jstring) jni()->CallStaticObjectMethod(JNIJVMCI::JavaConstant::clazz(), 1146 JNIJVMCI::JavaConstant::forPrimitive_method(), 1147 type_char, value); 1148 if (jni()->ExceptionCheck()) { 1149 return JVMCIObject(); 1150 } 1151 return wrap(result); 1152 } 1153 } 1154 1155 JVMCIObject JVMCIEnv::get_jvmci_primitive_type(BasicType type) { 1156 JVMCIObjectArray primitives = get_HotSpotResolvedPrimitiveType_primitives(); 1157 JVMCIObject result = get_object_at(primitives, type); 1158 return result; 1159 } 1160 1161 JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS) { 1162 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1163 Symbol* file_name_sym; 1164 int line_number; 1165 java_lang_StackTraceElement::decode(method, bci, file_name_sym, line_number, CHECK_(JVMCIObject())); 1166 1167 Symbol* method_name_sym = method->name(); 1168 InstanceKlass* holder = method->method_holder(); 1169 const char* declaring_class_str = holder->external_name(); 1170 1171 if (is_hotspot()) { 1172 HotSpotJVMCI::StackTraceElement::klass()->initialize(CHECK_(JVMCIObject())); 1173 oop objOop = HotSpotJVMCI::StackTraceElement::klass()->allocate_instance(CHECK_(JVMCIObject())); 1174 Handle obj = Handle(THREAD, objOop); 1175 1176 oop declaring_class = StringTable::intern((char*) declaring_class_str, CHECK_(JVMCIObject())); 1177 HotSpotJVMCI::StackTraceElement::set_declaringClass(this, obj(), declaring_class); 1178 1179 oop method_name = StringTable::intern(method_name_sym, CHECK_(JVMCIObject())); 1180 HotSpotJVMCI::StackTraceElement::set_methodName(this, obj(), method_name); 1181 1182 if (file_name_sym != nullptr) { 1183 oop file_name = StringTable::intern(file_name_sym, CHECK_(JVMCIObject())); 1184 HotSpotJVMCI::StackTraceElement::set_fileName(this, obj(), file_name); 1185 } 1186 HotSpotJVMCI::StackTraceElement::set_lineNumber(this, obj(), line_number); 1187 return wrap(obj()); 1188 } else { 1189 JNIAccessMark jni(this, THREAD); 1190 jobject declaring_class = jni()->NewStringUTF(declaring_class_str); 1191 if (jni()->ExceptionCheck()) { 1192 return JVMCIObject(); 1193 } 1194 jobject method_name = jni()->NewStringUTF(method_name_sym->as_C_string()); 1195 if (jni()->ExceptionCheck()) { 1196 return JVMCIObject(); 1197 } 1198 jobject file_name = nullptr; 1199 if (file_name_sym != nullptr) { 1200 file_name = jni()->NewStringUTF(file_name_sym->as_C_string()); 1201 if (jni()->ExceptionCheck()) { 1202 return JVMCIObject(); 1203 } 1204 } 1205 1206 jobject result = jni()->NewObject(JNIJVMCI::StackTraceElement::clazz(), 1207 JNIJVMCI::StackTraceElement::constructor(), 1208 declaring_class, method_name, file_name, line_number); 1209 return wrap(result); 1210 } 1211 } 1212 1213 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) { 1214 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1215 1216 JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject())); 1217 1218 if (is_hotspot()) { 1219 InstanceKlass* ik = InstanceKlass::cast(HotSpotJVMCI::HotSpotNmethod::klass()); 1220 if (ik->should_be_initialized()) { 1221 ik->initialize(CHECK_(JVMCIObject())); 1222 } 1223 oop obj = ik->allocate_instance(CHECK_(JVMCIObject())); 1224 Handle obj_h(THREAD, obj); 1225 Handle nameStr = java_lang_String::create_from_str(name, CHECK_(JVMCIObject())); 1226 1227 // Call constructor 1228 JavaCallArguments jargs; 1229 jargs.push_oop(obj_h); 1230 jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(methodObject))); 1231 jargs.push_oop(nameStr); 1232 jargs.push_int(isDefault); 1233 jargs.push_long(compileId); 1234 JavaValue result(T_VOID); 1235 JavaCalls::call_special(&result, ik, 1236 vmSymbols::object_initializer_name(), 1237 vmSymbols::method_string_bool_long_signature(), 1238 &jargs, CHECK_(JVMCIObject())); 1239 return wrap(obj_h()); 1240 } else { 1241 JNIAccessMark jni(this, THREAD); 1242 jobject nameStr = name == nullptr ? nullptr : jni()->NewStringUTF(name); 1243 if (jni()->ExceptionCheck()) { 1244 return JVMCIObject(); 1245 } 1246 1247 jobject result = jni()->NewObject(JNIJVMCI::HotSpotNmethod::clazz(), 1248 JNIJVMCI::HotSpotNmethod::constructor(), 1249 methodObject.as_jobject(), nameStr, isDefault); 1250 return wrap(result); 1251 } 1252 } 1253 1254 JVMCIObject JVMCIEnv::make_local(JVMCIObject object) { 1255 if (object.is_null()) { 1256 return JVMCIObject(); 1257 } 1258 if (is_hotspot()) { 1259 return wrap(JNIHandles::make_local(HotSpotJVMCI::resolve(object))); 1260 } else { 1261 JNIAccessMark jni(this); 1262 return wrap(jni()->NewLocalRef(object.as_jobject())); 1263 } 1264 } 1265 1266 JVMCIObject JVMCIEnv::make_global(JVMCIObject object) { 1267 if (object.is_null()) { 1268 return JVMCIObject(); 1269 } 1270 if (is_hotspot()) { 1271 return wrap(JNIHandles::make_global(Handle(Thread::current(), HotSpotJVMCI::resolve(object)))); 1272 } else { 1273 JNIAccessMark jni(this); 1274 return wrap(jni()->NewGlobalRef(object.as_jobject())); 1275 } 1276 } 1277 1278 void JVMCIEnv::destroy_local(JVMCIObject object) { 1279 if (is_hotspot()) { 1280 JNIHandles::destroy_local(object.as_jobject()); 1281 } else { 1282 JNIAccessMark jni(this); 1283 jni()->DeleteLocalRef(object.as_jobject()); 1284 } 1285 } 1286 1287 void JVMCIEnv::destroy_global(JVMCIObject object) { 1288 if (is_hotspot()) { 1289 JNIHandles::destroy_global(object.as_jobject()); 1290 } else { 1291 JNIAccessMark jni(this); 1292 jni()->DeleteGlobalRef(object.as_jobject()); 1293 } 1294 } 1295 1296 const char* JVMCIEnv::klass_name(JVMCIObject object) { 1297 if (is_hotspot()) { 1298 return HotSpotJVMCI::resolve(object)->klass()->signature_name(); 1299 } else { 1300 JVMCIObject name; 1301 { 1302 JNIAccessMark jni(this); 1303 jclass jcl = jni()->GetObjectClass(object.as_jobject()); 1304 jobject result = jni()->CallObjectMethod(jcl, JNIJVMCI::Class_getName_method()); 1305 name = JVMCIObject::create(result, is_hotspot()); 1306 } 1307 return as_utf8_string(name); 1308 } 1309 } 1310 1311 JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS) { 1312 JVMCIObject method_object; 1313 if (method() == nullptr) { 1314 return method_object; 1315 } 1316 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1317 JVMCIKlassHandle holder_klass(THREAD, method->method_holder()); 1318 JVMCIObject holder = get_jvmci_type(holder_klass, JVMCI_CHECK_(JVMCIObject())); 1319 1320 CompilerOracle::tag_blackhole_if_possible(method); 1321 1322 jmetadata handle = _runtime->allocate_handle(method); 1323 jboolean exception = false; 1324 if (is_hotspot()) { 1325 JavaValue result(T_OBJECT); 1326 JavaCallArguments args; 1327 args.push_long((jlong) handle); 1328 args.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(holder))); 1329 JavaCalls::call_static(&result, HotSpotJVMCI::HotSpotResolvedJavaMethodImpl::klass(), 1330 vmSymbols::fromMetaspace_name(), 1331 vmSymbols::method_fromMetaspace_signature(), &args, THREAD); 1332 if (HAS_PENDING_EXCEPTION) { 1333 exception = true; 1334 } else { 1335 method_object = wrap(result.get_oop()); 1336 } 1337 } else { 1338 JNIAccessMark jni(this, THREAD); 1339 method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(), 1340 JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(), 1341 (jlong) handle, holder.as_jobject())); 1342 exception = jni()->ExceptionCheck(); 1343 } 1344 1345 if (exception) { 1346 _runtime->release_handle(handle); 1347 return JVMCIObject(); 1348 } 1349 1350 assert(asMethod(method_object) == method(), "must be"); 1351 if (get_HotSpotResolvedJavaMethodImpl_methodHandle(method_object) != (jlong) handle) { 1352 _runtime->release_handle(handle); 1353 } 1354 assert(!method_object.is_null(), "must be"); 1355 return method_object; 1356 } 1357 1358 JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS) { 1359 JVMCIObject type; 1360 if (klass.is_null()) { 1361 return type; 1362 } 1363 1364 guarantee(klass->is_klass(), "must be valid klass"); 1365 guarantee(klass->is_loader_alive(), "klass must be alive"); 1366 1367 jlong pointer = (jlong) klass(); 1368 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1369 jboolean exception = false; 1370 if (is_hotspot()) { 1371 CompilerThreadCanCallJava ccj(THREAD, true); 1372 JavaValue result(T_OBJECT); 1373 JavaCallArguments args; 1374 args.push_long(pointer); 1375 JavaCalls::call_static(&result, 1376 HotSpotJVMCI::HotSpotResolvedObjectTypeImpl::klass(), 1377 vmSymbols::fromMetaspace_name(), 1378 vmSymbols::klass_fromMetaspace_signature(), &args, THREAD); 1379 1380 if (HAS_PENDING_EXCEPTION) { 1381 exception = true; 1382 } else { 1383 type = wrap(result.get_oop()); 1384 } 1385 } else { 1386 JNIAccessMark jni(this, THREAD); 1387 1388 HandleMark hm(THREAD); 1389 type = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedObjectTypeImpl::clazz(), 1390 JNIJVMCI::HotSpotResolvedObjectTypeImpl_fromMetaspace_method(), 1391 pointer)); 1392 exception = jni()->ExceptionCheck(); 1393 } 1394 if (exception) { 1395 return JVMCIObject(); 1396 } 1397 1398 assert(type.is_non_null(), "must have result"); 1399 return type; 1400 } 1401 1402 JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS) { 1403 JVMCIObject cp_object; 1404 jmetadata handle = _runtime->allocate_handle(cp); 1405 jboolean exception = false; 1406 JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current()); // For exception macros. 1407 if (is_hotspot()) { 1408 JavaValue result(T_OBJECT); 1409 JavaCallArguments args; 1410 args.push_long((jlong) handle); 1411 JavaCalls::call_static(&result, 1412 HotSpotJVMCI::HotSpotConstantPool::klass(), 1413 vmSymbols::fromMetaspace_name(), 1414 vmSymbols::constantPool_fromMetaspace_signature(), &args, THREAD); 1415 if (HAS_PENDING_EXCEPTION) { 1416 exception = true; 1417 } else { 1418 cp_object = wrap(result.get_oop()); 1419 } 1420 } else { 1421 JNIAccessMark jni(this, THREAD); 1422 cp_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotConstantPool::clazz(), 1423 JNIJVMCI::HotSpotConstantPool_fromMetaspace_method(), 1424 (jlong) handle)); 1425 exception = jni()->ExceptionCheck(); 1426 } 1427 1428 if (exception) { 1429 _runtime->release_handle(handle); 1430 return JVMCIObject(); 1431 } 1432 1433 assert(!cp_object.is_null(), "must be"); 1434 // Constant pools aren't cached so this is always a newly created object using the handle 1435 assert(get_HotSpotConstantPool_constantPoolHandle(cp_object) == (jlong) handle, "must use same handle"); 1436 return cp_object; 1437 } 1438 1439 JVMCIPrimitiveArray JVMCIEnv::new_booleanArray(int length, JVMCI_TRAPS) { 1440 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1441 if (is_hotspot()) { 1442 typeArrayOop result = oopFactory::new_boolArray(length, CHECK_(JVMCIObject())); 1443 return wrap(result); 1444 } else { 1445 JNIAccessMark jni(this, THREAD); 1446 jbooleanArray result = jni()->NewBooleanArray(length); 1447 return wrap(result); 1448 } 1449 } 1450 1451 JVMCIPrimitiveArray JVMCIEnv::new_byteArray(int length, JVMCI_TRAPS) { 1452 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1453 if (is_hotspot()) { 1454 typeArrayOop result = oopFactory::new_byteArray(length, CHECK_(JVMCIObject())); 1455 return wrap(result); 1456 } else { 1457 JNIAccessMark jni(this, THREAD); 1458 jbyteArray result = jni()->NewByteArray(length); 1459 return wrap(result); 1460 } 1461 } 1462 1463 JVMCIObjectArray JVMCIEnv::new_byte_array_array(int length, JVMCI_TRAPS) { 1464 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1465 if (is_hotspot()) { 1466 Klass* byteArrayArrayKlass = TypeArrayKlass::cast(Universe::byteArrayKlass())->array_klass(CHECK_(JVMCIObject())); 1467 objArrayOop result = ObjArrayKlass::cast(byteArrayArrayKlass) ->allocate(length, CHECK_(JVMCIObject())); 1468 return wrap(result); 1469 } else { 1470 JNIAccessMark jni(this, THREAD); 1471 jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::byte_array(), nullptr); 1472 return wrap(result); 1473 } 1474 } 1475 1476 JVMCIPrimitiveArray JVMCIEnv::new_intArray(int length, JVMCI_TRAPS) { 1477 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1478 if (is_hotspot()) { 1479 typeArrayOop result = oopFactory::new_intArray(length, CHECK_(JVMCIObject())); 1480 return wrap(result); 1481 } else { 1482 JNIAccessMark jni(this, THREAD); 1483 jintArray result = jni()->NewIntArray(length); 1484 return wrap(result); 1485 } 1486 } 1487 1488 JVMCIPrimitiveArray JVMCIEnv::new_longArray(int length, JVMCI_TRAPS) { 1489 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1490 if (is_hotspot()) { 1491 typeArrayOop result = oopFactory::new_longArray(length, CHECK_(JVMCIObject())); 1492 return wrap(result); 1493 } else { 1494 JNIAccessMark jni(this, THREAD); 1495 jlongArray result = jni()->NewLongArray(length); 1496 return wrap(result); 1497 } 1498 } 1499 1500 JVMCIObject JVMCIEnv::new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS) { 1501 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1502 if (is_hotspot()) { 1503 HotSpotJVMCI::VMField::klass()->initialize(CHECK_(JVMCIObject())); 1504 oop obj = HotSpotJVMCI::VMField::klass()->allocate_instance(CHECK_(JVMCIObject())); 1505 HotSpotJVMCI::VMField::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1506 HotSpotJVMCI::VMField::set_type(this, obj, HotSpotJVMCI::resolve(type)); 1507 HotSpotJVMCI::VMField::set_offset(this, obj, offset); 1508 HotSpotJVMCI::VMField::set_address(this, obj, address); 1509 HotSpotJVMCI::VMField::set_value(this, obj, HotSpotJVMCI::resolve(value)); 1510 return wrap(obj); 1511 } else { 1512 JNIAccessMark jni(this, THREAD); 1513 jobject result = jni()->NewObject(JNIJVMCI::VMField::clazz(), 1514 JNIJVMCI::VMField::constructor(), 1515 get_jobject(name), get_jobject(type), offset, address, get_jobject(value)); 1516 return wrap(result); 1517 } 1518 } 1519 1520 JVMCIObject JVMCIEnv::new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS) { 1521 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1522 if (is_hotspot()) { 1523 HotSpotJVMCI::VMFlag::klass()->initialize(CHECK_(JVMCIObject())); 1524 oop obj = HotSpotJVMCI::VMFlag::klass()->allocate_instance(CHECK_(JVMCIObject())); 1525 HotSpotJVMCI::VMFlag::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1526 HotSpotJVMCI::VMFlag::set_type(this, obj, HotSpotJVMCI::resolve(type)); 1527 HotSpotJVMCI::VMFlag::set_value(this, obj, HotSpotJVMCI::resolve(value)); 1528 return wrap(obj); 1529 } else { 1530 JNIAccessMark jni(this, THREAD); 1531 jobject result = jni()->NewObject(JNIJVMCI::VMFlag::clazz(), 1532 JNIJVMCI::VMFlag::constructor(), 1533 get_jobject(name), get_jobject(type), get_jobject(value)); 1534 return wrap(result); 1535 } 1536 } 1537 1538 JVMCIObject JVMCIEnv::new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, jboolean isAvailable, jboolean c1Supported, jboolean c2Supported, JVMCI_TRAPS) { 1539 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1540 if (is_hotspot()) { 1541 HotSpotJVMCI::VMIntrinsicMethod::klass()->initialize(CHECK_(JVMCIObject())); 1542 oop obj = HotSpotJVMCI::VMIntrinsicMethod::klass()->allocate_instance(CHECK_(JVMCIObject())); 1543 HotSpotJVMCI::VMIntrinsicMethod::set_declaringClass(this, obj, HotSpotJVMCI::resolve(declaringClass)); 1544 HotSpotJVMCI::VMIntrinsicMethod::set_name(this, obj, HotSpotJVMCI::resolve(name)); 1545 HotSpotJVMCI::VMIntrinsicMethod::set_descriptor(this, obj, HotSpotJVMCI::resolve(descriptor)); 1546 HotSpotJVMCI::VMIntrinsicMethod::set_id(this, obj, id); 1547 HotSpotJVMCI::VMIntrinsicMethod::set_isAvailable(this, obj, isAvailable); 1548 HotSpotJVMCI::VMIntrinsicMethod::set_c1Supported(this, obj, c1Supported); 1549 HotSpotJVMCI::VMIntrinsicMethod::set_c2Supported(this, obj, c2Supported); 1550 return wrap(obj); 1551 } else { 1552 JNIAccessMark jni(this, THREAD); 1553 jobject result = jni()->NewObject(JNIJVMCI::VMIntrinsicMethod::clazz(), 1554 JNIJVMCI::VMIntrinsicMethod::constructor(), 1555 get_jobject(declaringClass), get_jobject(name), get_jobject(descriptor), id, isAvailable, c1Supported, c2Supported); 1556 return wrap(result); 1557 } 1558 } 1559 1560 JVMCIObject JVMCIEnv::new_HotSpotStackFrameReference(JVMCI_TRAPS) { 1561 if (is_hotspot()) { 1562 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1563 HotSpotJVMCI::HotSpotStackFrameReference::klass()->initialize(CHECK_(JVMCIObject())); 1564 oop obj = HotSpotJVMCI::HotSpotStackFrameReference::klass()->allocate_instance(CHECK_(JVMCIObject())); 1565 return wrap(obj); 1566 } else { 1567 ShouldNotReachHere(); 1568 return JVMCIObject(); 1569 } 1570 } 1571 JVMCIObject JVMCIEnv::new_JVMCIError(JVMCI_TRAPS) { 1572 if (is_hotspot()) { 1573 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1574 HotSpotJVMCI::JVMCIError::klass()->initialize(CHECK_(JVMCIObject())); 1575 oop obj = HotSpotJVMCI::JVMCIError::klass()->allocate_instance(CHECK_(JVMCIObject())); 1576 return wrap(obj); 1577 } else { 1578 ShouldNotReachHere(); 1579 return JVMCIObject(); 1580 } 1581 } 1582 1583 JVMCIObject JVMCIEnv::new_FieldInfo(FieldInfo* fieldinfo, JVMCI_TRAPS) { 1584 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1585 if (is_hotspot()) { 1586 HotSpotJVMCI::FieldInfo::klass()->initialize(CHECK_(JVMCIObject())); 1587 oop obj = HotSpotJVMCI::FieldInfo::klass()->allocate_instance(CHECK_(JVMCIObject())); 1588 Handle obj_h(THREAD, obj); 1589 HotSpotJVMCI::FieldInfo::set_nameIndex(JVMCIENV, obj_h(), (jint)fieldinfo->name_index()); 1590 HotSpotJVMCI::FieldInfo::set_signatureIndex(JVMCIENV, obj_h(), (jint)fieldinfo->signature_index()); 1591 HotSpotJVMCI::FieldInfo::set_offset(JVMCIENV, obj_h(), (jint)fieldinfo->offset()); 1592 HotSpotJVMCI::FieldInfo::set_classfileFlags(JVMCIENV, obj_h(), (jint)fieldinfo->access_flags().as_field_flags()); 1593 HotSpotJVMCI::FieldInfo::set_internalFlags(JVMCIENV, obj_h(), (jint)fieldinfo->field_flags().as_uint()); 1594 HotSpotJVMCI::FieldInfo::set_initializerIndex(JVMCIENV, obj_h(), (jint)fieldinfo->initializer_index()); 1595 return wrap(obj_h()); 1596 } else { 1597 JNIAccessMark jni(this, THREAD); 1598 jobject result = jni()->NewObject(JNIJVMCI::FieldInfo::clazz(), 1599 JNIJVMCI::FieldInfo::constructor(), 1600 (jint)fieldinfo->name_index(), 1601 (jint)fieldinfo->signature_index(), 1602 (jint)fieldinfo->offset(), 1603 (jint)fieldinfo->access_flags().as_field_flags(), 1604 (jint)fieldinfo->field_flags().as_uint(), 1605 (jint)fieldinfo->initializer_index()); 1606 1607 return wrap(result); 1608 } 1609 } 1610 1611 JVMCIObject JVMCIEnv::get_object_constant(oop objOop, bool compressed, bool dont_register) { 1612 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1613 Handle obj = Handle(THREAD, objOop); 1614 if (obj.is_null()) { 1615 return JVMCIObject(); 1616 } 1617 if (is_hotspot()) { 1618 HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->initialize(CHECK_(JVMCIObject())); 1619 oop constant = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::klass()->allocate_instance(CHECK_(JVMCIObject())); 1620 HotSpotJVMCI::DirectHotSpotObjectConstantImpl::set_object(this, constant, obj()); 1621 HotSpotJVMCI::HotSpotObjectConstantImpl::set_compressed(this, constant, compressed); 1622 return wrap(constant); 1623 } else { 1624 jlong handle = make_oop_handle(obj); 1625 JNIAccessMark jni(this, THREAD); 1626 jobject result = jni()->NewObject(JNIJVMCI::IndirectHotSpotObjectConstantImpl::clazz(), 1627 JNIJVMCI::IndirectHotSpotObjectConstantImpl::constructor(), 1628 handle, compressed, dont_register); 1629 return wrap(result); 1630 } 1631 } 1632 1633 1634 Handle JVMCIEnv::asConstant(JVMCIObject constant, JVMCI_TRAPS) { 1635 if (constant.is_null()) { 1636 return Handle(); 1637 } 1638 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1639 if (is_hotspot()) { 1640 assert(HotSpotJVMCI::DirectHotSpotObjectConstantImpl::is_instance(this, constant), "wrong type"); 1641 oop obj = HotSpotJVMCI::DirectHotSpotObjectConstantImpl::object(this, HotSpotJVMCI::resolve(constant)); 1642 return Handle(THREAD, obj); 1643 } else if (isa_IndirectHotSpotObjectConstantImpl(constant)) { 1644 jlong object_handle = get_IndirectHotSpotObjectConstantImpl_objectHandle(constant); 1645 if (object_handle == 0L) { 1646 JVMCI_THROW_MSG_(NullPointerException, "Foreign object reference has been cleared", Handle()); 1647 } 1648 oop result = resolve_oop_handle(object_handle); 1649 if (result == nullptr) { 1650 JVMCI_THROW_MSG_(InternalError, "Constant was unexpectedly null", Handle()); 1651 } 1652 return Handle(THREAD, result); 1653 } else { 1654 JVMCI_THROW_MSG_(IllegalArgumentException, "DirectHotSpotObjectConstantImpl shouldn't reach JVMCI in SVM mode", Handle()); 1655 } 1656 } 1657 1658 JVMCIObject JVMCIEnv::wrap(jobject object) { 1659 return JVMCIObject::create(object, is_hotspot()); 1660 } 1661 1662 jlong JVMCIEnv::make_oop_handle(const Handle& obj) { 1663 assert(!obj.is_null(), "should only create handle for non-null oops"); 1664 return _runtime->make_oop_handle(obj); 1665 } 1666 1667 oop JVMCIEnv::resolve_oop_handle(jlong oopHandle) { 1668 assert(oopHandle != 0, "should be a valid handle"); 1669 oop obj = NativeAccess<>::oop_load(reinterpret_cast<oop*>(oopHandle)); 1670 if (obj != nullptr) { 1671 guarantee(oopDesc::is_oop_or_null(obj), "invalid oop: " INTPTR_FORMAT, p2i((oopDesc*) obj)); 1672 } 1673 return obj; 1674 } 1675 1676 JVMCIObject JVMCIEnv::create_string(const char* str, JVMCI_TRAPS) { 1677 JavaThread* THREAD = JavaThread::current(); // For exception macros. 1678 if (is_hotspot()) { 1679 Handle result = java_lang_String::create_from_str(str, CHECK_(JVMCIObject())); 1680 return HotSpotJVMCI::wrap(result()); 1681 } else { 1682 jobject result; 1683 jboolean exception = false; 1684 { 1685 JNIAccessMark jni(this, THREAD); 1686 result = jni()->NewStringUTF(str); 1687 exception = jni()->ExceptionCheck(); 1688 } 1689 return wrap(result); 1690 } 1691 } 1692 1693 bool JVMCIEnv::equals(JVMCIObject a, JVMCIObject b) { 1694 if (is_hotspot()) { 1695 return HotSpotJVMCI::resolve(a) == HotSpotJVMCI::resolve(b); 1696 } else { 1697 JNIAccessMark jni(this); 1698 return jni()->IsSameObject(a.as_jobject(), b.as_jobject()) != 0; 1699 } 1700 } 1701 1702 BasicType JVMCIEnv::typeCharToBasicType(jchar ch, JVMCI_TRAPS) { 1703 switch(ch) { 1704 case 'Z': return T_BOOLEAN; 1705 case 'B': return T_BYTE; 1706 case 'S': return T_SHORT; 1707 case 'C': return T_CHAR; 1708 case 'I': return T_INT; 1709 case 'F': return T_FLOAT; 1710 case 'J': return T_LONG; 1711 case 'D': return T_DOUBLE; 1712 case 'A': return T_OBJECT; 1713 case '-': return T_ILLEGAL; 1714 default: 1715 JVMCI_ERROR_(T_ILLEGAL, "unexpected type char: %c", ch); 1716 } 1717 } 1718 1719 BasicType JVMCIEnv::kindToBasicType(JVMCIObject kind, JVMCI_TRAPS) { 1720 if (kind.is_null()) { 1721 JVMCI_THROW_(NullPointerException, T_ILLEGAL); 1722 } 1723 jchar ch = get_JavaKind_typeChar(kind); 1724 BasicType bt = typeCharToBasicType(ch, JVMCI_CHECK_(T_ILLEGAL)); 1725 return bt; 1726 } 1727 1728 void JVMCIEnv::initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS) { 1729 // Ensure that all updates to the InstalledCode fields are consistent. 1730 if (get_InstalledCode_address(installed_code) != 0) { 1731 JVMCI_THROW_MSG(InternalError, "InstalledCode instance already in use"); 1732 } 1733 if (!isa_HotSpotInstalledCode(installed_code)) { 1734 JVMCI_THROW_MSG(InternalError, "InstalledCode instance must be a subclass of HotSpotInstalledCode"); 1735 } 1736 1737 // Ignore the version which can stay at 0 1738 if (cb->is_nmethod()) { 1739 nmethod* nm = cb->as_nmethod_or_null(); 1740 if (nm->is_in_use()) { 1741 set_InstalledCode_entryPoint(installed_code, (jlong) nm->verified_entry_point()); 1742 } 1743 } else { 1744 set_InstalledCode_entryPoint(installed_code, (jlong) cb->code_begin()); 1745 } 1746 set_InstalledCode_address(installed_code, (jlong) cb); 1747 set_HotSpotInstalledCode_size(installed_code, cb->size()); 1748 set_HotSpotInstalledCode_codeStart(installed_code, (jlong) cb->code_begin()); 1749 set_HotSpotInstalledCode_codeSize(installed_code, cb->code_size()); 1750 } 1751 1752 1753 void JVMCIEnv::invalidate_nmethod_mirror(JVMCIObject mirror, bool deoptimize, JVMCI_TRAPS) { 1754 if (mirror.is_null()) { 1755 JVMCI_THROW(NullPointerException); 1756 } 1757 1758 Thread* current = Thread::current(); 1759 if (!mirror.is_hotspot() && !current->is_Java_thread()) { 1760 // Calling back into native might cause the execution to block, so only allow this when calling 1761 // from a JavaThread, which is the normal case anyway. 1762 JVMCI_THROW_MSG(IllegalArgumentException, 1763 "Cannot invalidate HotSpotNmethod object in shared library VM heap from non-JavaThread"); 1764 } 1765 1766 JavaThread* thread = JavaThread::cast(current); 1767 JVMCINMethodHandle nmethod_handle(thread); 1768 nmethod* nm = JVMCIENV->get_nmethod(mirror, nmethod_handle); 1769 if (nm == nullptr) { 1770 // Nothing to do 1771 return; 1772 } 1773 1774 if (!deoptimize) { 1775 // Prevent future executions of the nmethod but let current executions complete. 1776 nm->make_not_entrant("JVMCI invalidate nmethod mirror"); 1777 1778 // Do not clear the address field here as the Java code may still 1779 // want to later call this method with deoptimize == true. That requires 1780 // the address field to still be pointing at the nmethod. 1781 } else { 1782 // Deoptimize the nmethod immediately. 1783 DeoptimizationScope deopt_scope; 1784 deopt_scope.mark(nm); 1785 nm->make_not_entrant("JVMCI invalidate nmethod mirror"); 1786 nm->make_deoptimized(); 1787 deopt_scope.deoptimize_marked(); 1788 1789 // A HotSpotNmethod instance can only reference a single nmethod 1790 // during its lifetime so simply clear it here. 1791 set_InstalledCode_address(mirror, 0); 1792 } 1793 } 1794 1795 Klass* JVMCIEnv::asKlass(JVMCIObject obj) { 1796 return (Klass*) get_HotSpotResolvedObjectTypeImpl_klassPointer(obj); 1797 } 1798 1799 Method* JVMCIEnv::asMethod(JVMCIObject obj) { 1800 Method** methodHandle = (Method**) get_HotSpotResolvedJavaMethodImpl_methodHandle(obj); 1801 return *methodHandle; 1802 } 1803 1804 ConstantPool* JVMCIEnv::asConstantPool(JVMCIObject obj) { 1805 ConstantPool** constantPoolHandle = (ConstantPool**) get_HotSpotConstantPool_constantPoolHandle(obj); 1806 return *constantPoolHandle; 1807 } 1808 1809 MethodData* JVMCIEnv::asMethodData(JVMCIObject obj) { 1810 return (MethodData*) get_HotSpotMethodData_methodDataPointer(obj); 1811 } 1812 1813 // Lookup an nmethod with a matching base and compile id 1814 nmethod* JVMCIEnv::lookup_nmethod(address code, jlong compile_id_snapshot) { 1815 if (code == nullptr) { 1816 return nullptr; 1817 } 1818 1819 CodeBlob* cb = CodeCache::find_blob(code); 1820 if (cb == (CodeBlob*) code) { 1821 nmethod* nm = cb->as_nmethod_or_null(); 1822 if (nm != nullptr && (compile_id_snapshot == 0 || nm->compile_id() == compile_id_snapshot)) { 1823 return nm; 1824 } 1825 } 1826 return nullptr; 1827 } 1828 1829 1830 CodeBlob* JVMCIEnv::get_code_blob(JVMCIObject obj) { 1831 address code = (address) get_InstalledCode_address(obj); 1832 if (code == nullptr) { 1833 return nullptr; 1834 } 1835 if (isa_HotSpotNmethod(obj)) { 1836 jlong compile_id_snapshot = get_HotSpotNmethod_compileIdSnapshot(obj); 1837 nmethod* nm = lookup_nmethod(code, compile_id_snapshot); 1838 if (nm != nullptr && compile_id_snapshot != 0L && nm->is_not_entrant()) { 1839 // Zero the entry point so that the nmethod 1840 // cannot be invoked by the mirror but can 1841 // still be deoptimized. 1842 set_InstalledCode_entryPoint(obj, 0); 1843 // Refetch the nmethod since the previous call will be a safepoint in libjvmci 1844 nm = lookup_nmethod(code, compile_id_snapshot); 1845 } 1846 1847 if (nm == nullptr) { 1848 // The HotSpotNmethod was pointing at some nmethod but the nmethod is no longer valid, so 1849 // clear the InstalledCode fields of this HotSpotNmethod so that it no longer refers to a 1850 // nmethod in the code cache. 1851 set_InstalledCode_address(obj, 0); 1852 set_InstalledCode_entryPoint(obj, 0); 1853 set_HotSpotInstalledCode_codeStart(obj, 0); 1854 } 1855 return nm; 1856 } 1857 1858 CodeBlob* cb = (CodeBlob*) code; 1859 assert(!cb->is_nmethod(), "unexpected nmethod"); 1860 return cb; 1861 } 1862 1863 void JVMCINMethodHandle::set_nmethod(nmethod* nm) { 1864 BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); 1865 bs_nm->nmethod_entry_barrier(nm); 1866 _thread->set_live_nmethod(nm); 1867 } 1868 1869 nmethod* JVMCIEnv::get_nmethod(JVMCIObject obj, JVMCINMethodHandle& nmethod_handle) { 1870 CodeBlob* cb = get_code_blob(obj); 1871 if (cb != nullptr) { 1872 nmethod* nm = cb->as_nmethod_or_null(); 1873 if (nm != nullptr) { 1874 nmethod_handle.set_nmethod(nm); 1875 return nm; 1876 } 1877 } 1878 return nullptr; 1879 } 1880 1881 // Generate implementations for the initialize, new, isa, get and set methods for all the types and 1882 // fields declared in the JVMCI_CLASSES_DO macro. 1883 1884 #define START_CLASS(className, fullClassName) \ 1885 void JVMCIEnv::className##_initialize(JVMCI_TRAPS) { \ 1886 if (is_hotspot()) { \ 1887 HotSpotJVMCI::className::initialize(JVMCI_CHECK); \ 1888 } else { \ 1889 JNIJVMCI::className::initialize(JVMCI_CHECK); \ 1890 } \ 1891 } \ 1892 JVMCIObjectArray JVMCIEnv::new_##className##_array(int length, JVMCI_TRAPS) { \ 1893 if (is_hotspot()) { \ 1894 JavaThread* THREAD = JavaThread::current(); /* For exception macros. */ \ 1895 objArrayOop array = oopFactory::new_objArray(HotSpotJVMCI::className::klass(), length, CHECK_(JVMCIObject())); \ 1896 return (JVMCIObjectArray) wrap(array); \ 1897 } else { \ 1898 JNIAccessMark jni(this); \ 1899 jobjectArray result = jni()->NewObjectArray(length, JNIJVMCI::className::clazz(), nullptr); \ 1900 return wrap(result); \ 1901 } \ 1902 } \ 1903 bool JVMCIEnv::isa_##className(JVMCIObject object) { \ 1904 if (is_hotspot()) { \ 1905 return HotSpotJVMCI::className::is_instance(this, object); \ 1906 } else { \ 1907 return JNIJVMCI::className::is_instance(this, object); \ 1908 } \ 1909 } 1910 1911 #define END_CLASS 1912 1913 #define FIELD(className, name, type, accessor, cast) \ 1914 type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \ 1915 if (is_hotspot()) { \ 1916 return HotSpotJVMCI::className::get_##name(this, obj); \ 1917 } else { \ 1918 return JNIJVMCI::className::get_##name(this, obj); \ 1919 } \ 1920 } \ 1921 void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \ 1922 if (is_hotspot()) { \ 1923 HotSpotJVMCI::className::set_##name(this, obj, x); \ 1924 } else { \ 1925 JNIJVMCI::className::set_##name(this, obj, x); \ 1926 } \ 1927 } 1928 1929 #define EMPTY_CAST 1930 #define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST) 1931 #define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST) 1932 #define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 1933 #define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST) 1934 #define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST) 1935 1936 #define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST) 1937 #define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 1938 #define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray)) 1939 1940 #define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject)) 1941 #define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray)) 1942 1943 #define OOPISH_FIELD(className, name, type, accessor, cast) \ 1944 type JVMCIEnv::get_##className##_##name(JVMCIObject obj) { \ 1945 if (is_hotspot()) { \ 1946 return HotSpotJVMCI::className::get_##name(this, obj); \ 1947 } else { \ 1948 return JNIJVMCI::className::get_##name(this, obj); \ 1949 } \ 1950 } \ 1951 void JVMCIEnv::set_##className##_##name(JVMCIObject obj, type x) { \ 1952 if (is_hotspot()) { \ 1953 HotSpotJVMCI::className::set_##name(this, obj, x); \ 1954 } else { \ 1955 JNIJVMCI::className::set_##name(this, obj, x); \ 1956 } \ 1957 } 1958 1959 #define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \ 1960 type JVMCIEnv::get_##className##_##name() { \ 1961 if (is_hotspot()) { \ 1962 return HotSpotJVMCI::className::get_##name(this); \ 1963 } else { \ 1964 return JNIJVMCI::className::get_##name(this); \ 1965 } \ 1966 } \ 1967 void JVMCIEnv::set_##className##_##name(type x) { \ 1968 if (is_hotspot()) { \ 1969 HotSpotJVMCI::className::set_##name(this, x); \ 1970 } else { \ 1971 JNIJVMCI::className::set_##name(this, x); \ 1972 } \ 1973 } 1974 1975 #define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \ 1976 type JVMCIEnv::get_##className##_##name() { \ 1977 if (is_hotspot()) { \ 1978 return HotSpotJVMCI::className::get_##name(this); \ 1979 } else { \ 1980 return JNIJVMCI::className::get_##name(this); \ 1981 } \ 1982 } \ 1983 void JVMCIEnv::set_##className##_##name(type x) { \ 1984 if (is_hotspot()) { \ 1985 HotSpotJVMCI::className::set_##name(this, x); \ 1986 } else { \ 1987 JNIJVMCI::className::set_##name(this, x); \ 1988 } \ 1989 } 1990 #define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST) 1991 #define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST) 1992 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName) 1993 #define CONSTRUCTOR(className, signature) 1994 1995 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) 1996 1997 #undef START_CLASS 1998 #undef END_CLASS 1999 #undef METHOD 2000 #undef CONSTRUCTOR 2001 #undef FIELD 2002 #undef CHAR_FIELD 2003 #undef INT_FIELD 2004 #undef BOOLEAN_FIELD 2005 #undef LONG_FIELD 2006 #undef FLOAT_FIELD 2007 #undef OBJECT_FIELD 2008 #undef PRIMARRAY_FIELD 2009 #undef OBJECTARRAY_FIELD 2010 #undef STATIC_OOPISH_FIELD 2011 #undef STATIC_OBJECT_FIELD 2012 #undef STATIC_OBJECTARRAY_FIELD 2013 #undef STATIC_INT_FIELD 2014 #undef STATIC_BOOLEAN_FIELD 2015 #undef EMPTY_CAST