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