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