1 /*
  2  * Copyright (c) 2008, 2019, 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_ARM_FRAME_ARM_INLINE_HPP
 26 #define CPU_ARM_FRAME_ARM_INLINE_HPP
 27 
 28 #include "code/codeCache.hpp"
 29 #include "code/vmreg.inline.hpp"
 30 
 31 // Inline functions for ARM frames:
 32 
 33 // Constructors:
 34 
 35 inline frame::frame() {
 36   _pc = NULL;
 37   _sp = NULL;
 38   _unextended_sp = NULL;
 39   _fp = NULL;
 40   _cb = NULL;
 41   _deopt_state = unknown;
 42 }
 43 
 44 inline frame::frame(intptr_t* sp) {
 45   Unimplemented();
 46 }
 47 
 48 inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
 49   _sp = sp;
 50   _unextended_sp = sp;
 51   _fp = fp;
 52   _pc = pc;
 53   assert(pc != NULL, "no pc?");
 54   _cb = CodeCache::find_blob(pc);
 55   adjust_unextended_sp();
 56 
 57   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 58   if (original_pc != NULL) {
 59     _pc = original_pc;
 60     _deopt_state = is_deoptimized;
 61   } else {
 62     _deopt_state = not_deoptimized;
 63   }
 64 }
 65 
 66 inline frame::frame(intptr_t* sp, intptr_t* fp, address pc) {
 67   init(sp, fp, pc);
 68 }
 69 
 70 inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc) {
 71   _sp = sp;
 72   _unextended_sp = unextended_sp;
 73   _fp = fp;
 74   _pc = pc;
 75   assert(pc != NULL, "no pc?");
 76   _cb = CodeCache::find_blob(pc);
 77   adjust_unextended_sp();
 78 
 79   address original_pc = CompiledMethod::get_deopt_original_pc(this);
 80   if (original_pc != NULL) {
 81     _pc = original_pc;
 82     assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc),
 83            "original PC must be in the main code section of the the compiled method (or must be immediately following it)");
 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   assert(sp != NULL,"null SP ?");
 96   _pc = (address)(sp[-1]);
 97   // assert(_pc != NULL, "no pc?"); // see comments in x86
 98   _cb = CodeCache::find_blob(_pc);
 99   adjust_unextended_sp();
100 
101   address original_pc = CompiledMethod::get_deopt_original_pc(this);
102   if (original_pc != NULL) {
103     _pc = original_pc;
104     _deopt_state = is_deoptimized;
105   } else {
106     _deopt_state = not_deoptimized;
107   }
108 }
109 
110 
111 // Accessors
112 
113 inline bool frame::equal(frame other) const {
114   bool ret =  sp() == other.sp()
115               && unextended_sp() == other.unextended_sp()
116               && fp() == other.fp()
117               && pc() == other.pc();
118   assert(!ret || ret && cb() == other.cb() && _deopt_state == other._deopt_state, "inconsistent construction");
119   return ret;
120 }
121 
122 // Return unique id for this frame. The id must have a value where we can distinguish
123 // identity and younger/older relationship. NULL represents an invalid (incomparable)
124 // frame.
125 inline intptr_t* frame::id(void) const { return unextended_sp(); }
126 
127 // Return true if the frame is older (less recent activation) than the frame represented by id
128 inline bool frame::is_older(intptr_t* id) const   { assert(this->id() != NULL && id != NULL, "NULL frame id");
129                                                     return this->id() > id ; }
130 
131 
132 inline intptr_t* frame::link() const              { return (intptr_t*) *(intptr_t **)addr_at(link_offset); }
133 
134 inline intptr_t* frame::unextended_sp() const     { return _unextended_sp; }
135 
136 // Return address:
137 
138 inline address* frame::sender_pc_addr()      const { return (address*) addr_at(return_addr_offset); }
139 inline address  frame::sender_pc()           const { return *sender_pc_addr(); }
140 
141 inline intptr_t* frame::sender_sp() const { return addr_at(sender_sp_offset); }
142 
143 inline intptr_t** frame::interpreter_frame_locals_addr() const {
144   return (intptr_t**)addr_at(interpreter_frame_locals_offset);
145 }
146 
147 inline intptr_t* frame::interpreter_frame_last_sp() const {
148   return *(intptr_t**)addr_at(interpreter_frame_last_sp_offset);
149 }
150 
151 inline intptr_t* frame::interpreter_frame_bcp_addr() const {
152   return (intptr_t*)addr_at(interpreter_frame_bcp_offset);
153 }
154 
155 inline intptr_t* frame::interpreter_frame_mdp_addr() const {
156   return (intptr_t*)addr_at(interpreter_frame_mdp_offset);
157 }
158 
159 
160 // Constant pool cache
161 
162 inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const {
163   return (ConstantPoolCache**)addr_at(interpreter_frame_cache_offset);
164 }
165 
166 // Method
167 
168 inline Method** frame::interpreter_frame_method_addr() const {
169   return (Method**)addr_at(interpreter_frame_method_offset);
170 }
171 
172 inline oop* frame::interpreter_frame_mirror_addr() const {
173   return (oop*)addr_at(interpreter_frame_mirror_offset);
174 }
175 
176 // top of expression stack
177 template <bool relative>
178 inline intptr_t* frame::interpreter_frame_tos_address() const {
179   intptr_t* last_sp = interpreter_frame_last_sp();
180   if (last_sp == NULL ) {
181     return sp();
182   } else {
183     // sp() may have been extended or shrunk by an adapter.  At least
184     // check that we don't fall behind the legal region.
185     // For top deoptimized frame last_sp == interpreter_frame_monitor_end.
186     assert(last_sp <= (intptr_t*) interpreter_frame_monitor_end(), "bad tos");
187     return last_sp;
188   }
189 }
190 
191 inline oop* frame::interpreter_frame_temp_oop_addr() const {
192   return (oop *)(fp() + interpreter_frame_oop_temp_offset);
193 }
194 
195 inline int frame::interpreter_frame_monitor_size() {
196   return BasicObjectLock::size();
197 }
198 
199 
200 // expression stack
201 // (the max_stack arguments are used by the GC; see class FrameClosure)
202 
203 template <bool relative>
204 inline intptr_t* frame::interpreter_frame_expression_stack() const {
205   intptr_t* monitor_end = (intptr_t*) interpreter_frame_monitor_end();
206   return monitor_end-1;
207 }
208 
209 
210 // Entry frames
211 
212 inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
213  return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset);
214 }
215 
216 
217 // Compiled frames
218 
219 inline oop frame::saved_oop_result(RegisterMap* map) const {
220   oop* result_adr = (oop*) map->location(R0->as_VMReg(), (intptr_t*) NULL);
221   guarantee(result_adr != NULL, "bad register save location");
222   return (*result_adr);
223 }
224 
225 inline void frame::set_saved_oop_result(RegisterMap* map, oop obj) {
226   oop* result_adr = (oop*) map->location(R0->as_VMReg(), (intptr_t*) NULL);
227   guarantee(result_adr != NULL, "bad register save location");
228   *result_adr = obj;
229 }
230 
231 inline int frame::frame_size() const {
232   return sender_sp() - sp();
233 }
234 
235 inline const ImmutableOopMap* frame::get_oop_map() const {
236   Unimplemented();
237   return NULL;
238 }
239 
240 inline int frame::compiled_frame_stack_argsize() const {
241   Unimplemented();
242   return 0;
243 }
244 
245 inline void frame::interpreted_frame_oop_map(InterpreterOopMap* mask) const {
246   Unimplemented();
247 }
248 
249 inline int frame::interpreted_frame_num_oops(InterpreterOopMap* mask) const {
250   Unimplemented();
251   return 0;
252 }
253 
254 template <bool relative>
255 inline intptr_t* frame::interpreter_frame_last_sp() const {
256   Unimplemented();
257   return NULL;
258 }
259 
260 inline int frame::sender_sp_ret_address_offset() {
261   Unimplemented();
262   return 0;
263 }
264 
265 template <typename RegisterMapT>
266 void frame::update_map_with_saved_link(RegisterMapT* map, intptr_t** link_addr) {
267   Unimplemented();
268 }
269 
270 inline void frame::set_unextended_sp(intptr_t* value) {
271   Unimplemented();
272 }
273 
274 inline int frame::offset_unextended_sp() const {
275   Unimplemented();
276   return 0;
277 }
278 
279 inline void frame::set_offset_unextended_sp(int value) {
280   Unimplemented();
281 }
282 
283 #endif // CPU_ARM_FRAME_ARM_INLINE_HPP
--- EOF ---