< prev index next > src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp
Print this page
/*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
if (real_unextended_sp != nullptr) {
f.set_unextended_sp(real_unextended_sp); // can be null at a safepoint
}
}
+ inline void FreezeBase::prepare_freeze_interpreted_top_frame(frame& f) {
+ assert(f.interpreter_frame_last_sp() == nullptr, "should be null for top frame");
+ f.interpreter_frame_set_last_sp(f.unextended_sp());
+ }
+
inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, const frame& hf) {
assert(hf.fp() == hf.unextended_sp() + (f.fp() - f.unextended_sp()), "");
assert((f.at(frame::interpreter_frame_last_sp_offset) != 0)
|| (f.unextended_sp() == f.sp()), "");
assert(f.fp() > (intptr_t*)f.at_relative(frame::interpreter_frame_initial_sp_offset), "");
assert(hf.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
// extended_sp is already relativized by TemplateInterpreterGenerator::generate_normal_entry or
// AbstractInterpreter::layout_activation
+ // The interpreter native wrapper code adds space in the stack equal to size_of_parameters()
+ // after the fixed part of the frame. For wait0 this is equal to 3 words (this + long parameter).
+ // We adjust by this size since otherwise the saved last sp will be less than the extended_sp.
+ DEBUG_ONLY(Method* m = hf.interpreter_frame_method();)
+ DEBUG_ONLY(int extra_space = m->is_object_wait0() ? m->size_of_parameters() : 0;)
+
assert((hf.fp() - hf.unextended_sp()) == (f.fp() - f.unextended_sp()), "");
assert(hf.unextended_sp() == (intptr_t*)hf.at(frame::interpreter_frame_last_sp_offset), "");
assert(hf.unextended_sp() <= (intptr_t*)hf.at(frame::interpreter_frame_initial_sp_offset), "");
- assert(hf.unextended_sp() > (intptr_t*)hf.at(frame::interpreter_frame_extended_sp_offset), "");
+ assert(hf.unextended_sp() + extra_space > (intptr_t*)hf.at(frame::interpreter_frame_extended_sp_offset), "");
assert(hf.fp() > (intptr_t*)hf.at(frame::interpreter_frame_initial_sp_offset), "");
assert(hf.fp() <= (intptr_t*)hf.at(frame::interpreter_frame_locals_offset), "");
}
inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) {
if (FKind::interpreted) {
intptr_t* heap_sp = hf.unextended_sp();
// If caller is interpreted it already made room for the callee arguments
int overlap = caller.is_interpreted_frame() ? ContinuationHelper::InterpretedFrame::stack_argsize(hf) : 0;
const int fsize = (int)(ContinuationHelper::InterpretedFrame::frame_bottom(hf) - hf.unextended_sp() - overlap);
- const int locals = hf.interpreter_frame_method()->max_locals();
intptr_t* frame_sp = caller.unextended_sp() - fsize;
intptr_t* fp = frame_sp + (hf.fp() - heap_sp);
if ((intptr_t)fp % frame::frame_alignment != 0) {
fp--;
frame_sp--;
return f;
} else {
int fsize = FKind::size(hf);
intptr_t* frame_sp = caller.unextended_sp() - fsize;
if (bottom || caller.is_interpreted_frame()) {
- int argsize = hf.compiled_frame_stack_argsize();
+ int argsize = FKind::stack_argsize(hf);
fsize += argsize;
frame_sp -= argsize;
caller.set_sp(caller.sp() - argsize);
assert(caller.sp() == frame_sp + (fsize-argsize), "");
intptr_t* fp;
if (PreserveFramePointer) {
// we need to recreate a "real" frame pointer, pointing into the stack
fp = frame_sp + FKind::size(hf) - frame::sender_sp_offset;
} else {
- fp = FKind::stub
- ? frame_sp + fsize - frame::sender_sp_offset // on AArch64, this value is used for the safepoint stub
+ fp = FKind::stub || FKind::native
+ ? frame_sp + fsize - frame::sender_sp_offset // fp always points to the address below the pushed return pc. We need correct address.
: *(intptr_t**)(hf.sp() - frame::sender_sp_offset); // we need to re-read fp because it may be an oop and we might have fixed the frame.
}
return frame(frame_sp, frame_sp, fp, hf.pc(), hf.cb(), hf.oop_map(), false); // TODO PERF : this computes deopt state; is it necessary?
}
}
inline void ThawBase::patch_pd(frame& f, const frame& caller) {
patch_callee_link(caller, caller.fp());
}
+ inline void ThawBase::patch_pd(frame& f, intptr_t* caller_sp) {
+ intptr_t* fp = caller_sp - frame::sender_sp_offset;
+ patch_callee_link(f, fp);
+ }
+
+ inline intptr_t* ThawBase::push_cleanup_continuation() {
+ frame enterSpecial = new_entry_frame();
+ intptr_t* sp = enterSpecial.sp();
+
+ sp[-1] = (intptr_t)ContinuationEntry::cleanup_pc();
+ sp[-2] = (intptr_t)enterSpecial.fp();
+
+ log_develop_trace(continuations, preempt)("push_cleanup_continuation initial sp: " INTPTR_FORMAT " final sp: " INTPTR_FORMAT, p2i(sp + 2 * frame::metadata_words), p2i(sp));
+ return sp;
+ }
+
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
// Make sure that last_sp is kept relativized.
assert((intptr_t*)f.at_relative(frame::interpreter_frame_last_sp_offset) == f.unextended_sp(), "");
// Make sure that monitor_block_top is still relativized.
assert(f.at_absolute(frame::interpreter_frame_monitor_block_top_offset) <= frame::interpreter_frame_initial_sp_offset, "");
// Make sure that extended_sp is kept relativized.
- assert((intptr_t*)f.at_relative(frame::interpreter_frame_extended_sp_offset) < f.unextended_sp(), "");
+ DEBUG_ONLY(Method* m = hf.interpreter_frame_method();)
+ DEBUG_ONLY(int extra_space = m->is_object_wait0() ? m->size_of_parameters() : 0;) // see comment in relativize_interpreted_frame_metadata()
+ assert((intptr_t*)f.at_relative(frame::interpreter_frame_extended_sp_offset) < f.unextended_sp() + extra_space, "");
}
#endif // CPU_AARCH64_CONTINUATIONFREEZETHAW_AARCH64_INLINE_HPP
< prev index next >