< prev index next > src/hotspot/cpu/aarch64/frame_aarch64.inline.hpp
Print this page
#include "code/codeCache.inline.hpp"
#include "code/vmreg.inline.hpp"
#include "interpreter/interpreter.hpp"
#include "runtime/sharedRuntime.hpp"
#include "pauth_aarch64.hpp"
+ #ifdef COMPILER1
+ #include "c1/c1_Runtime1.hpp"
+ #endif
// Inline functions for AArch64 frames:
#if INCLUDE_JFR
return frame(sender_sp(), link(), sender_pc());
}
inline frame frame::sender_for_compiled_frame(RegisterMap* map) const {
- // we cannot rely upon the last fp having been saved to the thread
- // in C2 code but it will have been pushed onto the stack. so we
- // have to find it relative to the unextended sp
-
- assert(_cb->frame_size() > 0, "must have non-zero frame size");
- intptr_t* l_sender_sp = (!PreserveFramePointer || _sp_is_trusted) ? unextended_sp() + _cb->frame_size()
- : sender_sp();
- assert(!_sp_is_trusted || l_sender_sp == real_fp(), "");
+ CompiledFramePointers cfp = compiled_frame_details();
// The return_address is always the word on the stack.
// For ROP protection, C1/C2 will have signed the sender_pc,
// but there is no requirement to authenticate it here.
- address sender_pc = pauth_strip_verifiable((address) *(l_sender_sp - 1));
-
- intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp - frame::sender_sp_offset);
+ address sender_pc = pauth_strip_verifiable(*cfp.sender_pc_addr);
if (map->update_map()) {
// Tell GC to use argument oopmaps for some runtime stubs that need it.
// For C1, the runtime stub might not have oop maps, so set this flag
// outside of update_register_map.
- if (!_cb->is_nmethod()) { // compiled frames do not use callee-saved registers
- map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));
+ bool c1_buffering = false;
+ #ifdef COMPILER1
+ nmethod* nm = _cb->as_nmethod_or_null();
+ if (nm != nullptr && nm->is_compiled_by_c1() && nm->method()->has_scalarized_args() &&
+ pc() < nm->verified_inline_entry_point()) {
+ // TODO 8284443 Can't we do that by not passing 'dont_gc_arguments' in case 'StubId::c1_buffer_inline_args_id' in 'Runtime1::generate_code_for'?
+ // The VEP and VIEP(RO) of C1-compiled methods call buffer_inline_args_xxx
+ // before doing any argument shuffling, so we need to scan the oops
+ // as the caller passes them.
+ c1_buffering = true;
+ }
+ #endif
+ if (!_cb->is_nmethod() || c1_buffering) { // compiled frames do not use callee-saved registers
+ bool caller_args = _cb->caller_must_gc_arguments(map->thread()) || c1_buffering;
+ map->set_include_argument_oops(caller_args);
if (oop_map() != nullptr) {
_oop_map->update_register_map(this, map);
}
} else {
assert(!_cb->caller_must_gc_arguments(map->thread()), "");
}
// Since the prolog does the save and restore of FP there is no oopmap
// for it so we must fill in its location as if there was an oopmap entry
// since if our caller was compiled code there could be live jvm state in it.
- update_map_with_saved_link(map, saved_fp_addr);
+ update_map_with_saved_link(map, cfp.saved_fp_addr);
}
if (Continuation::is_return_barrier_entry(sender_pc)) {
if (map->walk_cont()) { // about to walk into an h-stack
return Continuation::top_frame(*this, map);
} else {
- return Continuation::continuation_bottom_sender(map->thread(), *this, l_sender_sp);
+ return Continuation::continuation_bottom_sender(map->thread(), *this, cfp.sender_sp);
}
}
- intptr_t* unextended_sp = l_sender_sp;
- return frame(l_sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
+ intptr_t* unextended_sp = cfp.sender_sp;
+ return frame(cfp.sender_sp, unextended_sp, *cfp.saved_fp_addr, sender_pc);
}
template <typename RegisterMapT>
void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr) {
// The interpreter and compiler(s) always save FP in a known
< prev index next >