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 SHARE_RUNTIME_VFRAME_HPP
 26 #define SHARE_RUNTIME_VFRAME_HPP
 27 
 28 #include "code/debugInfo.hpp"
 29 #include "code/debugInfoRec.hpp"
 30 #include "code/location.hpp"
 31 #include "oops/oop.hpp"
 32 #include "runtime/frame.hpp"
 33 #include "runtime/handles.hpp"
 34 #include "runtime/registerMap.hpp"
 35 #include "runtime/stackValue.hpp"
 36 #include "runtime/stackValueCollection.hpp"
 37 #include "utilities/growableArray.hpp"
 38 
 39 // vframes are virtual stack frames representing source level activations.
 40 // A single frame may hold several source level activations in the case of
 41 // optimized code. The debugging stored with the optimized code enables
 42 // us to unfold a frame as a stack of vframes.
 43 // A cVFrame represents an activation of a non-java method.
 44 
 45 // The vframe inheritance hierarchy:
 46 // - vframe
 47 //   - javaVFrame
 48 //     - interpretedVFrame
 49 //     - compiledVFrame     ; (used for both compiled Java methods and native stubs)
 50 //   - externalVFrame
 51 //     - entryVFrame        ; special frame created when calling Java from C
 52 
 53 // - BasicLock
 54 
 55 class StackFrameStream;
 56 
 57 class vframe: public ResourceObj {
 58  protected:
 59   frame        _fr;      // Raw frame behind the virtual frame.
 60   RegisterMap  _reg_map; // Register map for the raw frame (used to handle callee-saved registers).
 61   JavaThread*  _thread;  // The thread owning the raw frame.
 62 
 63   vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread);
 64   vframe(const frame* fr, JavaThread* thread);
 65  public:
 66   // Factory methods for creating vframes
 67   static vframe* new_vframe(const frame* f, const RegisterMap *reg_map, JavaThread* thread);
 68   static vframe* new_vframe(StackFrameStream& fst, JavaThread* thread);
 69 
 70   // Accessors
 71   frame              fr()           const { return _fr;       }
 72   CodeBlob*          cb()         const { return _fr.cb();  }
 73   CompiledMethod*   nm()         const {
 74       assert( cb() != NULL && cb()->is_compiled(), "usage");
 75       return (CompiledMethod*) cb();
 76   }
 77 
 78 // ???? Does this need to be a copy?
 79   frame*             frame_pointer() { return &_fr;       }
 80   const RegisterMap* register_map() const { return &_reg_map; }
 81   JavaThread*        thread()       const { return _thread;   }
 82 
 83   // Returns the sender vframe
 84   virtual vframe* sender() const;
 85 
 86   // Returns the next javaVFrame on the stack (skipping all other kinds of frame)
 87   javaVFrame *java_sender() const;
 88 
 89   // Answers if the this is the top vframe in the frame, i.e., if the sender vframe
 90   // is in the caller frame
 91   virtual bool is_top() const { return true; }
 92 
 93   // Returns top vframe within same frame (see is_top())
 94   virtual vframe* top() const;
 95 
 96   // Type testing operations
 97   virtual bool is_entry_frame()       const { return false; }
 98   virtual bool is_java_frame()        const { return false; }
 99   virtual bool is_interpreted_frame() const { return false; }
100   virtual bool is_compiled_frame()    const { return false; }
101 
102 #ifndef PRODUCT
103   // printing operations
104   virtual void print_value() const;
105   virtual void print();
106 #endif
107 };
108 
109 
110 class javaVFrame: public vframe {
111  public:
112   // JVM state
113   virtual Method*                      method()         const = 0;
114   virtual int                          bci()            const = 0;
115   virtual StackValueCollection*        locals()         const = 0;
116   virtual StackValueCollection*        expressions()    const = 0;
117   // the order returned by monitors() is from oldest -> youngest#4418568
118   virtual GrowableArray<MonitorInfo*>* monitors()       const = 0;
119 
120   // Debugging support via JVMTI.
121   // NOTE that this is not guaranteed to give correct results for compiled vframes.
122   // Deoptimize first if necessary.
123   virtual void set_locals(StackValueCollection* values) const = 0;
124 
125   // Test operation
126   bool is_java_frame() const { return true; }
127 
128  protected:
129   javaVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : vframe(fr, reg_map, thread) {}
130   javaVFrame(const frame* fr, JavaThread* thread) : vframe(fr, thread) {}
131 
132  public:
133   // casting
134   static javaVFrame* cast(vframe* vf) {
135     assert(vf == NULL || vf->is_java_frame(), "must be java frame");
136     return (javaVFrame*) vf;
137   }
138 
139   // Return an array of monitors locked by this frame in the youngest to oldest order
140   GrowableArray<MonitorInfo*>* locked_monitors();
141 
142   // printing used during stack dumps and diagnostics
143   static void print_locked_object_class_name(outputStream* st, Handle obj, const char* lock_state);
144   void print_lock_info_on(outputStream* st, int frame_count);
145   void print_lock_info(int frame_count) { print_lock_info_on(tty, frame_count); }
146 
147 #ifndef PRODUCT
148  public:
149   // printing operations
150   void print();
151   void print_value() const;
152   void print_activation(int index) const;
153 
154   // verify operations
155   virtual void verify() const;
156 
157   // Structural compare
158   bool structural_compare(javaVFrame* other);
159 #endif
160   friend class vframe;
161 };
162 
163 class interpretedVFrame: public javaVFrame {
164  public:
165   // JVM state
166   Method*                      method()         const;
167   int                          bci()            const;
168   StackValueCollection*        locals()         const;
169   StackValueCollection*        expressions()    const;
170   GrowableArray<MonitorInfo*>* monitors()       const;
171 
172   void set_locals(StackValueCollection* values) const;
173 
174   // Test operation
175   bool is_interpreted_frame() const { return true; }
176 
177  protected:
178   interpretedVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : javaVFrame(fr, reg_map, thread) {};
179 
180  public:
181   // Accessors for Byte Code Pointer
182   u_char* bcp() const;
183   void set_bcp(u_char* bcp);
184 
185   // casting
186   static interpretedVFrame* cast(vframe* vf) {
187     assert(vf == NULL || vf->is_interpreted_frame(), "must be interpreted frame");
188     return (interpretedVFrame*) vf;
189   }
190 
191  private:
192   static const int bcp_offset;
193   intptr_t* locals_addr_at(int offset) const;
194   StackValueCollection* stack_data(bool expressions) const;
195   // returns where the parameters starts relative to the frame pointer
196   int start_of_parameters() const;
197 
198 #ifndef PRODUCT
199  public:
200   // verify operations
201   void verify() const;
202 #endif
203   friend class vframe;
204 };
205 
206 
207 class externalVFrame: public vframe {
208  protected:
209   externalVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : vframe(fr, reg_map, thread) {}
210 
211 #ifndef PRODUCT
212  public:
213   // printing operations
214   void print_value() const;
215   void print();
216 #endif
217   friend class vframe;
218 };
219 
220 class entryVFrame: public externalVFrame {
221  public:
222   bool is_entry_frame() const { return true; }
223 
224  protected:
225   entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread);
226 
227  public:
228   // casting
229   static entryVFrame* cast(vframe* vf) {
230     assert(vf == NULL || vf->is_entry_frame(), "must be entry frame");
231     return (entryVFrame*) vf;
232   }
233 
234 #ifndef PRODUCT
235  public:
236   // printing
237   void print_value() const;
238   void print();
239 #endif
240   friend class vframe;
241 };
242 
243 
244 // A MonitorInfo is a ResourceObject that describes a the pair:
245 // 1) the owner of the monitor
246 // 2) the monitor lock
247 class MonitorInfo : public ResourceObj {
248  private:
249   Handle     _owner; // the object owning the monitor
250   BasicLock* _lock;
251   Handle     _owner_klass; // klass (mirror) if owner was scalar replaced
252   bool       _eliminated;
253   bool       _owner_is_scalar_replaced;
254  public:
255   // Constructor
256   MonitorInfo(oop owner, BasicLock* lock, bool eliminated, bool owner_is_scalar_replaced);
257   // Accessors
258   oop owner() const {
259     assert(!_owner_is_scalar_replaced, "should not be called for scalar replaced object");
260     return _owner();
261   }
262   oop owner_klass() const {
263     assert(_owner_is_scalar_replaced, "should not be called for not scalar replaced object");
264     return _owner_klass();
265   }
266   BasicLock* lock()  const { return _lock;  }
267   bool eliminated()  const { return _eliminated; }
268   bool owner_is_scalar_replaced()  const { return _owner_is_scalar_replaced; }
269 };
270 
271 class vframeStreamCommon : StackObj {
272  protected:
273   // common
274   frame        _prev_frame;
275   frame        _frame;
276   JavaThread*  _thread;
277   RegisterMap  _reg_map;
278   enum { interpreted_mode, compiled_mode, at_end_mode } _mode;
279 
280   // For compiled_mode
281   int _decode_offset;
282   int _sender_decode_offset;
283   int _vframe_id;
284 
285   // Cached information
286   Method* _method;
287   int       _bci;
288 
289   // Should VM activations be ignored or not
290   bool _stop_at_java_call_stub;
291 
292   bool fill_in_compiled_inlined_sender();
293   void fill_from_compiled_frame(int decode_offset);
294   void fill_from_compiled_native_frame();
295 
296   void fill_from_interpreter_frame();
297   bool fill_from_frame();
298 
299   // Helper routine for security_get_caller_frame
300   void skip_prefixed_method_and_wrappers();
301 
302   DEBUG_ONLY(void found_bad_method_frame() const;)
303 
304  public:
305   // Constructor
306   inline vframeStreamCommon(JavaThread* thread, bool process_frames);
307 
308   // Accessors
309   Method* method() const { return _method; }
310   int bci() const { return _bci; }
311   inline intptr_t* frame_id() const;
312   address frame_pc() const { return _frame.pc(); }
313   inline int vframe_id() const;
314   inline int decode_offset() const;
315 
316   CodeBlob*          cb()         const { return _frame.cb();  }
317   CompiledMethod*   nm()         const {
318       assert( cb() != NULL && cb()->is_compiled(), "usage");
319       return (CompiledMethod*) cb();
320   }
321 
322   javaVFrame* asJavaVFrame();
323 
324   // Frame type
325   inline bool is_interpreted_frame() const;
326   inline bool is_entry_frame() const;
327 
328   // Iteration
329   inline void next();
330   void security_next();
331 
332   bool at_end() const { return _mode == at_end_mode; }
333 
334   // Implements security traversal. Skips depth no. of frame including
335   // special security frames and prefixed native methods
336   void security_get_caller_frame(int depth);
337 };
338 
339 class vframeStream : public vframeStreamCommon {
340  public:
341   // Constructors
342   vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false, bool process_frames = true);
343 
344   // top_frame may not be at safepoint, start with sender
345   vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false);
346 };
347 
348 #endif // SHARE_RUNTIME_VFRAME_HPP