Skip to content

Commit d244442

Browse files
committed
PPC64 implementation.
1 parent 44330f9 commit d244442

14 files changed

+187
-80
lines changed

src/hotspot/cpu/ppc/c1_CodeStubs_ppc.cpp

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,8 @@ void C1SafepointPollStub::emit_code(LIR_Assembler* ce) {
4141
if (UseSIGTRAP) {
4242
DEBUG_ONLY( __ should_not_reach_here("C1SafepointPollStub::emit_code"); )
4343
} else {
44-
assert(SharedRuntime::polling_page_return_handler_blob() != nullptr,
45-
"polling page return stub not created yet");
46-
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
47-
4844
__ bind(_entry);
49-
// Using pc relative address computation.
50-
{
51-
Label next_pc;
52-
__ bl(next_pc);
53-
__ bind(next_pc);
54-
}
55-
int current_offset = __ offset();
56-
__ mflr(R12);
57-
__ add_const_optimized(R12, R12, safepoint_offset() - current_offset);
58-
__ std(R12, in_bytes(JavaThread::saved_exception_pc_offset()), R16_thread);
59-
60-
__ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
61-
__ mtctr(R0);
62-
__ bctr();
45+
__ jump_to_polling_page_return_handler_blob(safepoint_offset());
6346
}
6447
}
6548

src/hotspot/cpu/ppc/c2_CodeStubs_ppc.cpp

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2021, 2022, SAP SE. All rights reserved.
3+
* Copyright (c) 2021, 2025 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -34,26 +34,8 @@ int C2SafepointPollStub::max_size() const {
3434
}
3535

3636
void C2SafepointPollStub::emit(C2_MacroAssembler& masm) {
37-
assert(SharedRuntime::polling_page_return_handler_blob() != nullptr,
38-
"polling page return stub not created yet");
39-
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
40-
4137
__ bind(entry());
42-
// Using pc relative address computation.
43-
{
44-
Label next_pc;
45-
__ bl(next_pc);
46-
__ bind(next_pc);
47-
}
48-
int current_offset = __ offset();
4938
// Code size should not depend on offset: see _stub_size computation in output.cpp
50-
__ load_const32(R12, _safepoint_offset - current_offset);
51-
__ mflr(R0);
52-
__ add(R12, R12, R0);
53-
__ std(R12, in_bytes(JavaThread::saved_exception_pc_offset()), R16_thread);
54-
55-
__ add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
56-
__ mtctr(R0);
57-
__ bctr();
39+
__ jump_to_polling_page_return_handler_blob(_safepoint_offset, true);
5840
}
5941
#undef __

src/hotspot/cpu/ppc/frame_ppc.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@
363363
inline frame(intptr_t* sp, intptr_t* fp, address pc);
364364
inline frame(intptr_t* sp, address pc, kind knd = kind::nmethod);
365365
inline frame(intptr_t* sp, address pc, intptr_t* unextended_sp, intptr_t* fp = nullptr, CodeBlob* cb = nullptr);
366-
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map);
366+
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map = nullptr);
367367
inline frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, const ImmutableOopMap* oop_map, bool on_heap);
368368

369369
private:

src/hotspot/cpu/ppc/frame_ppc.inline.hpp

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2012, 2024 SAP SE. All rights reserved.
2+
* Copyright (c) 2000, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -391,4 +391,43 @@ void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr)
391391
// Nothing to do.
392392
}
393393

394+
#if INCLUDE_JFR
395+
396+
// Static helper routines
397+
inline intptr_t* frame::sender_sp(intptr_t* fp) { return fp; }
398+
399+
// Extract common_abi parts.
400+
inline intptr_t* frame::fp(const intptr_t* sp) {
401+
assert(sp != nullptr, "invariant");
402+
return reinterpret_cast<intptr_t*>(((common_abi*)sp)->callers_sp);
403+
}
404+
405+
inline intptr_t* frame::link(const intptr_t* fp) { return frame::fp(fp); }
406+
407+
inline address frame::return_address(const intptr_t* sp) {
408+
assert(sp != nullptr, "invariant");
409+
return reinterpret_cast<address>(((common_abi*)sp)->lr);
410+
}
411+
412+
inline address frame::interpreter_return_address(const intptr_t* fp) { return frame::return_address(fp); }
413+
414+
// Extract java interpreter state parts.
415+
inline address frame::interpreter_bcp(const intptr_t* fp) {
416+
assert(fp != nullptr, "invariant");
417+
return reinterpret_cast<address>(*(fp + ijava_idx(bcp)));
418+
}
419+
420+
inline intptr_t* frame::interpreter_sender_sp(const intptr_t* fp) {
421+
assert(fp != nullptr, "invariant");
422+
return reinterpret_cast<intptr_t*>(*(fp + ijava_idx(sender_sp)));
423+
}
424+
425+
inline bool frame::is_interpreter_frame_setup_at(const intptr_t* fp, const void* sp) {
426+
assert(fp != nullptr, "invariant");
427+
assert(sp != nullptr, "invariant");
428+
return sp <= fp - ((frame::ijava_state_size + frame::top_ijava_frame_abi_size) >> LogBytesPerWord);
429+
}
430+
431+
#endif // INCLUDE_JFR
432+
394433
#endif // CPU_PPC_FRAME_PPC_INLINE_HPP

src/hotspot/cpu/ppc/interp_masm_ppc.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2012, 2023 SAP SE. All rights reserved.
2+
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -170,7 +170,11 @@ class InterpreterMacroAssembler: public MacroAssembler {
170170
void remove_activation(TosState state,
171171
bool throw_monitor_exception = true,
172172
bool install_monitor_exception = true);
173-
void merge_frames(Register Rtop_frame_sp, Register return_pc, Register Rscratch1, Register Rscratch2); // merge top frames
173+
JFR_ONLY(void enter_jfr_critical_section();)
174+
JFR_ONLY(void leave_jfr_critical_section();)
175+
void load_fp(Register fp);
176+
void remove_top_frame_given_fp(Register fp, Register sender_sp, Register sender_fp, Register return_pc, Register temp);
177+
void merge_frames(Register sender_sp, Register return_pc, Register temp1, Register temp2); // merge top frames
174178

175179
void add_monitor_to_stack(bool stack_is_empty, Register Rtemp1, Register Rtemp2);
176180

src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -793,19 +793,27 @@ void InterpreterMacroAssembler::unlock_if_synchronized_method(TosState state,
793793
}
794794

795795
// Support function for remove_activation & Co.
796-
void InterpreterMacroAssembler::merge_frames(Register Rsender_sp, Register return_pc,
797-
Register Rscratch1, Register Rscratch2) {
798-
// Pop interpreter frame.
799-
ld(Rscratch1, 0, R1_SP); // *SP
800-
ld(Rsender_sp, _ijava_state_neg(sender_sp), Rscratch1); // top_frame_sp
801-
ld(Rscratch2, 0, Rscratch1); // **SP
802-
if (return_pc!=noreg) {
803-
ld(return_pc, _abi0(lr), Rscratch1); // LR
796+
void InterpreterMacroAssembler::load_fp(Register fp) {
797+
ld(fp, _abi0(callers_sp), R1_SP); // *SP
798+
}
799+
800+
void InterpreterMacroAssembler::remove_top_frame_given_fp(Register fp, Register sender_sp, Register sender_fp,
801+
Register return_pc, Register temp) {
802+
assert_different_registers(sender_sp, sender_fp, return_pc, temp);
803+
ld(sender_sp, _ijava_state_neg(sender_sp), fp);
804+
ld(sender_fp, _abi0(callers_sp), fp); // **SP
805+
if (return_pc != noreg) {
806+
ld(return_pc, _abi0(lr), fp); // last usage of fp, register can be reused
804807
}
808+
subf(temp, R1_SP, sender_sp); // sender_sp - SP
809+
stdux(sender_fp, R1_SP, temp); // atomically set *(SP = sender_sp) = sender_fp
810+
}
805811

806-
// Merge top frames.
807-
subf(Rscratch1, R1_SP, Rsender_sp); // top_frame_sp - SP
808-
stdux(Rscratch2, R1_SP, Rscratch1); // atomically set *(SP = top_frame_sp) = **SP
812+
void InterpreterMacroAssembler::merge_frames(Register sender_sp, Register return_pc,
813+
Register temp1, Register temp2) {
814+
Register fp = temp1, sender_fp = temp2;
815+
load_fp(fp);
816+
remove_top_frame_given_fp(fp, sender_sp, sender_fp, return_pc, /* temp */ fp);
809817
}
810818

811819
void InterpreterMacroAssembler::narrow(Register result) {
@@ -864,11 +872,16 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
864872
bool install_monitor_exception) {
865873
BLOCK_COMMENT("remove_activation {");
866874

875+
unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
876+
867877
// The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
868878
// that would normally not be safe to use. Such bad returns into unsafe territory of
869879
// the stack, will call InterpreterRuntime::at_unwind.
870-
Label slow_path;
871-
Label fast_path;
880+
Label slow_path, fast_path;
881+
Register fp = R22_tmp2;
882+
load_fp(fp);
883+
884+
JFR_ONLY(enter_jfr_critical_section();)
872885
safepoint_poll(slow_path, R11_scratch1, true /* at_return */, false /* in_nmethod */);
873886
b(fast_path);
874887
bind(slow_path);
@@ -880,8 +893,6 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
880893
align(32);
881894
bind(fast_path);
882895

883-
unlock_if_synchronized_method(state, throw_monitor_exception, install_monitor_exception);
884-
885896
// Save result (push state before jvmti call and pop it afterwards) and notify jvmti.
886897
notify_method_exit(false, state, NotifyJVMTI, true);
887898

@@ -901,10 +912,11 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
901912
// call could have a smaller SP, so that this compare succeeds for an
902913
// inner call of the method annotated with ReservedStack.
903914
ld_ptr(R0, JavaThread::reserved_stack_activation_offset(), R16_thread);
904-
ld_ptr(R11_scratch1, _abi0(callers_sp), R1_SP); // Load frame pointer.
905-
cmpld(CR0, R11_scratch1, R0);
915+
cmpld(CR0, fp, R0);
906916
blt_predict_taken(CR0, no_reserved_zone_enabling);
907917

918+
JFR_ONLY(leave_jfr_critical_section();)
919+
908920
// Enable reserved zone again, throw stack overflow exception.
909921
call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::enable_stack_reserved_zone), R16_thread);
910922
call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_delayed_StackOverflowError));
@@ -916,12 +928,26 @@ void InterpreterMacroAssembler::remove_activation(TosState state,
916928

917929
verify_oop(R17_tos, state);
918930

919-
merge_frames(/*top_frame_sp*/ R21_sender_SP, /*return_pc*/ R0, R11_scratch1, R12_scratch2);
931+
remove_top_frame_given_fp(fp, R21_sender_SP, R23_tmp3, /*return_pc*/ R0, R11_scratch1);
920932
mtlr(R0);
921933
pop_cont_fastpath();
934+
JFR_ONLY(leave_jfr_critical_section();)
935+
922936
BLOCK_COMMENT("} remove_activation");
923937
}
924938

939+
#if INCLUDE_JFR
940+
void InterpreterMacroAssembler::enter_jfr_critical_section() {
941+
li(R0, 1);
942+
stb(R0, in_bytes(SAMPLING_CRITICAL_SECTION_OFFSET_JFR), R16_thread);
943+
}
944+
945+
void InterpreterMacroAssembler::leave_jfr_critical_section() {
946+
li(R0, 0);
947+
stb(R0, in_bytes(SAMPLING_CRITICAL_SECTION_OFFSET_JFR), R16_thread);
948+
}
949+
#endif // INCLUDE_JFR
950+
925951
// Lock object
926952
//
927953
// Registers alive

src/hotspot/cpu/ppc/javaFrameAnchor_ppc.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
2-
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
3-
* Copyright (c) 2012, 2014 SAP SE. All rights reserved.
2+
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2012, 2025 SAP SE. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
66
* This code is free software; you can redistribute it and/or modify it
@@ -73,6 +73,8 @@
7373

7474
address last_Java_pc(void) { return _last_Java_pc; }
7575

76+
intptr_t* last_Java_fp() const { return *(intptr_t**)_last_Java_sp; }
77+
7678
void set_last_Java_sp(intptr_t* sp) { OrderAccess::release(); _last_Java_sp = sp; }
7779

7880
#endif // CPU_PPC_JAVAFRAMEANCHOR_PPC_HPP

src/hotspot/cpu/ppc/macroAssembler_ppc.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3342,6 +3342,35 @@ void MacroAssembler::safepoint_poll(Label& slow_path, Register temp, bool at_ret
33423342
}
33433343
}
33443344

3345+
void MacroAssembler::jump_to_polling_page_return_handler_blob(int safepoint_offset, bool fixed_size) {
3346+
assert(SharedRuntime::polling_page_return_handler_blob() != nullptr,
3347+
"polling page return stub not created yet");
3348+
address stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
3349+
3350+
// Determine saved exception pc using pc relative address computation.
3351+
{
3352+
Label next_pc;
3353+
bl(next_pc);
3354+
bind(next_pc);
3355+
}
3356+
int current_offset = offset();
3357+
3358+
if (fixed_size) {
3359+
// Code size must not depend on offsets.
3360+
load_const32(R12, safepoint_offset - current_offset);
3361+
mflr(R0);
3362+
add(R12, R12, R0);
3363+
} else {
3364+
mflr(R12);
3365+
add_const_optimized(R12, R12, safepoint_offset - current_offset);
3366+
}
3367+
std(R12, in_bytes(JavaThread::saved_exception_pc_offset()), R16_thread);
3368+
3369+
add_const_optimized(R0, R29_TOC, MacroAssembler::offset_to_global_toc(stub));
3370+
mtctr(R0);
3371+
bctr();
3372+
}
3373+
33453374
void MacroAssembler::resolve_jobject(Register value, Register tmp1, Register tmp2,
33463375
MacroAssembler::PreservationLevel preservation_level) {
33473376
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();

src/hotspot/cpu/ppc/macroAssembler_ppc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,7 @@ class MacroAssembler: public Assembler {
731731

732732
// Check if safepoint requested and if so branch
733733
void safepoint_poll(Label& slow_path, Register temp, bool at_return, bool in_nmethod);
734+
void jump_to_polling_page_return_handler_blob(int safepoint_offset, bool fixed_size = false);
734735

735736
void resolve_jobject(Register value, Register tmp1, Register tmp2,
736737
MacroAssembler::PreservationLevel preservation_level);

src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,30 +2740,45 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
27402740
__ li(r_temp_2, 0);
27412741
__ stw(r_temp_2, in_bytes(JNIHandleBlock::top_offset()), r_temp_1);
27422742

2743+
// Prepare for return
2744+
// --------------------------------------------------------------------------
2745+
__ pop_frame();
2746+
__ restore_LR(R11);
2747+
2748+
#if INCLUDE_JFR
2749+
// We need to do a poll test after unwind in case the sampler
2750+
// managed to sample the native frame after returning to Java.
2751+
Label L_stub;
2752+
int safepoint_offset = __ offset();
2753+
if (!UseSIGTRAP) {
2754+
__ relocate(relocInfo::poll_return_type);
2755+
}
2756+
__ safepoint_poll(L_stub, r_temp_2, true /* at_return */, true /* in_nmethod: frame already popped */);
2757+
#endif // INCLUDE_JFR
27432758

27442759
// Check for pending exceptions.
27452760
// --------------------------------------------------------------------------
27462761
__ ld(r_temp_2, thread_(pending_exception));
27472762
__ cmpdi(CR0, r_temp_2, 0);
27482763
__ bne(CR0, handle_pending_exception);
27492764

2750-
// Return
2751-
// --------------------------------------------------------------------------
2752-
2753-
__ pop_frame();
2754-
__ restore_LR(R11);
2765+
// Return.
27552766
__ blr();
27562767

2768+
// Handler for return safepoint (out-of-line).
2769+
#if INCLUDE_JFR
2770+
if (!UseSIGTRAP) {
2771+
__ bind(L_stub);
2772+
__ jump_to_polling_page_return_handler_blob(safepoint_offset);
2773+
}
2774+
#endif // INCLUDE_JFR
27572775

27582776
// Handler for pending exceptions (out-of-line).
27592777
// --------------------------------------------------------------------------
27602778
// Since this is a native call, we know the proper exception handler
27612779
// is the empty function. We just pop this frame and then jump to
27622780
// forward_exception_entry.
27632781
__ bind(handle_pending_exception);
2764-
2765-
__ pop_frame();
2766-
__ restore_LR(R11);
27672782
__ b64_patchable((address)StubRoutines::forward_exception_entry(),
27682783
relocInfo::runtime_call_type);
27692784

0 commit comments

Comments
 (0)