annotate src/share/vm/runtime/vframe.hpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children d3cd40645d0d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // vframes are virtual stack frames representing source level activations.
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // A single frame may hold several source level activations in the case of
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // optimized code. The debugging stored with the optimized code enables
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // us to unfold a frame as a stack of vframes.
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // A cVFrame represents an activation of a non-java method.
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // The vframe inheritance hierarchy:
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // - vframe
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // - javaVFrame
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // - interpretedVFrame
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // - compiledVFrame ; (used for both compiled Java methods and native stubs)
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // - externalVFrame
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // - entryVFrame ; special frame created when calling Java from C
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // - BasicLock
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 class vframe: public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
43 frame _fr; // Raw frame behind the virtual frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
44 RegisterMap _reg_map; // Register map for the raw frame (used to handle callee-saved registers).
a61af66fc99e Initial load
duke
parents:
diff changeset
45 JavaThread* _thread; // The thread owning the raw frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 vframe(const frame* fr, const RegisterMap* reg_map, JavaThread* thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
48 vframe(const frame* fr, JavaThread* thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
49 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Factory method for creating vframes
a61af66fc99e Initial load
duke
parents:
diff changeset
51 static vframe* new_vframe(const frame* f, const RegisterMap *reg_map, JavaThread* thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
54 frame fr() const { return _fr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
55 CodeBlob* cb() const { return _fr.cb(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
56 nmethod* nm() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 assert( cb() != NULL && cb()->is_nmethod(), "usage");
a61af66fc99e Initial load
duke
parents:
diff changeset
58 return (nmethod*) cb();
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // ???? Does this need to be a copy?
a61af66fc99e Initial load
duke
parents:
diff changeset
62 frame* frame_pointer() { return &_fr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 const RegisterMap* register_map() const { return &_reg_map; }
a61af66fc99e Initial load
duke
parents:
diff changeset
64 JavaThread* thread() const { return _thread; }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // Returns the sender vframe
a61af66fc99e Initial load
duke
parents:
diff changeset
67 virtual vframe* sender() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
68
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // Returns the next javaVFrame on the stack (skipping all other kinds of frame)
a61af66fc99e Initial load
duke
parents:
diff changeset
70 javaVFrame *java_sender() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72 // Answers if the this is the top vframe in the frame, i.e., if the sender vframe
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // is in the caller frame
a61af66fc99e Initial load
duke
parents:
diff changeset
74 virtual bool is_top() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // Returns top vframe within same frame (see is_top())
a61af66fc99e Initial load
duke
parents:
diff changeset
77 virtual vframe* top() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // Type testing operations
a61af66fc99e Initial load
duke
parents:
diff changeset
80 virtual bool is_entry_frame() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
81 virtual bool is_java_frame() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
82 virtual bool is_interpreted_frame() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
83 virtual bool is_compiled_frame() const { return false; }
a61af66fc99e Initial load
duke
parents:
diff changeset
84
a61af66fc99e Initial load
duke
parents:
diff changeset
85 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // printing operations
a61af66fc99e Initial load
duke
parents:
diff changeset
87 virtual void print_value() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
88 virtual void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
89 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
90 };
a61af66fc99e Initial load
duke
parents:
diff changeset
91
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 class javaVFrame: public vframe {
a61af66fc99e Initial load
duke
parents:
diff changeset
94 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // JVM state
a61af66fc99e Initial load
duke
parents:
diff changeset
96 virtual methodOop method() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 virtual int bci() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 virtual StackValueCollection* locals() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 virtual StackValueCollection* expressions() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // the order returned by monitors() is from oldest -> youngest#4418568
a61af66fc99e Initial load
duke
parents:
diff changeset
101 virtual GrowableArray<MonitorInfo*>* monitors() const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Debugging support via JVMTI.
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // NOTE that this is not guaranteed to give correct results for compiled vframes.
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // Deoptimize first if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
106 virtual void set_locals(StackValueCollection* values) const = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 // Test operation
a61af66fc99e Initial load
duke
parents:
diff changeset
109 bool is_java_frame() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
112 javaVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : vframe(fr, reg_map, thread) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
113 javaVFrame(const frame* fr, JavaThread* thread) : vframe(fr, thread) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // casting
a61af66fc99e Initial load
duke
parents:
diff changeset
117 static javaVFrame* cast(vframe* vf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
118 assert(vf == NULL || vf->is_java_frame(), "must be java frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
119 return (javaVFrame*) vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Return an array of monitors locked by this frame in the youngest to oldest order
a61af66fc99e Initial load
duke
parents:
diff changeset
123 GrowableArray<MonitorInfo*>* locked_monitors();
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // printing used during stack dumps
a61af66fc99e Initial load
duke
parents:
diff changeset
126 void print_lock_info_on(outputStream* st, int frame_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
127 void print_lock_info(int frame_count) { print_lock_info_on(tty, frame_count); }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
130 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // printing operations
a61af66fc99e Initial load
duke
parents:
diff changeset
132 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
133 void print_value() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
134 void print_activation(int index) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // verify operations
a61af66fc99e Initial load
duke
parents:
diff changeset
137 virtual void verify() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 // Structural compare
a61af66fc99e Initial load
duke
parents:
diff changeset
140 bool structural_compare(javaVFrame* other);
a61af66fc99e Initial load
duke
parents:
diff changeset
141 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
142 friend class vframe;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 };
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 class interpretedVFrame: public javaVFrame {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // JVM state
a61af66fc99e Initial load
duke
parents:
diff changeset
148 methodOop method() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 int bci() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 StackValueCollection* locals() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 StackValueCollection* expressions() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 GrowableArray<MonitorInfo*>* monitors() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
153
a61af66fc99e Initial load
duke
parents:
diff changeset
154 void set_locals(StackValueCollection* values) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156 // Test operation
a61af66fc99e Initial load
duke
parents:
diff changeset
157 bool is_interpreted_frame() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
158
a61af66fc99e Initial load
duke
parents:
diff changeset
159 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
160 interpretedVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : javaVFrame(fr, reg_map, thread) {};
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Accessors for Byte Code Pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
164 u_char* bcp() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
165 void set_bcp(u_char* bcp);
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167 // casting
a61af66fc99e Initial load
duke
parents:
diff changeset
168 static interpretedVFrame* cast(vframe* vf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 assert(vf == NULL || vf->is_interpreted_frame(), "must be interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
170 return (interpretedVFrame*) vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
174 static const int bcp_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
175 intptr_t* locals_addr_at(int offset) const;
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 // returns where the parameters starts relative to the frame pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
178 int start_of_parameters() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
181 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // verify operations
a61af66fc99e Initial load
duke
parents:
diff changeset
183 void verify() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
185 friend class vframe;
a61af66fc99e Initial load
duke
parents:
diff changeset
186 };
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 class externalVFrame: public vframe {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
191 externalVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread) : vframe(fr, reg_map, thread) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
194 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // printing operations
a61af66fc99e Initial load
duke
parents:
diff changeset
196 void print_value() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
199 friend class vframe;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 };
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 class entryVFrame: public externalVFrame {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
204 bool is_entry_frame() const { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
205
a61af66fc99e Initial load
duke
parents:
diff changeset
206 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
207 entryVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // casting
a61af66fc99e Initial load
duke
parents:
diff changeset
211 static entryVFrame* cast(vframe* vf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 assert(vf == NULL || vf->is_entry_frame(), "must be entry frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
213 return (entryVFrame*) vf;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
217 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // printing
a61af66fc99e Initial load
duke
parents:
diff changeset
219 void print_value() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
222 friend class vframe;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 };
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // A MonitorInfo is a ResourceObject that describes a the pair:
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // 1) the owner of the monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // 2) the monitor lock
a61af66fc99e Initial load
duke
parents:
diff changeset
229 class MonitorInfo : public ResourceObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
231 oop _owner; // the object owning the monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
232 BasicLock* _lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
233 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
235 MonitorInfo(oop owner, BasicLock* lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 _owner = owner;
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _lock = lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
240 oop owner() const { return _owner; }
a61af66fc99e Initial load
duke
parents:
diff changeset
241 BasicLock* lock() const { return _lock; }
a61af66fc99e Initial load
duke
parents:
diff changeset
242 };
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 class vframeStreamCommon : StackObj {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
246 // common
a61af66fc99e Initial load
duke
parents:
diff changeset
247 frame _frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
248 JavaThread* _thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 RegisterMap _reg_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 enum { interpreted_mode, compiled_mode, at_end_mode } _mode;
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 int _sender_decode_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Cached information
a61af66fc99e Initial load
duke
parents:
diff changeset
255 methodOop _method;
a61af66fc99e Initial load
duke
parents:
diff changeset
256 int _bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
257
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // Should VM activations be ignored or not
a61af66fc99e Initial load
duke
parents:
diff changeset
259 bool _stop_at_java_call_stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 bool fill_in_compiled_inlined_sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
262 void fill_from_compiled_frame(int decode_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 void fill_from_compiled_native_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265 void found_bad_method_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
266
a61af66fc99e Initial load
duke
parents:
diff changeset
267 void fill_from_interpreter_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
268 bool fill_from_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Helper routine for security_get_caller_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
271 void skip_prefixed_method_and_wrappers();
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // Constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
275 vframeStreamCommon(JavaThread* thread) : _reg_map(thread, false) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Accessors
a61af66fc99e Initial load
duke
parents:
diff changeset
280 methodOop method() const { return _method; }
a61af66fc99e Initial load
duke
parents:
diff changeset
281 int bci() const { return _bci; }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 intptr_t* frame_id() const { return _frame.id(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 address frame_pc() const { return _frame.pc(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 CodeBlob* cb() const { return _frame.cb(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
286 nmethod* nm() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 assert( cb() != NULL && cb()->is_nmethod(), "usage");
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return (nmethod*) cb();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Frame type
a61af66fc99e Initial load
duke
parents:
diff changeset
292 bool is_interpreted_frame() const { return _frame.is_interpreted_frame(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
293 bool is_entry_frame() const { return _frame.is_entry_frame(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // Iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
296 void next() {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // handle frames with inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
298 if (_mode == compiled_mode && fill_in_compiled_inlined_sender()) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // handle general case
a61af66fc99e Initial load
duke
parents:
diff changeset
301 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
302 _frame = _frame.sender(&_reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 } while (!fill_from_frame());
a61af66fc99e Initial load
duke
parents:
diff changeset
304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
305
a61af66fc99e Initial load
duke
parents:
diff changeset
306 bool at_end() const { return _mode == at_end_mode; }
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 // Implements security traversal. Skips depth no. of frame including
a61af66fc99e Initial load
duke
parents:
diff changeset
309 // special security frames and prefixed native methods
a61af66fc99e Initial load
duke
parents:
diff changeset
310 void security_get_caller_frame(int depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // Helper routine for JVM_LatestUserDefinedLoader -- needed for 1.4
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // reflection implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
314 void skip_reflection_related_frames();
a61af66fc99e Initial load
duke
parents:
diff changeset
315 };
a61af66fc99e Initial load
duke
parents:
diff changeset
316
a61af66fc99e Initial load
duke
parents:
diff changeset
317 class vframeStream : public vframeStreamCommon {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // Constructors
a61af66fc99e Initial load
duke
parents:
diff changeset
320 vframeStream(JavaThread* thread, bool stop_at_java_call_stub = false)
a61af66fc99e Initial load
duke
parents:
diff changeset
321 : vframeStreamCommon(thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 _stop_at_java_call_stub = stop_at_java_call_stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 if (!thread->has_last_Java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 _mode = at_end_mode;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 _frame = _thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
330 while (!fill_from_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 _frame = _frame.sender(&_reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // top_frame may not be at safepoint, start with sender
a61af66fc99e Initial load
duke
parents:
diff changeset
336 vframeStream(JavaThread* thread, frame top_frame, bool stop_at_java_call_stub = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 };
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
a61af66fc99e Initial load
duke
parents:
diff changeset
341 if (_sender_decode_offset == DebugInformationRecorder::serialized_null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
344 fill_from_compiled_frame(_sender_decode_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 _mode = compiled_mode;
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 // Range check to detect ridiculous offsets.
a61af66fc99e Initial load
duke
parents:
diff changeset
353 if (decode_offset == DebugInformationRecorder::serialized_null ||
a61af66fc99e Initial load
duke
parents:
diff changeset
354 decode_offset < 0 ||
a61af66fc99e Initial load
duke
parents:
diff changeset
355 decode_offset >= nm()->scopes_data_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
356 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
357 // If we attempt to read nmethod::scopes_data at serialized_null (== 0),
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // or if we read some at other crazy offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
359 // we will decode garbage and make wild references into the heap,
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // leading to crashes in product mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // (This isn't airtight, of course, since there are internal
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // offsets which are also crazy.)
a61af66fc99e Initial load
duke
parents:
diff changeset
363 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
364 if (WizardMode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
365 tty->print_cr("Error in fill_from_frame: pc_desc for "
a61af66fc99e Initial load
duke
parents:
diff changeset
366 INTPTR_FORMAT " not found or invalid at %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
367 _frame.pc(), decode_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 nm()->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
369 nm()->method()->print_codes();
a61af66fc99e Initial load
duke
parents:
diff changeset
370 nm()->print_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
371 nm()->print_pcs();
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // Provide a cheap fallback in product mode. (See comment above.)
a61af66fc99e Initial load
duke
parents:
diff changeset
375 found_bad_method_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
376 fill_from_compiled_native_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
377 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // Decode first part of scopeDesc
a61af66fc99e Initial load
duke
parents:
diff changeset
381 DebugInfoReadStream buffer(nm(), decode_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
382 _sender_decode_offset = buffer.read_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
383 _method = methodOop(buffer.read_oop());
a61af66fc99e Initial load
duke
parents:
diff changeset
384 _bci = buffer.read_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
385
a61af66fc99e Initial load
duke
parents:
diff changeset
386 assert(_method->is_method(), "checking type of decoded method");
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // The native frames are handled specially. We do not rely on ScopeDesc info
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // since the pc might not be exact due to the _last_native_pc trick.
a61af66fc99e Initial load
duke
parents:
diff changeset
391 inline void vframeStreamCommon::fill_from_compiled_native_frame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 _mode = compiled_mode;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 _sender_decode_offset = DebugInformationRecorder::serialized_null;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 _method = nm()->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
395 _bci = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 inline bool vframeStreamCommon::fill_from_frame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // Interpreted frame
a61af66fc99e Initial load
duke
parents:
diff changeset
400 if (_frame.is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 fill_from_interpreter_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 // Compiled frame
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 if (cb() != NULL && cb()->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
408 if (nm()->is_native_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 // Do not rely on scopeDesc since the pc might be unprecise due to the _last_native_pc trick.
a61af66fc99e Initial load
duke
parents:
diff changeset
410 fill_from_compiled_native_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
411 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 PcDesc* pc_desc = nm()->pc_desc_at(_frame.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
413 int decode_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
414 if (pc_desc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Should not happen, but let fill_from_compiled_frame handle it.
a61af66fc99e Initial load
duke
parents:
diff changeset
416 decode_offset = DebugInformationRecorder::serialized_null;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
418 decode_offset = pc_desc->scope_decode_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420 fill_from_compiled_frame(decode_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
422 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // End of stack?
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if (_frame.is_first_frame() || (_stop_at_java_call_stub && _frame.is_entry_frame())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 _mode = at_end_mode;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 inline void vframeStreamCommon::fill_from_interpreter_frame() {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 methodOop method = _frame.interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
437 intptr_t bcx = _frame.interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 int bci = method->validate_bci_from_bcx(bcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // 6379830 AsyncGetCallTrace sometimes feeds us wild frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if (bci < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 found_bad_method_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
442 bci = 0; // pretend it's on the point of entering
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 _mode = interpreted_mode;
a61af66fc99e Initial load
duke
parents:
diff changeset
445 _method = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
446 _bci = bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }