1 /* 2 * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_RUNTIME_FRAME_INLINE_HPP 26 #define SHARE_RUNTIME_FRAME_INLINE_HPP 27 28 #include "runtime/frame.hpp" 29 30 #include "code/codeBlob.inline.hpp" 31 #include "code/nmethod.inline.hpp" 32 #include "interpreter/interpreter.hpp" 33 #include "oops/stackChunkOop.inline.hpp" 34 #include "oops/method.hpp" 35 #include "runtime/continuation.hpp" 36 #include "runtime/registerMap.hpp" 37 #include "runtime/stubRoutines.hpp" 38 #include "utilities/macros.hpp" 39 #ifdef ZERO 40 # include "entryFrame_zero.hpp" 41 # include "fakeStubFrame_zero.hpp" 42 # include "interpreterFrame_zero.hpp" 43 #endif 44 45 #include CPU_HEADER_INLINE(frame) 46 47 inline bool frame::is_entry_frame() const { 48 return StubRoutines::returns_to_call_stub(pc()); 49 } 50 51 inline bool frame::is_stub_frame() const { 52 return StubRoutines::is_stub_code(pc()) || (_cb != nullptr && _cb->is_adapter_blob()); 53 } 54 55 inline bool frame::is_first_frame() const { 56 return (is_entry_frame() && entry_frame_is_first()) 57 // Upcall stub frames entry frames are only present on certain platforms 58 || (is_upcall_stub_frame() && upcall_stub_frame_is_first()); 59 } 60 61 inline bool frame::is_upcall_stub_frame() const { 62 return _cb != nullptr && _cb->is_upcall_stub(); 63 } 64 65 inline bool frame::is_compiled_frame() const { 66 if (_cb != nullptr && 67 _cb->is_nmethod() && 68 _cb->as_nmethod()->is_java_method()) { 69 return true; 70 } 71 return false; 72 } 73 74 inline address frame::get_deopt_original_pc() const { 75 if (_cb == nullptr) return nullptr; 76 77 nmethod* nm = _cb->as_nmethod_or_null(); 78 if (nm != nullptr && nm->is_deopt_pc(_pc)) { 79 return nm->get_original_pc(this); 80 } 81 return nullptr; 82 } 83 84 template <typename RegisterMapT> 85 inline address frame::oopmapreg_to_location(VMReg reg, const RegisterMapT* reg_map) const { 86 if (reg->is_reg()) { 87 // If it is passed in a register, it got spilled in the stub frame. 88 return reg_map->location(reg, sp()); 89 } else { 90 int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size; 91 if (reg_map->in_cont()) { 92 return (address)((intptr_t)reg_map->as_RegisterMap()->stack_chunk()->relativize_usp_offset(*this, sp_offset_in_bytes)); 93 } 94 address usp = (address)unextended_sp(); 95 assert(reg_map->thread() == nullptr || reg_map->thread()->is_in_usable_stack(usp), INTPTR_FORMAT, p2i(usp)); 96 return (usp + sp_offset_in_bytes); 97 } 98 } 99 100 template <typename RegisterMapT> 101 inline oop* frame::oopmapreg_to_oop_location(VMReg reg, const RegisterMapT* reg_map) const { 102 return (oop*)oopmapreg_to_location(reg, reg_map); 103 } 104 105 inline CodeBlob* frame::get_cb() const { 106 // if (_cb == nullptr) _cb = CodeCache::find_blob(_pc); 107 if (_cb == nullptr) { 108 int slot; 109 _cb = CodeCache::find_blob_and_oopmap(_pc, slot); 110 if (_oop_map == nullptr && slot >= 0) { 111 _oop_map = _cb->oop_map_for_slot(slot, _pc); 112 } 113 } 114 return _cb; 115 } 116 117 inline const ImmutableOopMap* frame::get_oop_map() const { 118 if (_cb == nullptr || _cb->oop_maps() == nullptr) return nullptr; 119 120 NativePostCallNop* nop = nativePostCallNop_at(_pc); 121 int oopmap_slot; 122 int cb_offset; 123 if (nop != nullptr && nop->decode(oopmap_slot, cb_offset)) { 124 return _cb->oop_map_for_slot(oopmap_slot, _pc); 125 } 126 const ImmutableOopMap* oop_map = OopMapSet::find_map(this); 127 return oop_map; 128 } 129 130 inline int frame::interpreter_frame_monitor_size_in_bytes() { 131 // Number of bytes for a monitor. 132 return frame::interpreter_frame_monitor_size() * wordSize; 133 } 134 135 #endif // SHARE_RUNTIME_FRAME_INLINE_HPP