Skip to content

Commit 6af1358

Browse files
committedOct 3, 2024
8337753: Target class of upcall stub may be unloaded
Reviewed-by: amitkumar, vlivanov, mdoerr
1 parent 19642bd commit 6af1358

23 files changed

+307
-78
lines changed
 

‎src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -7320,6 +7320,28 @@ class StubGenerator: public StubCodeGenerator {
73207320
return start;
73217321
}
73227322

7323+
// load Method* target of MethodHandle
7324+
// j_rarg0 = jobject receiver
7325+
// rmethod = result
7326+
address generate_upcall_stub_load_target() {
7327+
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
7328+
address start = __ pc();
7329+
7330+
__ resolve_global_jobject(j_rarg0, rscratch1, rscratch2);
7331+
// Load target method from receiver
7332+
__ load_heap_oop(rmethod, Address(j_rarg0, java_lang_invoke_MethodHandle::form_offset()), rscratch1, rscratch2);
7333+
__ load_heap_oop(rmethod, Address(rmethod, java_lang_invoke_LambdaForm::vmentry_offset()), rscratch1, rscratch2);
7334+
__ load_heap_oop(rmethod, Address(rmethod, java_lang_invoke_MemberName::method_offset()), rscratch1, rscratch2);
7335+
__ access_load_at(T_ADDRESS, IN_HEAP, rmethod,
7336+
Address(rmethod, java_lang_invoke_ResolvedMethodName::vmtarget_offset()),
7337+
noreg, noreg);
7338+
__ str(rmethod, Address(rthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
7339+
7340+
__ ret(lr);
7341+
7342+
return start;
7343+
}
7344+
73237345
#undef __
73247346
#define __ masm->
73257347

@@ -8241,6 +8263,7 @@ class StubGenerator: public StubCodeGenerator {
82418263
#endif
82428264

82438265
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
8266+
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
82448267

82458268
StubRoutines::aarch64::set_completed(); // Inidicate that arraycopy and zero_blocks stubs are generated
82468269
}

‎src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp

+7-9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "precompiled.hpp"
2626
#include "asm/macroAssembler.hpp"
27+
#include "classfile/javaClasses.hpp"
2728
#include "logging/logStream.hpp"
2829
#include "memory/resourceArea.hpp"
2930
#include "prims/upcallLinker.hpp"
@@ -117,7 +118,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
117118
static const int upcall_stub_code_base_size = 1024;
118119
static const int upcall_stub_size_per_arg = 16;
119120

120-
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
121+
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
121122
BasicType* out_sig_bt, int total_out_args,
122123
BasicType ret_type,
123124
jobject jabi, jobject jconv,
@@ -222,7 +223,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
222223

223224
__ block_comment("{ on_entry");
224225
__ lea(c_rarg0, Address(sp, frame_data_offset));
225-
__ movptr(c_rarg1, (intptr_t)receiver);
226226
__ movptr(rscratch1, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry));
227227
__ blr(rscratch1);
228228
__ mov(rthread, r0);
@@ -238,12 +238,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
238238
arg_shuffle.generate(_masm, as_VMStorage(shuffle_reg), abi._shadow_space_bytes, 0);
239239
__ block_comment("} argument shuffle");
240240

241-
__ block_comment("{ receiver ");
242-
__ get_vm_result(j_rarg0, rthread);
243-
__ block_comment("} receiver ");
244-
245-
__ mov_metadata(rmethod, entry);
246-
__ str(rmethod, Address(rthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
241+
__ block_comment("{ load target ");
242+
__ movptr(j_rarg0, (intptr_t)receiver);
243+
__ far_call(RuntimeAddress(StubRoutines::upcall_stub_load_target()), rscratch1); // puts target Method* in rmethod
244+
__ block_comment("} load target ");
247245

248246
__ push_cont_fastpath(rthread);
249247

@@ -318,7 +316,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
318316

319317
#ifndef PRODUCT
320318
stringStream ss;
321-
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
319+
ss.print("upcall_stub_%s", signature->as_C_string());
322320
const char* name = _masm->code_string(ss.as_string());
323321
#else // PRODUCT
324322
const char* name = "upcall_stub";

‎src/hotspot/cpu/arm/upcallLinker_arm.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "prims/upcallLinker.hpp"
2626
#include "utilities/debug.hpp"
2727

28-
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
28+
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
2929
BasicType* out_sig_bt, int total_out_args,
3030
BasicType ret_type,
3131
jobject jabi, jobject jconv,

‎src/hotspot/cpu/ppc/stubGenerator_ppc.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -4587,6 +4587,30 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) {
45874587
return start;
45884588
}
45894589

4590+
// load Method* target of MethodHandle
4591+
// R3_ARG1 = jobject receiver
4592+
// R19_method = result Method*
4593+
address generate_upcall_stub_load_target() {
4594+
4595+
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
4596+
address start = __ pc();
4597+
4598+
__ resolve_global_jobject(R3_ARG1, R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS);
4599+
// Load target method from receiver
4600+
__ load_heap_oop(R19_method, java_lang_invoke_MethodHandle::form_offset(), R3_ARG1,
4601+
R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS, IS_NOT_NULL);
4602+
__ load_heap_oop(R19_method, java_lang_invoke_LambdaForm::vmentry_offset(), R19_method,
4603+
R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS, IS_NOT_NULL);
4604+
__ load_heap_oop(R19_method, java_lang_invoke_MemberName::method_offset(), R19_method,
4605+
R22_tmp2, R23_tmp3, MacroAssembler::PRESERVATION_FRAME_LR_GP_FP_REGS, IS_NOT_NULL);
4606+
__ ld(R19_method, java_lang_invoke_ResolvedMethodName::vmtarget_offset(), R19_method);
4607+
__ std(R19_method, in_bytes(JavaThread::callee_target_offset()), R16_thread); // just in case callee is deoptimized
4608+
4609+
__ blr();
4610+
4611+
return start;
4612+
}
4613+
45904614
// Initialization
45914615
void generate_initial_stubs() {
45924616
// Generates all stubs and initializes the entry points
@@ -4651,6 +4675,7 @@ address generate_lookup_secondary_supers_table_stub(u1 super_klass_index) {
46514675
}
46524676

46534677
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
4678+
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
46544679
}
46554680

46564681
void generate_compiler_stubs() {

‎src/hotspot/cpu/ppc/upcallLinker_ppc.cpp

+9-9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "precompiled.hpp"
2626
#include "asm/macroAssembler.inline.hpp"
27+
#include "classfile/javaClasses.hpp"
2728
#include "logging/logStream.hpp"
2829
#include "memory/resourceArea.hpp"
2930
#include "prims/upcallLinker.hpp"
@@ -118,7 +119,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
118119
static const int upcall_stub_code_base_size = 1024;
119120
static const int upcall_stub_size_per_arg = 16; // arg save & restore + move
120121

121-
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
122+
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
122123
BasicType* out_sig_bt, int total_out_args,
123124
BasicType ret_type,
124125
jobject jabi, jobject jconv,
@@ -221,7 +222,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
221222
__ block_comment("{ on_entry");
222223
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry), R0);
223224
__ addi(R3_ARG1, R1_SP, frame_data_offset);
224-
__ load_const_optimized(R4_ARG2, (intptr_t)receiver, R0);
225225
__ call_c(call_target_address);
226226
__ mr(R16_thread, R3_RET);
227227
__ block_comment("} on_entry");
@@ -236,12 +236,12 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
236236
arg_shuffle.generate(_masm, as_VMStorage(callerSP), frame::native_abi_minframe_size, frame::jit_out_preserve_size);
237237
__ block_comment("} argument shuffle");
238238

239-
__ block_comment("{ receiver ");
240-
__ get_vm_result(R3_ARG1);
241-
__ block_comment("} receiver ");
242-
243-
__ load_const_optimized(R19_method, (intptr_t)entry);
244-
__ std(R19_method, in_bytes(JavaThread::callee_target_offset()), R16_thread);
239+
__ block_comment("{ load target ");
240+
__ load_const_optimized(call_target_address, StubRoutines::upcall_stub_load_target(), R0);
241+
__ load_const_optimized(R3_ARG1, (intptr_t)receiver, R0);
242+
__ mtctr(call_target_address);
243+
__ bctrl(); // loads target Method* into R19_method
244+
__ block_comment("} load target ");
245245

246246
__ push_cont_fastpath();
247247

@@ -326,7 +326,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
326326

327327
#ifndef PRODUCT
328328
stringStream ss;
329-
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
329+
ss.print("upcall_stub_%s", signature->as_C_string());
330330
const char* name = _masm->code_string(ss.as_string());
331331
#else // PRODUCT
332332
const char* name = "upcall_stub";

‎src/hotspot/cpu/riscv/stubGenerator_riscv.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -6124,6 +6124,29 @@ static const int64_t right_3_bits = right_n_bits(3);
61246124
return start;
61256125
}
61266126

6127+
// load Method* target of MethodHandle
6128+
// j_rarg0 = jobject receiver
6129+
// xmethod = Method* result
6130+
address generate_upcall_stub_load_target() {
6131+
6132+
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
6133+
address start = __ pc();
6134+
6135+
__ resolve_global_jobject(j_rarg0, t0, t1);
6136+
// Load target method from receiver
6137+
__ load_heap_oop(xmethod, Address(j_rarg0, java_lang_invoke_MethodHandle::form_offset()), t0, t1);
6138+
__ load_heap_oop(xmethod, Address(xmethod, java_lang_invoke_LambdaForm::vmentry_offset()), t0, t1);
6139+
__ load_heap_oop(xmethod, Address(xmethod, java_lang_invoke_MemberName::method_offset()), t0, t1);
6140+
__ access_load_at(T_ADDRESS, IN_HEAP, xmethod,
6141+
Address(xmethod, java_lang_invoke_ResolvedMethodName::vmtarget_offset()),
6142+
noreg, noreg);
6143+
__ sd(xmethod, Address(xthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
6144+
6145+
__ ret();
6146+
6147+
return start;
6148+
}
6149+
61276150
#undef __
61286151

61296152
// Initialization
@@ -6189,6 +6212,7 @@ static const int64_t right_3_bits = right_n_bits(3);
61896212
#endif // COMPILER2
61906213

61916214
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
6215+
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
61926216

61936217
StubRoutines::riscv::set_completed();
61946218
}

‎src/hotspot/cpu/riscv/upcallLinker_riscv.cpp

+7-9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "precompiled.hpp"
2727
#include "asm/macroAssembler.hpp"
28+
#include "classfile/javaClasses.hpp"
2829
#include "logging/logStream.hpp"
2930
#include "memory/resourceArea.hpp"
3031
#include "prims/upcallLinker.hpp"
@@ -117,7 +118,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
117118
static const int upcall_stub_code_base_size = 1024;
118119
static const int upcall_stub_size_per_arg = 16;
119120

120-
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
121+
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
121122
BasicType* out_sig_bt, int total_out_args,
122123
BasicType ret_type,
123124
jobject jabi, jobject jconv,
@@ -223,7 +224,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
223224

224225
__ block_comment("{ on_entry");
225226
__ la(c_rarg0, Address(sp, frame_data_offset));
226-
__ movptr(c_rarg1, (address) receiver);
227227
__ rt_call(CAST_FROM_FN_PTR(address, UpcallLinker::on_entry));
228228
__ mv(xthread, x10);
229229
__ reinit_heapbase();
@@ -260,12 +260,10 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
260260
arg_shuffle.generate(_masm, as_VMStorage(shuffle_reg), abi._shadow_space_bytes, 0);
261261
__ block_comment("} argument shuffle");
262262

263-
__ block_comment("{ receiver ");
264-
__ get_vm_result(j_rarg0, xthread);
265-
__ block_comment("} receiver ");
266-
267-
__ mov_metadata(xmethod, entry);
268-
__ sd(xmethod, Address(xthread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
263+
__ block_comment("{ load target ");
264+
__ movptr(j_rarg0, (address) receiver);
265+
__ far_call(RuntimeAddress(StubRoutines::upcall_stub_load_target())); // loads Method* into xmethod
266+
__ block_comment("} load target ");
269267

270268
__ push_cont_fastpath(xthread);
271269

@@ -338,7 +336,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
338336

339337
#ifndef PRODUCT
340338
stringStream ss;
341-
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
339+
ss.print("upcall_stub_%s", signature->as_C_string());
342340
const char *name = _masm->code_string(ss.as_string());
343341
#else // PRODUCT
344342
const char* name = "upcall_stub";

‎src/hotspot/cpu/s390/stubGenerator_s390.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -3053,6 +3053,29 @@ class StubGenerator: public StubCodeGenerator {
30533053
return start;
30543054
}
30553055

3056+
// load Method* target of MethodHandle
3057+
// Z_ARG1 = jobject receiver
3058+
// Z_method = Method* result
3059+
address generate_upcall_stub_load_target() {
3060+
StubCodeMark mark(this, "StubRoutines", "upcall_stub_load_target");
3061+
address start = __ pc();
3062+
3063+
__ resolve_global_jobject(Z_ARG1, Z_tmp_1, Z_tmp_2);
3064+
// Load target method from receiver
3065+
__ load_heap_oop(Z_method, Address(Z_ARG1, java_lang_invoke_MethodHandle::form_offset()),
3066+
noreg, noreg, IS_NOT_NULL);
3067+
__ load_heap_oop(Z_method, Address(Z_method, java_lang_invoke_LambdaForm::vmentry_offset()),
3068+
noreg, noreg, IS_NOT_NULL);
3069+
__ load_heap_oop(Z_method, Address(Z_method, java_lang_invoke_MemberName::method_offset()),
3070+
noreg, noreg, IS_NOT_NULL);
3071+
__ z_lg(Z_method, Address(Z_method, java_lang_invoke_ResolvedMethodName::vmtarget_offset()));
3072+
__ z_stg(Z_method, Address(Z_thread, JavaThread::callee_target_offset())); // just in case callee is deoptimized
3073+
3074+
__ z_br(Z_R14);
3075+
3076+
return start;
3077+
}
3078+
30563079
void generate_initial_stubs() {
30573080
// Generates all stubs and initializes the entry points.
30583081

@@ -3110,6 +3133,7 @@ class StubGenerator: public StubCodeGenerator {
31103133
}
31113134

31123135
StubRoutines::_upcall_stub_exception_handler = generate_upcall_stub_exception_handler();
3136+
StubRoutines::_upcall_stub_load_target = generate_upcall_stub_load_target();
31133137
}
31143138

31153139
void generate_compiler_stubs() {

‎src/hotspot/cpu/s390/upcallLinker_s390.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "precompiled.hpp"
2525
#include "asm/macroAssembler.inline.hpp"
26+
#include "classfile/javaClasses.hpp"
2627
#include "logging/logStream.hpp"
2728
#include "memory/resourceArea.hpp"
2829
#include "prims/upcallLinker.hpp"
@@ -116,7 +117,7 @@ static void restore_callee_saved_registers(MacroAssembler* _masm, const ABIDescr
116117

117118
static const int upcall_stub_code_base_size = 1024;
118119
static const int upcall_stub_size_per_arg = 16; // arg save & restore + move
119-
address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
120+
address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
120121
BasicType* out_sig_bt, int total_out_args,
121122
BasicType ret_type,
122123
jobject jabi, jobject jconv,
@@ -206,7 +207,6 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
206207
__ block_comment("on_entry {");
207208
__ load_const_optimized(call_target_address, CAST_FROM_FN_PTR(uint64_t, UpcallLinker::on_entry));
208209
__ z_aghik(Z_ARG1, Z_SP, frame_data_offset);
209-
__ load_const_optimized(Z_ARG2, (intptr_t)receiver);
210210
__ call(call_target_address);
211211
__ z_lgr(Z_thread, Z_RET);
212212
__ block_comment("} on_entry");
@@ -216,12 +216,11 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
216216
arg_shuffle.generate(_masm, shuffle_reg, abi._shadow_space_bytes, frame::z_jit_out_preserve_size);
217217
__ block_comment("} argument_shuffle");
218218

219-
__ block_comment("receiver {");
220-
__ get_vm_result(Z_ARG1);
221-
__ block_comment("} receiver");
222-
223-
__ load_const_optimized(Z_method, (intptr_t)entry);
224-
__ z_stg(Z_method, Address(Z_thread, in_bytes(JavaThread::callee_target_offset())));
219+
__ block_comment("load_target {");
220+
__ load_const_optimized(Z_ARG1, (intptr_t)receiver);
221+
__ load_const_optimized(call_target_address, StubRoutines::upcall_stub_load_target());
222+
__ call(call_target_address); // load taget Method* into Z_method
223+
__ block_comment("} load_target");
225224

226225
__ z_lg(call_target_address, Address(Z_method, in_bytes(Method::from_compiled_offset())));
227226
__ call(call_target_address);
@@ -274,7 +273,7 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Method* entry,
274273

275274
#ifndef PRODUCT
276275
stringStream ss;
277-
ss.print("upcall_stub_%s", entry->signature()->as_C_string());
276+
ss.print("upcall_stub_%s", signature->as_C_string());
278277
const char* name = _masm->code_string(ss.as_string());
279278
#else // PRODUCT
280279
const char* name = "upcall_stub";

0 commit comments

Comments
 (0)
Please sign in to comment.