8318609: Upcall stubs should be smaller

Co-authored-by: Jorn Vernee <jvernee@openjdk.org>
Reviewed-by: rrich, jvernee
This commit is contained in:
Martin Doerr 2023-10-24 09:09:33 +00:00
parent e6f23a90d4
commit a644670cc6
18 changed files with 129 additions and 112 deletions

View File

@ -41,6 +41,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "prims/upcallLinker.hpp"
#include "runtime/atomic.hpp"
#include "runtime/continuation.hpp"
#include "runtime/continuationEntry.inline.hpp"
@ -7326,6 +7327,21 @@ class StubGenerator: public StubCodeGenerator {
#endif // INCLUDE_JFR
// exception handler for upcall stubs
address generate_upcall_stub_exception_handler() {
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
address start = __ pc();
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(r0);
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
__ blr(rscratch1);
__ should_not_reach_here();
return start;
}
// Continuation point for throwing of implicit exceptions that are
// not handled in the current activation. Fabricates an exception
// oop and initiates normal exception dispatching in this
@ -8377,6 +8393,8 @@ class StubGenerator: public StubCodeGenerator {
#endif // LINUX
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
StubRoutines::aarch64::set_completed(); // Inidicate that arraycopy and zero_blocks stubs are generated
}

View File

@ -217,6 +217,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("{ on_entry");
__ lea(c_rarg0, Address(sp, frame_data_offset));
__ movptr(c_rarg1, (intptr_t)receiver);
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry));
__ blr(rscratch1);
__ mov(rthread, r0);
@ -233,9 +234,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("} argument shuffle");
__ block_comment("{ receiver ");
__ movptr(shuffle_reg, (intptr_t)receiver);
__ resolve_jobject(shuffle_reg, rscratch1, rscratch2);
__ mov(j_rarg0, shuffle_reg);
__ get_vm_result(j_rarg0, rthread);
__ block_comment("} receiver ");
__ mov_metadata(rmethod, entry);
@ -306,19 +305,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
//////////////////////////////////////////////////////////////////////////////
__ block_comment("{ exception handler");
intptr_t exception_handler_offset = __ pc() - start;
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(r0);
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
__ blr(rscratch1);
__ should_not_reach_here();
__ block_comment("} exception handler");
_masm->flush();
#ifndef PRODUCT
@ -334,7 +320,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
UpcallStub* blob
= UpcallStub::create(name,
&buffer,
exception_handler_offset,
receiver,
in_ByteSize(frame_data_offset));

View File

@ -36,6 +36,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "prims/upcallLinker.hpp"
#include "runtime/continuation.hpp"
#include "runtime/continuationEntry.inline.hpp"
#include "runtime/frame.inline.hpp"
@ -4717,6 +4718,20 @@ class StubGenerator: public StubCodeGenerator {
#endif // INCLUDE_JFR
// exception handler for upcall stubs
address generate_upcall_stub_exception_handler() {
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
address start = __ pc();
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(R3_ARG1);
__ load_const_optimized(R12_scratch2, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception), R0);
__ call_c(R12_scratch2);
__ should_not_reach_here();
return start;
}
// Initialization
void generate_initial_stubs() {
@ -4796,6 +4811,8 @@ class StubGenerator: public StubCodeGenerator {
// arraycopy stubs used by compilers
generate_arraycopy_stubs();
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
}
void generate_compiler_stubs() {

View File

@ -115,7 +115,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
__ block_comment("} restore_callee_saved_regs ");
}
static const int upcall_stub_code_base_size = 1536; // depends on GC (resolve_jobject)
static const int upcall_stub_code_base_size = 1024;
static const int upcall_stub_size_per_arg = 16; // arg save & restore + move
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
@ -217,6 +217,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("{ on_entry");
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry), R0);
__ addi(R3_ARG1, R1_SP, frame_data_offset);
__ load_const_optimized(R4_ARG2, (intptr_t)receiver, R0);
__ call_c(call_target_address);
__ mr(R16_thread, R3_RET);
__ block_comment("} on_entry");
@ -232,8 +233,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("} argument shuffle");
__ block_comment("{ receiver ");
__ load_const_optimized(R3_ARG1, (intptr_t)receiver, R0);
__ resolve_jobject(R3_ARG1, tmp, R31, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS); // kills R31
__ get_vm_result(R3_ARG1);
__ block_comment("} receiver ");
__ load_const_optimized(R19_method, (intptr_t)entry);
@ -314,19 +314,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
//////////////////////////////////////////////////////////////////////////////
__ block_comment("{ exception handler");
intptr_t exception_handler_offset = __ pc() - start;
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(R3_ARG1);
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception), R0);
__ call_c(call_target_address);
__ should_not_reach_here();
__ block_comment("} exception handler");
_masm->flush();
#ifndef PRODUCT
@ -342,7 +329,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
UpcallStub* blob
= UpcallStub::create(name,
&buffer,
exception_handler_offset,
receiver,
in_ByteSize(frame_data_offset));
#ifndef ABI_ELFv2

View File

@ -38,6 +38,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "prims/upcallLinker.hpp"
#include "runtime/continuation.hpp"
#include "runtime/continuationEntry.inline.hpp"
#include "runtime/frame.inline.hpp"
@ -4504,6 +4505,20 @@ class StubGenerator: public StubCodeGenerator {
#endif // INCLUDE_JFR
// exception handler for upcall stubs
address generate_upcall_stub_exception_handler() {
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
address start = __ pc();
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(x10); // return a exception oop in a0
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception));
__ should_not_reach_here();
return start;
}
#undef __
// Initialization
@ -4588,6 +4603,8 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::riscv::_method_entry_barrier = generate_method_entry_barrier();
}
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
StubRoutines::riscv::set_completed();
}

View File

@ -114,7 +114,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
__ block_comment("} restore_callee_saved_regs ");
}
static const int upcall_stub_code_base_size = 2048;
static const int upcall_stub_code_base_size = 1024;
static const int upcall_stub_size_per_arg = 16;
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
@ -218,6 +218,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("{ on_entry");
__ la(c_rarg0, Address(sp, frame_data_offset));
__ movptr(c_rarg1, (intptr_t) receiver);
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::on_entry));
__ mv(xthread, x10);
__ reinit_heapbase();
@ -255,9 +256,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("} argument shuffle");
__ block_comment("{ receiver ");
__ movptr(shuffle_reg, (intptr_t) receiver);
__ resolve_jobject(shuffle_reg, t0, t1);
__ mv(j_rarg0, shuffle_reg);
__ get_vm_result(j_rarg0, xthread);
__ block_comment("} receiver ");
__ mov_metadata(xmethod, entry);
@ -326,17 +325,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
//////////////////////////////////////////////////////////////////////////////
__ block_comment("{ exception handler");
intptr_t exception_handler_offset = __ pc() - start;
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(x10); // return a exception oop in a0
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception));
__ should_not_reach_here();
__ block_comment("} exception handler");
__ flush();
#ifndef PRODUCT
@ -352,7 +340,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
UpcallStub* blob
= UpcallStub::create(name,
&buffer,
exception_handler_offset,
receiver,
in_ByteSize(frame_data_offset));
#ifndef PRODUCT

View File

@ -37,6 +37,7 @@
#include "oops/objArrayKlass.hpp"
#include "oops/oop.inline.hpp"
#include "prims/methodHandles.hpp"
#include "prims/upcallLinker.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaThread.hpp"
@ -3094,6 +3095,21 @@ class StubGenerator: public StubCodeGenerator {
#endif // INCLUDE_JFR
// exception handler for upcall stubs
address generate_upcall_stub_exception_handler() {
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
address start = __ pc();
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(Z_ARG1);
__ load_const_optimized(Z_R1_scratch, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
__ call_c(Z_R1_scratch);
__ should_not_reach_here();
return start;
}
void generate_initial_stubs() {
// Generates all stubs and initializes the entry points.
@ -3174,6 +3190,7 @@ class StubGenerator: public StubCodeGenerator {
StubRoutines::zarch::_nmethod_entry_barrier = generate_nmethod_entry_barrier();
}
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
}
void generate_compiler_stubs() {

View File

@ -114,7 +114,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
__ block_comment("} restore_callee_saved_regs ");
}
static const int upcall_stub_code_base_size = 1024; // depends on GC (resolve_jobject)
static const int upcall_stub_code_base_size = 1024;
static const int upcall_stub_size_per_arg = 16; // arg save & restore + move
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
BasicType* in_sig_bt, int total_in_args,
@ -202,6 +202,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("{ on_entry");
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry));
__ z_aghik(Z_ARG1, Z_SP, frame_data_offset);
__ load_const_optimized(Z_ARG2, (intptr_t)receiver);
__ call(call_target_address);
__ z_lgr(Z_thread, Z_RET);
__ block_comment("} on_entry");
@ -212,8 +213,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("} argument shuffle");
__ block_comment("{ receiver ");
__ load_const_optimized(Z_ARG1, (intptr_t)receiver);
__ resolve_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2);
__ get_vm_result(Z_ARG1);
__ block_comment("} receiver ");
__ load_const_optimized(Z_method, (intptr_t)entry);
@ -266,19 +266,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
//////////////////////////////////////////////////////////////////////////////
__ block_comment("{ exception handler");
intptr_t exception_handler_offset = __ pc() - start;
// Native caller has no idea how to handle exceptions,
// so we just crash here. Up to callee to catch exceptions.
__ verify_oop(Z_ARG1);
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::handle_uncaught_exception));
__ call_c(call_target_address);
__ should_not_reach_here();
__ block_comment("} exception handler");
_masm->flush();
#ifndef PRODUCT
@ -293,7 +280,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
UpcallStub* blob
= UpcallStub::create(name,
&buffer,
exception_handler_offset,
receiver,
in_ByteSize(frame_data_offset));
#ifndef PRODUCT

View File

@ -32,6 +32,7 @@
#include "gc/shared/gc_globals.hpp"
#include "memory/universe.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/upcallLinker.hpp"
#include "runtime/arguments.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/sharedRuntime.hpp"
@ -3887,6 +3888,24 @@ address StubGenerator::generate_throw_exception(const char* name,
return stub->entry_point();
}
// exception handler for upcall stubs
address StubGenerator::generate_upcall_stub_exception_handler() {
StubCodeMark mark(this, "StubRoutines", "upcall stub exception handler");
address start = __ pc();
// native caller has no idea how to handle exceptions
// we just crash here. Up to callee to catch exceptions.
__ verify_oop(rax);
__ vzeroupper();
__ mov(c_rarg0, rax);
__ andptr(rsp, -StackAlignmentInBytes); // align stack as required by ABI
__ subptr(rsp, frame::arg_reg_save_area_bytes); // windows
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception)));
__ should_not_reach_here();
return start;
}
void StubGenerator::create_control_words() {
// Round to nearest, 64-bit mode, exceptions masked
StubRoutines::x86::_mxcsr_std = 0x1F80;
@ -4039,6 +4058,8 @@ void StubGenerator::generate_final_stubs() {
if (UseVectorizedMismatchIntrinsic) {
StubRoutines::_vectorizedMismatch = generate_vectorizedMismatch();
}
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
}
void StubGenerator::generate_compiler_stubs() {

View File

@ -565,6 +565,9 @@ class StubGenerator: public StubCodeGenerator {
Register arg1 = noreg,
Register arg2 = noreg);
// shared exception handler for FFM upcall stubs
address generate_upcall_stub_exception_handler();
void create_control_words();
// Initialization

View File

@ -165,7 +165,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
__ block_comment("} restore_callee_saved_regs ");
}
static const int upcall_stub_code_base_size = 2048;
static const int upcall_stub_code_base_size = 1024;
static const int upcall_stub_size_per_arg = 16;
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
@ -272,6 +272,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("{ on_entry");
__ vzeroupper();
__ lea(c_rarg0, Address(rsp, frame_data_offset));
__ movptr(c_rarg1, (intptr_t)receiver);
// stack already aligned
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::on_entry)));
__ movptr(r15_thread, rax);
@ -288,9 +289,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
__ block_comment("} argument shuffle");
__ block_comment("{ receiver ");
__ movptr(rscratch1, (intptr_t)receiver);
__ resolve_jobject(rscratch1, r15_thread, rscratch2);
__ movptr(j_rarg0, rscratch1);
__ get_vm_result(j_rarg0, r15_thread);
__ block_comment("} receiver ");
__ mov_metadata(rbx, entry);
@ -361,27 +360,8 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
//////////////////////////////////////////////////////////////////////////////
__ block_comment("{ exception handler");
intptr_t exception_handler_offset = __ pc() - start;
// TODO: this is always the same, can we bypass and call handle_uncaught_exception directly?
// native caller has no idea how to handle exceptions
// we just crash here. Up to callee to catch exceptions.
__ verify_oop(rax);
__ vzeroupper();
__ mov(c_rarg0, rax);
__ andptr(rsp, -StackAlignmentInBytes); // align stack as required by ABI
__ subptr(rsp, frame::arg_reg_save_area_bytes); // windows (not really needed)
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, UpcallLinker::handle_uncaught_exception)));
__ should_not_reach_here();
__ block_comment("} exception handler");
_masm->flush();
#ifndef PRODUCT
stringStream ss;
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
@ -395,7 +375,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
UpcallStub* blob
= UpcallStub::create(name,
&buffer,
exception_handler_offset,
receiver,
in_ByteSize(frame_data_offset));

View File

@ -738,12 +738,9 @@ void DeoptimizationBlob::print_value_on(outputStream* st) const {
// Implementation of UpcallStub
UpcallStub::UpcallStub(const char* name, CodeBuffer* cb, int size,
intptr_t exception_handler_offset,
jobject receiver, ByteSize frame_data_offset) :
UpcallStub::UpcallStub(const char* name, CodeBuffer* cb, int size, jobject receiver, ByteSize frame_data_offset) :
RuntimeBlob(name, cb, sizeof(UpcallStub), size, CodeOffsets::frame_never_safe, 0 /* no frame size */,
/* oop maps = */ nullptr, /* caller must gc arguments = */ false),
_exception_handler_offset(exception_handler_offset),
_receiver(receiver),
_frame_data_offset(frame_data_offset) {
CodeCache::commit(this);
@ -753,17 +750,14 @@ void* UpcallStub::operator new(size_t s, unsigned size) throw() {
return CodeCache::allocate(size, CodeBlobType::NonNMethod);
}
UpcallStub* UpcallStub::create(const char* name, CodeBuffer* cb,
intptr_t exception_handler_offset,
jobject receiver, ByteSize frame_data_offset) {
UpcallStub* UpcallStub::create(const char* name, CodeBuffer* cb, jobject receiver, ByteSize frame_data_offset) {
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
UpcallStub* blob = nullptr;
unsigned int size = CodeBlob::allocation_size(cb, sizeof(UpcallStub));
{
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
blob = new (size) UpcallStub(name, cb, size,
exception_handler_offset, receiver, frame_data_offset);
blob = new (size) UpcallStub(name, cb, size, receiver, frame_data_offset);
}
// Track memory usage statistic after releasing CodeCache_lock
MemoryService::track_code_cache_memory_usage();

View File

@ -733,13 +733,10 @@ class UpcallLinker;
class UpcallStub: public RuntimeBlob {
friend class UpcallLinker;
private:
intptr_t _exception_handler_offset;
jobject _receiver;
ByteSize _frame_data_offset;
UpcallStub(const char* name, CodeBuffer* cb, int size,
intptr_t exception_handler_offset,
jobject receiver, ByteSize frame_data_offset);
UpcallStub(const char* name, CodeBuffer* cb, int size, jobject receiver, ByteSize frame_data_offset);
void* operator new(size_t s, unsigned size) throw();
@ -754,13 +751,10 @@ class UpcallStub: public RuntimeBlob {
FrameData* frame_data_for_frame(const frame& frame) const;
public:
// Creation
static UpcallStub* create(const char* name, CodeBuffer* cb,
intptr_t exception_handler_offset,
jobject receiver, ByteSize frame_data_offset);
static UpcallStub* create(const char* name, CodeBuffer* cb, jobject receiver, ByteSize frame_data_offset);
static void free(UpcallStub* blob);
address exception_handler() { return code_begin() + _exception_handler_offset; }
jobject receiver() { return _receiver; }
JavaFrameAnchor* jfa_for_frame(const frame& frame) const;

View File

@ -74,7 +74,7 @@ JavaThread* UpcallLinker::maybe_attach_and_get_thread() {
}
// modelled after JavaCallWrapper::JavaCallWrapper
JavaThread* UpcallLinker::on_entry(UpcallStub::FrameData* context) {
JavaThread* UpcallLinker::on_entry(UpcallStub::FrameData* context, jobject receiver) {
JavaThread* thread = maybe_attach_and_get_thread();
guarantee(thread->thread_state() == _thread_in_native, "wrong thread state for upcall");
context->thread = thread;
@ -109,6 +109,8 @@ JavaThread* UpcallLinker::on_entry(UpcallStub::FrameData* context) {
debug_only(thread->inc_java_call_counter());
thread->set_active_handles(context->new_handles); // install new handle block and reset Java frame linkage
thread->set_vm_result(JNIHandles::resolve(receiver));
return thread;
}

View File

@ -32,10 +32,9 @@ class JavaThread;
class UpcallLinker {
private:
static void handle_uncaught_exception(oop exception);
static JavaThread* maybe_attach_and_get_thread();
static JavaThread* on_entry(UpcallStub::FrameData* context);
static JavaThread* on_entry(UpcallStub::FrameData* context, jobject receiver);
static void on_exit(UpcallStub::FrameData* context);
public:
static address make_upcall_stub(jobject mh, Method* entry,
@ -44,6 +43,9 @@ public:
BasicType ret_type,
jobject jabi, jobject jconv,
bool needs_return_buffer, int ret_buf_size);
// public for stubGenerator
static void handle_uncaught_exception(oop exception);
};
#endif // SHARE_VM_PRIMS_UPCALLLINKER_HPP

View File

@ -520,7 +520,7 @@ address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* curr
return StubRoutines::catch_exception_entry();
}
if (blob != nullptr && blob->is_upcall_stub()) {
return ((UpcallStub*)blob)->exception_handler();
return StubRoutines::upcall_stub_exception_handler();
}
// Interpreted code
if (Interpreter::contains(return_address)) {

View File

@ -188,6 +188,8 @@ JFR_ONLY(address StubRoutines::_jfr_write_checkpoint = nullptr;)
JFR_ONLY(RuntimeStub* StubRoutines::_jfr_return_lease_stub = nullptr;)
JFR_ONLY(address StubRoutines::_jfr_return_lease = nullptr;)
address StubRoutines::_upcall_stub_exception_handler = nullptr;
// Initialization
//
// Note: to break cycle with universe initialization, stubs are generated in two phases.

View File

@ -269,6 +269,8 @@ class StubRoutines: AllStatic {
static address _vector_f_math[VectorSupport::NUM_VEC_SIZES][VectorSupport::NUM_SVML_OP];
static address _vector_d_math[VectorSupport::NUM_VEC_SIZES][VectorSupport::NUM_SVML_OP];
static address _upcall_stub_exception_handler;
public:
// Initialization/Testing
static void initialize_initial_stubs(); // must happen before universe::genesis
@ -465,6 +467,11 @@ class StubRoutines: AllStatic {
JFR_ONLY(static address jfr_write_checkpoint() { return _jfr_write_checkpoint; })
JFR_ONLY(static address jfr_return_lease() { return _jfr_return_lease; })
static address upcall_stub_exception_handler() {
assert(_upcall_stub_exception_handler != nullptr, "not implemented");
return _upcall_stub_exception_handler;
}
static address select_fill_function(BasicType t, bool aligned, const char* &name);
//