From a644670cc6afc3bd6cedaa7f0d7bb75c1de90417 Mon Sep 17 00:00:00 2001 From: Martin Doerr Date: Tue, 24 Oct 2023 09:09:33 +0000 Subject: [PATCH] 8318609: Upcall stubs should be smaller Co-authored-by: Jorn Vernee Reviewed-by: rrich, jvernee --- .../cpu/aarch64/stubGenerator_aarch64.cpp | 18 +++++++++++++ .../cpu/aarch64/upcallLinker_aarch64.cpp | 19 ++----------- src/hotspot/cpu/ppc/stubGenerator_ppc.cpp | 17 ++++++++++++ src/hotspot/cpu/ppc/upcallLinker_ppc.cpp | 20 +++----------- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 17 ++++++++++++ src/hotspot/cpu/riscv/upcallLinker_riscv.cpp | 19 +++---------- src/hotspot/cpu/s390/stubGenerator_s390.cpp | 17 ++++++++++++ src/hotspot/cpu/s390/upcallLinker_s390.cpp | 20 +++----------- src/hotspot/cpu/x86/stubGenerator_x86_64.cpp | 21 +++++++++++++++ src/hotspot/cpu/x86/stubGenerator_x86_64.hpp | 3 +++ src/hotspot/cpu/x86/upcallLinker_x86_64.cpp | 27 +++---------------- src/hotspot/share/code/codeBlob.cpp | 12 +++------ src/hotspot/share/code/codeBlob.hpp | 10 ++----- src/hotspot/share/prims/upcallLinker.cpp | 4 ++- src/hotspot/share/prims/upcallLinker.hpp | 6 +++-- src/hotspot/share/runtime/sharedRuntime.cpp | 2 +- src/hotspot/share/runtime/stubRoutines.cpp | 2 ++ src/hotspot/share/runtime/stubRoutines.hpp | 7 +++++ 18 files changed, 129 insertions(+), 112 deletions(-) diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index 6d2e2628553..7b36f42986e 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -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 } diff --git a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp index 57cc9fe6274..fb2f52facaf 100644 --- a/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp @@ -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)); diff --git a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp index c06f22e0fbb..efcc8c89721 100644 --- a/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp +++ b/src/hotspot/cpu/ppc/stubGenerator_ppc.cpp @@ -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() { diff --git a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp index 4cb86ad573c..aaa9952656c 100644 --- a/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp +++ b/src/hotspot/cpu/ppc/upcallLinker_ppc.cpp @@ -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 diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 6f302f747bb..2431df1178d 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -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(); } diff --git a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp index 6d605d716af..de90694945b 100644 --- a/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp +++ b/src/hotspot/cpu/riscv/upcallLinker_riscv.cpp @@ -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 diff --git a/src/hotspot/cpu/s390/stubGenerator_s390.cpp b/src/hotspot/cpu/s390/stubGenerator_s390.cpp index a26bcd04de2..64d8d9fa978 100644 --- a/src/hotspot/cpu/s390/stubGenerator_s390.cpp +++ b/src/hotspot/cpu/s390/stubGenerator_s390.cpp @@ -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() { diff --git a/src/hotspot/cpu/s390/upcallLinker_s390.cpp b/src/hotspot/cpu/s390/upcallLinker_s390.cpp index b748ec547cc..884f334c806 100644 --- a/src/hotspot/cpu/s390/upcallLinker_s390.cpp +++ b/src/hotspot/cpu/s390/upcallLinker_s390.cpp @@ -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 diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp index e071583b10b..15109a6af1b 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp @@ -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() { diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp index 3b568ace836..109c98f83bd 100644 --- a/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.hpp @@ -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 diff --git a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp index dfce6aef52d..395877f1479 100644 --- a/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp +++ b/src/hotspot/cpu/x86/upcallLinker_x86_64.cpp @@ -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)); diff --git a/src/hotspot/share/code/codeBlob.cpp b/src/hotspot/share/code/codeBlob.cpp index 9011bbfc1c2..c49fca717c9 100644 --- a/src/hotspot/share/code/codeBlob.cpp +++ b/src/hotspot/share/code/codeBlob.cpp @@ -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(); diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp index d5618f86622..4e7093bed24 100644 --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -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; diff --git a/src/hotspot/share/prims/upcallLinker.cpp b/src/hotspot/share/prims/upcallLinker.cpp index 1576c011525..8358649ac95 100644 --- a/src/hotspot/share/prims/upcallLinker.cpp +++ b/src/hotspot/share/prims/upcallLinker.cpp @@ -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; } diff --git a/src/hotspot/share/prims/upcallLinker.hpp b/src/hotspot/share/prims/upcallLinker.hpp index 3f8c717e501..529cb7c3911 100644 --- a/src/hotspot/share/prims/upcallLinker.hpp +++ b/src/hotspot/share/prims/upcallLinker.hpp @@ -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 diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp index 31a38443672..536944a61dc 100644 --- a/src/hotspot/share/runtime/sharedRuntime.cpp +++ b/src/hotspot/share/runtime/sharedRuntime.cpp @@ -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)) { diff --git a/src/hotspot/share/runtime/stubRoutines.cpp b/src/hotspot/share/runtime/stubRoutines.cpp index bea2a934bc6..faeaedac55e 100644 --- a/src/hotspot/share/runtime/stubRoutines.cpp +++ b/src/hotspot/share/runtime/stubRoutines.cpp @@ -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. diff --git a/src/hotspot/share/runtime/stubRoutines.hpp b/src/hotspot/share/runtime/stubRoutines.hpp index d62c3913f25..77d968263f7 100644 --- a/src/hotspot/share/runtime/stubRoutines.hpp +++ b/src/hotspot/share/runtime/stubRoutines.hpp @@ -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); //