1 /*
  2  * Copyright (c) 1997, 2021, 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 CPU_X86_FRAME_X86_INLINE_HPP
 26 #define CPU_X86_FRAME_X86_INLINE_HPP
 27 
 28 #include "code/codeCache.hpp"
 29 #include "code/vmreg.inline.hpp"
 30 #include "runtime/registerMap.hpp"
 31 
 32 // Inline functions for Intel frames:
 33 
 34 // Constructors:
 35 
 36 inline frame::frame() {
 37   _pc = NULL;
 38   _sp = NULL;
 39   _unextended_sp = NULL;
 40   _fp = NULL;
 41   _cb = NULL;
 42   _deopt_state = unknown;
 43 }
 44 
 45 inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
 46   _sp = sp;
 47   _unextended_sp = sp;
 48   _fp = fp;
 49   _pc = pc;
 50   assert(pc != NULL, "no pc?");
 51   _cb = CodeCache::find_blob(pc);
 52   adjust_unextended_sp();
 53 
 54   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 55   if (original_pc != NULL) {
 56     _pc = original_pc;
 57     _deopt_state = is_deoptimized;
 58   } else {
 59     _deopt_state = not_deoptimized;
 60   }
 61 }
 62 
 63 inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
 64   init(sp, fp, pc);
 65 }
 66 
 67 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
 68   _sp = sp;
 69   _unextended_sp = unextended_sp;
 70   _fp = fp;
 71   _pc = pc;
 72   assert(pc != NULL, "no pc?");
 73   _cb = CodeCache::find_blob(pc);
 74   adjust_unextended_sp();
 75 
 76   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 77   if (original_pc != NULL) {
 78     _pc = original_pc;
 79     assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
 80            "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 81     _deopt_state = is_deoptimized;
 82   } else {
 83     if (_cb->is_deoptimization_stub()) {
 84       _deopt_state = is_deoptimized;
 85     } else {
 86       _deopt_state = not_deoptimized;
 87     }
 88   }
 89 }
 90 
 91 inline frame::frame(intptr_t* sp, intptr_t* fp) {
 92   _sp = sp;
 93   _unextended_sp = sp;
 94   _fp = fp;
 95   _pc = (address)(sp[-1]);
 96 
 97   // Here's a sticky one. This constructor can be called via AsyncGetCallTrace
 98   // when last_Java_sp is non-null but the pc fetched is junk. If we are truly
 99   // unlucky the junk value could be to a zombied method and we'll die on the
100   // find_blob call. This is also why we can have no asserts on the validity
101   // of the pc we find here. AsyncGetCallTrace -> pd_get_top_frame_for_signal_handler
102   // -> pd_last_frame should use a specialized version of pd_last_frame which could
103   // call a specialized frame constructor instead of this one.
104   // Then we could use the assert below. However this assert is of somewhat dubious
105   // value.
106   // UPDATE: this constructor is only used by trace_method_handle_stub() now.
107   // assert(_pc != NULL, "no pc?");
108 
109   _cb = CodeCache::find_blob(_pc);
110   adjust_unextended_sp();
111 
112   address original_pc = CompiledMethod::get_deopt_original_pc(this);
113   if (original_pc != NULL) {
114     _pc = original_pc;
115     _deopt_state = is_deoptimized;
116   } else {
117     _deopt_state = not_deoptimized;
118   }
119 }
120 
121 // Accessors
122 
123 inline bool frame::equal(frame other) const {
124   bool ret =  sp() == other.sp()
125               && unextended_sp() == other.unextended_sp()
126               && fp() == other.fp()
127               && pc() == other.pc();
128   assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
129   return ret;
130 }
131 
132 // Return unique id for this frame. The id must have a value where we can distinguish
133 // identity and younger/older relationship. NULL represents an invalid (incomparable)
134 // frame.
135 inline intptr_t* frame::id(void) const { return unextended_sp(); }
136 
137 // Return true if the frame is older (less recent activation) than the frame represented by id
138 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
139                                                     return this->id() > id ; }
140 
141 
142 
143 inline intptr_t* frame::link() const              { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
144 
145 inline intptr_t* frame::unextended_sp() const     { return _unextended_sp; }
146 
147 // Return address:
148 
149 inline address* frame::sender_pc_addr()      const { return (address*) addr_at( return_addr_offset); }
150 inline address  frame::sender_pc()           const { return *sender_pc_addr(); }
151 
152 inline intptr_t*    frame::sender_sp()        const { return            addr_at(   sender_sp_offset); }
153 
154 inline intptr_t** frame::interpreter_frame_locals_addr() const {
155   return (intptr_t**)addr_at(interpreter_frame_locals_offset);
156 }
157 
158 inline intptr_t* frame::interpreter_frame_last_sp() const {
159   return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset);
160 }
161 
162 inline intptr_t* frame::interpreter_frame_bcp_addr() const {
163   return (intptr_t*)addr_at(interpreter_frame_bcp_offset);
164 }
165 
166 
167 inline intptr_t* frame::interpreter_frame_mdp_addr() const {
168   return (intptr_t*)addr_at(interpreter_frame_mdp_offset);
169 }
170 
171 
172 
173 // Constant pool cache
174 
175 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
176   return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset);
177 }
178 
179 // Method
180 
181 inline Method** frame::interpreter_frame_method_addr() const {
182   return (Method**)addr_at(interpreter_frame_method_offset);
183 }
184 
185 // Mirror
186 
187 inline oop* frame::interpreter_frame_mirror_addr() const {
188   return (oop*)addr_at(interpreter_frame_mirror_offset);
189 }
190 
191 // top of expression stack
192 inline intptr_t* frame::interpreter_frame_tos_address() const {
193   intptr_t* last_sp = interpreter_frame_last_sp();
194   if (last_sp == NULL) {
195     return sp();
196   } else {
197     // sp() may have been extended or shrunk by an adapter.  At least
198     // check that we don't fall behind the legal region.
199     // For top deoptimized frame last_sp == interpreter_frame_monitor_end.
200     assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
201     return last_sp;
202   }
203 }
204 
205 inline oop* frame::interpreter_frame_temp_oop_addr() const {
206   return (oop *)(fp() + interpreter_frame_oop_temp_offset);
207 }
208 
209 inline int frame::interpreter_frame_monitor_size() {
210   return BasicObjectLock::size();
211 }
212 
213 
214 // expression stack
215 // (the max_stack arguments are used by the GC; see class FrameClosure)
216 
217 inline intptr_t* frame::interpreter_frame_expression_stack() const {
218   intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
219   return monitor_end-1;
220 }
221 
222 // Entry frames
223 
224 inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
225  return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
226 }
227 
228 // Compiled frames
229 
230 // Register is a class, but it would be assigned numerical value.
231 // "0" is assigned for rax. Thus we need to ignore -Wnonnull.
232 PRAGMA_DIAG_PUSH
233 PRAGMA_NONNULL_IGNORED
234 inline oop frame::saved_oop_result(RegisterMap* map) const {
235   oop* result_adr = (oop *)map->location(rax->as_VMReg());
236   guarantee(result_adr != NULL, "bad register save location");
237 
238   return (*result_adr);
239 }
240 
241 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
242   oop* result_adr = (oop *)map->location(rax->as_VMReg());
243   guarantee(result_adr != NULL, "bad register save location");
244 
245   *result_adr = obj;
246 }
247 PRAGMA_DIAG_POP
248 
249 #endif // CPU_X86_FRAME_X86_INLINE_HPP