< prev index next >

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

Print this page

 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #ifndef CPU_AARCH64_FRAME_AARCH64_INLINE_HPP
 27 #define CPU_AARCH64_FRAME_AARCH64_INLINE_HPP
 28 
 29 #include "code/codeBlob.inline.hpp"
 30 #include "code/codeCache.inline.hpp"
 31 #include "code/vmreg.inline.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "runtime/sharedRuntime.hpp"
 34 #include "pauth_aarch64.hpp"



 35 
 36 // Inline functions for AArch64 frames:
 37 
 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]);

424     return map->stack_chunk()->sender(*this, map);
425   }
426 
427   if (is_entry_frame())       return sender_for_entry_frame(map);
428   if (is_upcall_stub_frame()) return sender_for_upcall_stub_frame(map);
429   if (is_interpreted_frame()) return sender_for_interpreter_frame(map);
430 
431   assert(_cb == CodeCache::find_blob(pc()), "Must be the same");
432   if (_cb != nullptr) return sender_for_compiled_frame(map);
433 
434   // Must be native-compiled frame, i.e. the marshaling code for native
435   // methods that exists in the core system.
436 
437   // Native code may or may not have signed the return address, we have no way to be sure or what
438   // signing methods they used. Instead, just ensure the stripped value is used.
439 
440   return frame(sender_sp(), link(), sender_pc());
441 }
442 
443 inline frame frame::sender_for_compiled_frame(RegisterMap* map) const {
444   // we cannot rely upon the last fp having been saved to the thread
445   // in C2 code but it will have been pushed onto the stack. so we
446   // have to find it relative to the unextended sp
447 
448   assert(_cb->frame_size() > 0, "must have non-zero frame size");
449   intptr_t* l_sender_sp = (!PreserveFramePointer || _sp_is_trusted) ? unextended_sp() + _cb->frame_size()
450                                                                     : sender_sp();
451   assert(!_sp_is_trusted || l_sender_sp == real_fp(), "");
452 
453   // The return_address is always the word on the stack.
454   // For ROP protection, C1/C2 will have signed the sender_pc,
455   // but there is no requirement to authenticate it here.
456   address sender_pc = pauth_strip_verifiable((address) *(l_sender_sp - 1));
457 
458   intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp - frame::sender_sp_offset);
459 
460   if (map->update_map()) {
461     // Tell GC to use argument oopmaps for some runtime stubs that need it.
462     // For C1, the runtime stub might not have oop maps, so set this flag
463     // outside of update_register_map.
464     if (!_cb->is_nmethod()) { // compiled frames do not use callee-saved registers
465       map->set_include_argument_oops(_cb->caller_must_gc_arguments(map->thread()));













466       if (oop_map() != nullptr) {
467         _oop_map->update_register_map(this, map);
468       }
469     } else {
470       assert(!_cb->caller_must_gc_arguments(map->thread()), "");
471       assert(!map->include_argument_oops(), "");
472       assert(oop_map() == nullptr || !oop_map()->has_any(OopMapValue::callee_saved_value), "callee-saved value in compiled frame");
473     }
474 
475     // Since the prolog does the save and restore of FP there is no oopmap
476     // for it so we must fill in its location as if there was an oopmap entry
477     // since if our caller was compiled code there could be live jvm state in it.
478     update_map_with_saved_link(map, saved_fp_addr);
479   }
480 
481   if (Continuation::is_return_barrier_entry(sender_pc)) {
482     if (map->walk_cont()) { // about to walk into an h-stack
483       return Continuation::top_frame(*this, map);
484     } else {
485       return Continuation::continuation_bottom_sender(map->thread(), *this, l_sender_sp);
486     }
487   }
488 
489   intptr_t* unextended_sp = l_sender_sp;
490   return frame(l_sender_sp, unextended_sp, *saved_fp_addr, sender_pc);
491 }
492 
493 template <typename RegisterMapT>
494 void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr) {
495   // The interpreter and compiler(s) always save FP in a known
496   // location on entry. C2-compiled code uses FP as an allocatable
497   // callee-saved register. We must record where that location is so
498   // that if FP was live on callout from c2 we can find the saved copy.
499 
500   map->set_location(rfp->as_VMReg(), (address) link_addr);
501   // this is weird "H" ought to be at a higher address however the
502   // oopMaps seems to have the "H" regs at the same address and the
503   // vanilla register.
504   // XXXX make this go away
505   if (true) {
506     map->set_location(rfp->as_VMReg()->next(), (address) link_addr);
507   }
508 }
509 #endif // CPU_AARCH64_FRAME_AARCH64_INLINE_HPP

 15  *
 16  * You should have received a copy of the GNU General Public License version
 17  * 2 along with this work; if not, write to the Free Software Foundation,
 18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 19  *
 20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 21  * or visit www.oracle.com if you need additional information or have any
 22  * questions.
 23  *
 24  */
 25 
 26 #ifndef CPU_AARCH64_FRAME_AARCH64_INLINE_HPP
 27 #define CPU_AARCH64_FRAME_AARCH64_INLINE_HPP
 28 
 29 #include "code/codeBlob.inline.hpp"
 30 #include "code/codeCache.inline.hpp"
 31 #include "code/vmreg.inline.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "runtime/sharedRuntime.hpp"
 34 #include "pauth_aarch64.hpp"
 35 #ifdef COMPILER1
 36 #include "c1/c1_Runtime1.hpp"
 37 #endif
 38 
 39 // Inline functions for AArch64 frames:
 40 
 41 #if INCLUDE_JFR
 42 
 43 // Static helper routines
 44 
 45 inline address frame::interpreter_bcp(const intptr_t* fp) {
 46   assert(fp != nullptr, "invariant");
 47   return reinterpret_cast<address>(fp[frame::interpreter_frame_bcp_offset]);
 48 }
 49 
 50 inline address frame::interpreter_return_address(const intptr_t* fp) {
 51   assert(fp != nullptr, "invariant");
 52   return reinterpret_cast<address>(fp[frame::return_addr_offset]);
 53 }
 54 
 55 inline intptr_t* frame::interpreter_sender_sp(const intptr_t* fp) {
 56   assert(fp != nullptr, "invariant");
 57   return reinterpret_cast<intptr_t*>(fp[frame::interpreter_frame_sender_sp_offset]);

427     return map->stack_chunk()->sender(*this, map);
428   }
429 
430   if (is_entry_frame())       return sender_for_entry_frame(map);
431   if (is_upcall_stub_frame()) return sender_for_upcall_stub_frame(map);
432   if (is_interpreted_frame()) return sender_for_interpreter_frame(map);
433 
434   assert(_cb == CodeCache::find_blob(pc()), "Must be the same");
435   if (_cb != nullptr) return sender_for_compiled_frame(map);
436 
437   // Must be native-compiled frame, i.e. the marshaling code for native
438   // methods that exists in the core system.
439 
440   // Native code may or may not have signed the return address, we have no way to be sure or what
441   // signing methods they used. Instead, just ensure the stripped value is used.
442 
443   return frame(sender_sp(), link(), sender_pc());
444 }
445 
446 inline frame frame::sender_for_compiled_frame(RegisterMap* map) const {
447   CompiledFramePointers cfp = compiled_frame_details();







448 
449   // The return_address is always the word on the stack.
450   // For ROP protection, C1/C2 will have signed the sender_pc,
451   // but there is no requirement to authenticate it here.
452   address sender_pc = pauth_strip_verifiable(*cfp.sender_pc_addr);


453 
454   if (map->update_map()) {
455     // Tell GC to use argument oopmaps for some runtime stubs that need it.
456     // For C1, the runtime stub might not have oop maps, so set this flag
457     // outside of update_register_map.
458     bool c1_buffering = false;
459 #ifdef COMPILER1
460     nmethod* nm = _cb->as_nmethod_or_null();
461     if (nm != nullptr && nm->is_compiled_by_c1() && nm->method()->has_scalarized_args() &&
462         pc() < nm->verified_inline_entry_point()) {
463       // 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'?
464       // The VEP and VIEP(RO) of C1-compiled methods call buffer_inline_args_xxx
465       // before doing any argument shuffling, so we need to scan the oops
466       // as the caller passes them.
467       c1_buffering = true;
468     }
469 #endif
470     if (!_cb->is_nmethod() || c1_buffering) { // compiled frames do not use callee-saved registers
471       bool caller_args = _cb->caller_must_gc_arguments(map->thread()) || c1_buffering;
472       map->set_include_argument_oops(caller_args);
473       if (oop_map() != nullptr) {
474         _oop_map->update_register_map(this, map);
475       }
476     } else {
477       assert(!_cb->caller_must_gc_arguments(map->thread()), "");
478       assert(!map->include_argument_oops(), "");
479       assert(oop_map() == nullptr || !oop_map()->has_any(OopMapValue::callee_saved_value), "callee-saved value in compiled frame");
480     }
481 
482     // Since the prolog does the save and restore of FP there is no oopmap
483     // for it so we must fill in its location as if there was an oopmap entry
484     // since if our caller was compiled code there could be live jvm state in it.
485     update_map_with_saved_link(map, cfp.saved_fp_addr);
486   }
487 
488   if (Continuation::is_return_barrier_entry(sender_pc)) {
489     if (map->walk_cont()) { // about to walk into an h-stack
490       return Continuation::top_frame(*this, map);
491     } else {
492       return Continuation::continuation_bottom_sender(map->thread(), *this, cfp.sender_sp);
493     }
494   }
495 
496   intptr_t* unextended_sp = cfp.sender_sp;
497   return frame(cfp.sender_sp, unextended_sp, *cfp.saved_fp_addr, sender_pc);
498 }
499 
500 template <typename RegisterMapT>
501 void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr) {
502   // The interpreter and compiler(s) always save FP in a known
503   // location on entry. C2-compiled code uses FP as an allocatable
504   // callee-saved register. We must record where that location is so
505   // that if FP was live on callout from c2 we can find the saved copy.
506 
507   map->set_location(rfp->as_VMReg(), (address) link_addr);
508   // this is weird "H" ought to be at a higher address however the
509   // oopMaps seems to have the "H" regs at the same address and the
510   // vanilla register.
511   // XXXX make this go away
512   if (true) {
513     map->set_location(rfp->as_VMReg()->next(), (address) link_addr);
514   }
515 }
516 #endif // CPU_AARCH64_FRAME_AARCH64_INLINE_HPP
< prev index next >