Skip to content

Commit ca5efaa

Browse files
committed
community
1 parent 9927ec0 commit ca5efaa

File tree

86 files changed

+2497
-1261
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+2497
-1261
lines changed

src/hotspot/cpu/aarch64/frame_aarch64.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,6 @@ void JavaFrameAnchor::make_walkable() {
828828
// already walkable?
829829
if (walkable()) return;
830830
vmassert(last_Java_sp() != nullptr, "not called from Java code?");
831-
vmassert(last_Java_pc() == nullptr, "already walkable");
832831
_last_Java_pc = (address)_last_Java_sp[-1];
833832
vmassert(walkable(), "something went wrong");
834833
}

src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,53 @@
3535

3636
// Inline functions for AArch64 frames:
3737

38+
#if INCLUDE_JFR
39+
40+
// Static helper routines
41+
42+
inline address frame::interpreter_bcp(const intptr_t* fp) {
43+
assert(fp != nullptr, "invariant");
44+
return reinterpret_cast<address>(fp[frame::interpreter_frame_bcp_offset]);
45+
}
46+
47+
inline address frame::interpreter_return_address(const intptr_t* fp) {
48+
assert(fp != nullptr, "invariant");
49+
return reinterpret_cast<address>(fp[frame::return_addr_offset]);
50+
}
51+
52+
inline intptr_t* frame::interpreter_sender_sp(const intptr_t* fp) {
53+
assert(fp != nullptr, "invariant");
54+
return reinterpret_cast<intptr_t*>(fp[frame::interpreter_frame_sender_sp_offset]);
55+
}
56+
57+
inline bool frame::is_interpreter_frame_setup_at(const intptr_t* fp, const void* sp) {
58+
assert(fp != nullptr, "invariant");
59+
assert(sp != nullptr, "invariant");
60+
return sp <= fp + frame::interpreter_frame_initial_sp_offset;
61+
}
62+
63+
inline intptr_t* frame::sender_sp(intptr_t* fp) {
64+
assert(fp != nullptr, "invariant");
65+
return fp + frame::sender_sp_offset;
66+
}
67+
68+
inline intptr_t* frame::link(const intptr_t* fp) {
69+
assert(fp != nullptr, "invariant");
70+
return reinterpret_cast<intptr_t*>(fp[frame::link_offset]);
71+
}
72+
73+
inline address frame::return_address(const intptr_t* sp) {
74+
assert(sp != nullptr, "invariant");
75+
return reinterpret_cast<address>(sp[-1]);
76+
}
77+
78+
inline intptr_t* frame::fp(const intptr_t* sp) {
79+
assert(sp != nullptr, "invariant");
80+
return reinterpret_cast<intptr_t*>(sp[-2]);
81+
}
82+
83+
#endif // INCLUDE_JFR
84+
3885
// Constructors:
3986

4087
inline frame::frame() {

src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp

Lines changed: 95 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "prims/jvmtiExport.hpp"
4242
#include "prims/jvmtiThreadState.hpp"
4343
#include "runtime/basicLock.hpp"
44+
#include "runtime/continuationEntry.hpp"
4445
#include "runtime/frame.inline.hpp"
4546
#include "runtime/javaThread.hpp"
4647
#include "runtime/safepointMechanism.hpp"
@@ -456,11 +457,43 @@ void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
456457
dispatch_base(state, table);
457458
}
458459

460+
void InterpreterMacroAssembler::call_VM_with_sender_Java_fp_entry(address entry_point) {
461+
mov(c_rarg0, rthread);
462+
MacroAssembler::call_VM_leaf_base(entry_point, 0);
463+
}
464+
465+
void InterpreterMacroAssembler::set_last_Java_frame_with_sender_fp(Register last_java_sp,
466+
Register last_java_fp,
467+
address last_java_pc,
468+
Register scratch) {
469+
assert_different_registers(last_java_fp, rfp);
470+
471+
#if INCLUDE_JFR
472+
Label L_ljf, L_valid_rfp;
473+
cbnz(rfp, L_valid_rfp);
474+
mov(scratch, 1);
475+
str(scratch, Address(rthread, JavaThread::last_sender_Java_fp_offset()));
476+
b(L_ljf);
477+
bind(L_valid_rfp);
478+
str(rfp, Address(rthread, JavaThread::last_sender_Java_fp_offset()));
479+
bind(L_ljf);
480+
#endif
481+
482+
set_last_Java_frame(last_java_sp, last_java_fp, last_java_pc, scratch);
483+
}
484+
485+
void InterpreterMacroAssembler::reset_last_Java_frame_with_sender_fp(Register fp_reg) {
486+
// Restore the fp_reg.
487+
ldr(fp_reg, Address(rthread, JavaThread::last_Java_fp_offset()));
488+
reset_last_Java_frame(true);
489+
JFR_ONLY(str(zr, Address(rthread, JavaThread::last_sender_Java_fp_offset()));)
490+
}
491+
459492
// remove activation
460493
//
461-
// Apply stack watermark barrier.
462494
// Unlock the receiver if this is a synchronized method.
463495
// Unlock any Java monitors from synchronized blocks.
496+
// Apply stack watermark barrier.
464497
// Remove the activation from the stack.
465498
//
466499
// If there are locked Java monitors
@@ -470,30 +503,14 @@ void InterpreterMacroAssembler::dispatch_via(TosState state, address* table) {
470503
// installs IllegalMonitorStateException
471504
// Else
472505
// no error processing
473-
void InterpreterMacroAssembler::remove_activation(
474-
TosState state,
475-
bool throw_monitor_exception,
476-
bool install_monitor_exception,
477-
bool notify_jvmdi) {
506+
void InterpreterMacroAssembler::remove_activation(TosState state,
507+
bool throw_monitor_exception,
508+
bool install_monitor_exception,
509+
bool notify_jvmdi) {
478510
// Note: Registers r3 xmm0 may be in use for the
479511
// result check if synchronized method
480512
Label unlocked, unlock, no_unlock;
481513

482-
// The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
483-
// that would normally not be safe to use. Such bad returns into unsafe territory of
484-
// the stack, will call InterpreterRuntime::at_unwind.
485-
Label slow_path;
486-
Label fast_path;
487-
safepoint_poll(slow_path, true /* at_return */, false /* acquire */, false /* in_nmethod */);
488-
br(Assembler::AL, fast_path);
489-
bind(slow_path);
490-
push(state);
491-
set_last_Java_frame(esp, rfp, (address)pc(), rscratch1);
492-
super_call_VM_leaf(CAST_FROM_FN_PTR(address, InterpreterRuntime::at_unwind), rthread);
493-
reset_last_Java_frame(true);
494-
pop(state);
495-
bind(fast_path);
496-
497514
// get the value of _do_not_unlock_if_synchronized into r3
498515
const Address do_not_unlock_if_synchronized(rthread,
499516
in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()));
@@ -647,17 +664,70 @@ void InterpreterMacroAssembler::remove_activation(
647664
bind(no_reserved_zone_enabling);
648665
}
649666

650-
// restore sender esp
651-
mov(esp, rscratch2);
652-
// remove frame anchor
653-
leave();
667+
// For asynchronous profiling to work correctly, we must remove the
668+
// activation frame _before_ we test the method return safepoint poll.
669+
// This is equivalent to how it is done for compiled frames.
670+
// Removing an interpreter activation frame from a sampling perspective means
671+
// updating the frame link. But since we are unwinding the current frame,
672+
// we must save the current rfp in a temporary register, this_fp, for use
673+
// as the last java fp should we decide to unwind.
674+
// The asynchronous profiler will only see the updated rfp, either using the
675+
// CPU context or by reading the last_sender_Java_fp() field as part of the ljf.
676+
const Register this_fp = rscratch2;
677+
make_sender_fp_current(this_fp, rscratch1);
678+
679+
// The interpreter frame is now unwound from a sampling perspective,
680+
// meaning it sees the sender frame as the current frame from this point onwards.
681+
682+
// The below poll is for the stack watermark barrier. It allows fixing up frames lazily,
683+
// that would normally not be safe to use. Such bad returns into unsafe territory of
684+
// the stack, will call InterpreterRuntime::at_unwind.
685+
Label slow_path;
686+
Label fast_path;
687+
safepoint_poll(slow_path, this_fp, true /* at_return */, false /* acquire */, false /* in_nmethod */);
688+
br(Assembler::AL, fast_path);
689+
bind(slow_path);
690+
save_bcp(this_fp); // need to save bcp but not restore it.
691+
push(state);
692+
set_last_Java_frame_with_sender_fp(esp, this_fp, (address)pc(), rscratch1);
693+
call_VM_with_sender_Java_fp_entry(CAST_FROM_FN_PTR(address, InterpreterRuntime::at_unwind));
694+
reset_last_Java_frame_with_sender_fp(this_fp);
695+
pop(state);
696+
bind(fast_path);
697+
698+
ldr(esp, Address(this_fp, frame::interpreter_frame_sender_sp_offset * wordSize));
699+
ldr(lr, Address(this_fp, wordSize));
700+
authenticate_return_address();
701+
lea(sp, Address(this_fp, 2 * wordSize));
702+
654703
// If we're returning to interpreted code we will shortly be
655704
// adjusting SP to allow some space for ESP. If we're returning to
656705
// compiled code the saved sender SP was saved in sender_sp, so this
657706
// restores it.
658707
andr(sp, esp, -16);
659708
}
660709

710+
void InterpreterMacroAssembler::make_sender_fp_current(Register save_this_fp, Register tmp) {
711+
const Register return_addr = save_this_fp;
712+
const Register continuation_return_pc = tmp;
713+
const Register sender_sp = tmp;
714+
ldr(return_addr, Address(rfp, wordSize)); // return address
715+
// Load address of ContinuationEntry return pc
716+
lea(continuation_return_pc, ExternalAddress(ContinuationEntry::return_pc_address()));
717+
// Load the ContinuationEntry return pc
718+
ldr(continuation_return_pc, Address(continuation_return_pc));
719+
Label L_continuation, L_end;
720+
cmp(continuation_return_pc, return_addr);
721+
mov(save_this_fp, rfp); // Save current fp in temporary register.
722+
br(Assembler::EQ, L_continuation);
723+
ldr(rfp, Address(rfp)); // Update the frame link.
724+
b(L_end);
725+
bind(L_continuation);
726+
lea(sender_sp, Address(rfp, frame::sender_sp_offset * wordSize));
727+
ldr(rfp, Address(sender_sp, (int)(ContinuationEntry::size()))); // Update the frame link.
728+
bind(L_end);
729+
}
730+
661731
// Lock object
662732
//
663733
// Args:

src/hotspot/cpu/aarch64/interp_masm_aarch64.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -63,14 +63,27 @@ class InterpreterMacroAssembler: public MacroAssembler {
6363
Register arg_1);
6464
void restore_after_resume(bool is_native);
6565

66+
void call_VM_with_sender_Java_fp_entry(address entry_point);
67+
68+
void set_last_Java_frame_with_sender_fp(Register last_java_sp,
69+
Register last_java_fp,
70+
address last_java_pc,
71+
Register scratch);
72+
73+
void reset_last_Java_frame_with_sender_fp(Register fp_reg);
74+
6675
void jump_to_entry(address entry);
6776

6877
virtual void check_and_handle_popframe(Register java_thread);
6978
virtual void check_and_handle_earlyret(Register java_thread);
7079

7180
// Interpreter-specific registers
7281
void save_bcp() {
73-
str(rbcp, Address(rfp, frame::interpreter_frame_bcp_offset * wordSize));
82+
save_bcp(rfp);
83+
}
84+
85+
void save_bcp(Register fp_register) {
86+
str(rbcp, Address(fp_register, frame::interpreter_frame_bcp_offset * wordSize));
7487
}
7588

7689
void restore_bcp() {
@@ -225,6 +238,8 @@ class InterpreterMacroAssembler: public MacroAssembler {
225238
bool install_monitor_exception = true,
226239
bool notify_jvmdi = true);
227240

241+
void make_sender_fp_current(Register save_this_fp, Register tmp);
242+
228243
// FIXME: Give us a valid frame at a null check.
229244
virtual void null_check(Register reg, int offset = -1) {
230245
// #ifdef ASSERT

src/hotspot/cpu/aarch64/javaFrameAnchor_aarch64.hpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -26,12 +26,13 @@
2626
#ifndef CPU_AARCH64_JAVAFRAMEANCHOR_AARCH64_HPP
2727
#define CPU_AARCH64_JAVAFRAMEANCHOR_AARCH64_HPP
2828

29-
private:
29+
private:
3030

3131
// FP value associated with _last_Java_sp:
3232
intptr_t* volatile _last_Java_fp; // pointer is volatile not what it points to
33+
JFR_ONLY(intptr_t* volatile _last_sender_Java_fp;) // specialized field for when JFR samples an interpreter frame
3334

34-
public:
35+
public:
3536
// Each arch must define reset, save, restore
3637
// These are used by objects that only care about:
3738
// 1 - initializing a new state (thread creation, javaCalls)
@@ -44,6 +45,7 @@
4445
OrderAccess::release();
4546
_last_Java_fp = nullptr;
4647
_last_Java_pc = nullptr;
48+
JFR_ONLY(_last_sender_Java_fp = nullptr;)
4749
}
4850

4951
void copy(JavaFrameAnchor* src) {
@@ -59,6 +61,7 @@
5961
OrderAccess::release();
6062
}
6163
_last_Java_fp = src->_last_Java_fp;
64+
JFR_ONLY(_last_sender_Java_fp = src->_last_sender_Java_fp;)
6265
_last_Java_pc = src->_last_Java_pc;
6366
// Must be last so profiler will always see valid frame if has_last_frame() is true
6467
_last_Java_sp = src->_last_Java_sp;
@@ -72,16 +75,18 @@
7275

7376
address last_Java_pc(void) { return _last_Java_pc; }
7477

75-
private:
76-
77-
static ByteSize last_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); }
78-
79-
public:
78+
public:
8079

8180
void set_last_Java_sp(intptr_t* sp) { _last_Java_sp = sp; OrderAccess::release(); }
8281

83-
intptr_t* last_Java_fp(void) { return _last_Java_fp; }
82+
intptr_t* last_Java_fp() const { return _last_Java_fp; }
8483

8584
void set_last_Java_fp(intptr_t* fp) { _last_Java_fp = fp; }
8685

86+
JFR_ONLY(intptr_t* last_sender_Java_fp() const { return _last_sender_Java_fp; })
87+
88+
static ByteSize last_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_fp); }
89+
90+
JFR_ONLY(static ByteSize last_sender_Java_fp_offset() { return byte_offset_of(JavaFrameAnchor, _last_sender_Java_fp); })
91+
8792
#endif // CPU_AARCH64_JAVAFRAMEANCHOR_AARCH64_HPP

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,11 @@ address MacroAssembler::target_addr_for_insn_or_null(address insn_addr, unsigned
554554
}
555555

556556
void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod, Register tmp) {
557+
safepoint_poll(slow_path, rfp, at_return, acquire, in_nmethod, tmp);
558+
}
559+
560+
void MacroAssembler::safepoint_poll(Label& slow_path, Register fp_reg, bool at_return, bool acquire, bool in_nmethod, Register tmp) {
561+
assert(fp_reg != tmp, "invariant");
557562
if (acquire) {
558563
lea(tmp, Address(rthread, JavaThread::polling_word_offset()));
559564
ldar(tmp, tmp);
@@ -563,7 +568,7 @@ void MacroAssembler::safepoint_poll(Label& slow_path, bool at_return, bool acqui
563568
if (at_return) {
564569
// Note that when in_nmethod is set, the stack pointer is incremented before the poll. Therefore,
565570
// we may safely use the sp instead to perform the stack watermark check.
566-
cmp(in_nmethod ? sp : rfp, tmp);
571+
cmp(in_nmethod ? sp : fp_reg, tmp);
567572
br(Assembler::HI, slow_path);
568573
} else {
569574
tbnz(tmp, log2i_exact(SafepointMechanism::poll_bit()), slow_path);

src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ class MacroAssembler: public Assembler {
121121
virtual void check_and_handle_earlyret(Register java_thread);
122122

123123
void safepoint_poll(Label& slow_path, bool at_return, bool acquire, bool in_nmethod, Register tmp = rscratch1);
124+
void safepoint_poll(Label& slow_path, Register fp_reg, bool at_return, bool acquire, bool in_nmethod, Register tmp = rscratch1);
125+
124126
void rt_call(address dest, Register tmp = rscratch1);
125127

126128
// Load Effective Address

0 commit comments

Comments
 (0)