annotate src/share/vm/runtime/frame.cpp @ 94:0834225a7916

6634032: CMS: Need CMSInitiatingPermOccupancyFraction for perm, divorcing from CMSInitiatingOccupancyFraction Summary: The option CMSInitiatingPermOccupancyFraction now controls perm triggering threshold. Even though the actual value of the threshold has not yet been changed, so there is no change in policy, we now have the infrastructure in place for dynamically deciding when to collect the perm gen, an issue that will be addressed in the near future. Reviewed-by: jmasa
author ysr
date Sun, 16 Mar 2008 21:57:25 -0700
parents a61af66fc99e
children ba764ed4b6f2
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 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_frame.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 RegisterMap::RegisterMap(JavaThread *thread, bool update_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
29 _thread = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
30 _update_map = update_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
32 debug_only(_update_for_id = NULL;)
a61af66fc99e Initial load
duke
parents:
diff changeset
33 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
34 for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
35 #endif /* PRODUCT */
a61af66fc99e Initial load
duke
parents:
diff changeset
36 }
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 RegisterMap::RegisterMap(const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 assert(map != this, "bad initialization parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
40 assert(map != NULL, "RegisterMap must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
41 _thread = map->thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
42 _update_map = map->update_map();
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _include_argument_oops = map->include_argument_oops();
a61af66fc99e Initial load
duke
parents:
diff changeset
44 debug_only(_update_for_id = map->_update_for_id;)
a61af66fc99e Initial load
duke
parents:
diff changeset
45 pd_initialize_from(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
46 if (update_map()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 for(int i = 0; i < location_valid_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 LocationValidType bits = !update_map() ? 0 : map->_location_valid[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
49 _location_valid[i] = bits;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // for whichever bits are set, pull in the corresponding map->_location
a61af66fc99e Initial load
duke
parents:
diff changeset
51 int j = i*location_valid_type_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 while (bits != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 if ((bits & 1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
54 assert(0 <= j && j < reg_count, "range check");
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _location[j] = map->_location[j];
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57 bits >>= 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 j += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 }
a61af66fc99e Initial load
duke
parents:
diff changeset
60 }
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 void RegisterMap::clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
65 set_include_argument_oops(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
66 if (_update_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 for(int i = 0; i < location_valid_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _location_valid[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 pd_clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
71 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 pd_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 void RegisterMap::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 st->print_cr("Register map");
a61af66fc99e Initial load
duke
parents:
diff changeset
80 for(int i = 0; i < reg_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 VMReg r = VMRegImpl::as_VMReg(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 intptr_t* src = (intptr_t*) location(r);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 if (src != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 r->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
87 tty->print(" [" INTPTR_FORMAT "] = ", src);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 if (((uintptr_t)src & (sizeof(*src)-1)) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 tty->print_cr("<misaligned>");
a61af66fc99e Initial load
duke
parents:
diff changeset
90 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 tty->print_cr(INTPTR_FORMAT, *src);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97 void RegisterMap::print() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 print_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // This returns the pc that if you were in the debugger you'd see. Not
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // the idealized value in the frame object. This undoes the magic conversion
a61af66fc99e Initial load
duke
parents:
diff changeset
104 // that happens for deoptimized frames. In addition it makes the value the
a61af66fc99e Initial load
duke
parents:
diff changeset
105 // hardware would want to see in the native frame. The only user (at this point)
a61af66fc99e Initial load
duke
parents:
diff changeset
106 // is deoptimization. It likely no one else should ever use it.
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 address frame::raw_pc() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 if (is_deoptimized_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 return ((nmethod*) cb())->deopt_handler_begin() - pc_return_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
111 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return (pc() - pc_return_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
115
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Change the pc in a frame object. This does not change the actual pc in
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // actual frame. To do that use patch_pc.
a61af66fc99e Initial load
duke
parents:
diff changeset
118 //
a61af66fc99e Initial load
duke
parents:
diff changeset
119 void frame::set_pc(address newpc ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
121 if (_cb != NULL && _cb->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant violation");
a61af66fc99e Initial load
duke
parents:
diff changeset
123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
124 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Unsafe to use the is_deoptimzed tester after changing pc
a61af66fc99e Initial load
duke
parents:
diff changeset
127 _deopt_state = unknown;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 _pc = newpc;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 _cb = CodeCache::find_blob_unsafe(_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 // type testers
a61af66fc99e Initial load
duke
parents:
diff changeset
134 bool frame::is_deoptimized_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 assert(_deopt_state != unknown, "not answerable");
a61af66fc99e Initial load
duke
parents:
diff changeset
136 return _deopt_state == is_deoptimized;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 bool frame::is_native_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 return (_cb != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
141 _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
142 ((nmethod*)_cb)->is_native_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 bool frame::is_java_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 if (is_interpreted_frame()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (is_compiled_frame()) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152 bool frame::is_compiled_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 if (_cb != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
154 _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
155 ((nmethod*)_cb)->is_java_method()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 bool frame::is_runtime_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 return (_cb != NULL && _cb->is_runtime_stub());
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165
a61af66fc99e Initial load
duke
parents:
diff changeset
166 bool frame::is_safepoint_blob_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
167 return (_cb != NULL && _cb->is_safepoint_stub());
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 // testers
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 bool frame::is_first_java_frame() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 RegisterMap map(JavaThread::current(), false); // No update
a61af66fc99e Initial load
duke
parents:
diff changeset
174 frame s;
a61af66fc99e Initial load
duke
parents:
diff changeset
175 for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map));
a61af66fc99e Initial load
duke
parents:
diff changeset
176 return s.is_first_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179
a61af66fc99e Initial load
duke
parents:
diff changeset
180 bool frame::entry_frame_is_first() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 bool frame::should_be_deoptimized() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (_deopt_state == is_deoptimized ||
a61af66fc99e Initial load
duke
parents:
diff changeset
187 !is_compiled_frame() ) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 assert(_cb != NULL && _cb->is_nmethod(), "must be an nmethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
189 nmethod* nm = (nmethod *)_cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 if (TraceDependencies) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 tty->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 nm->print_value_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 if( !nm->is_marked_for_deoptimization() )
a61af66fc99e Initial load
duke
parents:
diff changeset
197 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
198
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // If at the return point, then the frame has already been popped, and
a61af66fc99e Initial load
duke
parents:
diff changeset
200 // only the return needs to be executed. Don't deoptimize here.
a61af66fc99e Initial load
duke
parents:
diff changeset
201 return !nm->is_at_poll_return(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 bool frame::can_be_deoptimized() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 if (!is_compiled_frame()) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 nmethod* nm = (nmethod*)_cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 if( !nm->can_be_deoptimized() )
a61af66fc99e Initial load
duke
parents:
diff changeset
209 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 return !nm->is_at_poll_return(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 void frame::deoptimize(JavaThread* thread, bool thread_is_known_safe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Schedule deoptimization of an nmethod activation with this frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217 // Store the original pc before an patch (or request to self-deopt)
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // in the published location of the frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 assert(_cb != NULL && _cb->is_nmethod(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
221 nmethod* nm = (nmethod*)_cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 // This is a fix for register window patching race
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if (NeedsDeoptSuspend && !thread_is_known_safe) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // It is possible especially with DeoptimizeALot/DeoptimizeRandom that
a61af66fc99e Initial load
duke
parents:
diff changeset
227 // we could see the frame again and ask for it to be deoptimized since
a61af66fc99e Initial load
duke
parents:
diff changeset
228 // it might move for a long time. That is harmless and we just ignore it.
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (id() == thread->must_deopt_id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 assert(thread->is_deopt_suspend(), "lost suspension");
a61af66fc99e Initial load
duke
parents:
diff changeset
231 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // We are at a safepoint so the target thread can only be
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // in 4 states:
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // blocked - no problem
a61af66fc99e Initial load
duke
parents:
diff changeset
237 // blocked_trans - no problem (i.e. could have woken up from blocked
a61af66fc99e Initial load
duke
parents:
diff changeset
238 // during a safepoint).
a61af66fc99e Initial load
duke
parents:
diff changeset
239 // native - register window pc patching race
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // native_trans - momentary state
a61af66fc99e Initial load
duke
parents:
diff changeset
241 //
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // We could just wait out a thread in native_trans to block.
a61af66fc99e Initial load
duke
parents:
diff changeset
243 // Then we'd have all the issues that the safepoint code has as to
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // whether to spin or block. It isn't worth it. Just treat it like
a61af66fc99e Initial load
duke
parents:
diff changeset
245 // native and be done with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
246 //
a61af66fc99e Initial load
duke
parents:
diff changeset
247 JavaThreadState state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (state == _thread_in_native || state == _thread_in_native_trans) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // Since we are at a safepoint the target thread will stop itself
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // before it can return to java as long as we remain at the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // Therefore we can put an additional request for the thread to stop
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // no matter what no (like a suspend). This will cause the thread
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // to notice it needs to do the deopt on its own once it leaves native.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 //
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // The only reason we must do this is because on machine with register
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // windows we have a race with patching the return address and the
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // window coming live as the thread returns to the Java code (but still
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // in native mode) and then blocks. It is only this top most frame
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // that is at risk. So in truth we could add an additional check to
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // see if this frame is one that is at risk.
a61af66fc99e Initial load
duke
parents:
diff changeset
261 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
262 frame at_risk = thread->last_frame().sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
263 if (id() == at_risk.id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 thread->set_must_deopt_id(id());
a61af66fc99e Initial load
duke
parents:
diff changeset
265 thread->set_deopt_suspend();
a61af66fc99e Initial load
duke
parents:
diff changeset
266 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
269 } // NeedsDeoptSuspend
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 address deopt = nm->deopt_handler_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // Save the original pc before we patch in the new one
a61af66fc99e Initial load
duke
parents:
diff changeset
274 nm->set_original_pc(this, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
275 patch_pc(thread, deopt);
a61af66fc99e Initial load
duke
parents:
diff changeset
276 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
277 {
a61af66fc99e Initial load
duke
parents:
diff changeset
278 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
279 frame check = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
280 while (id() != check.id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
281 check = check.sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
283 assert(check.is_deoptimized_frame(), "missed deopt");
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 frame frame::java_sender() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 RegisterMap map(JavaThread::current(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
290 frame s;
a61af66fc99e Initial load
duke
parents:
diff changeset
291 for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map)) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
292 guarantee(s.is_java_frame(), "tried to get caller of first java frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
293 return s;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296 frame frame::real_sender(RegisterMap* map) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
297 frame result = sender(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
298 while (result.is_runtime_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 result = result.sender(map);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
301 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // Note: called by profiler - NOT for current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
305 frame frame::profile_find_Java_sender_frame(JavaThread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
306 // If we don't recognize this frame, walk back up the stack until we do
a61af66fc99e Initial load
duke
parents:
diff changeset
307 RegisterMap map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 frame first_java_frame = frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 // Find the first Java frame on the stack starting with input frame
a61af66fc99e Initial load
duke
parents:
diff changeset
311 if (is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // top frame is compiled frame or deoptimized frame
a61af66fc99e Initial load
duke
parents:
diff changeset
313 first_java_frame = *this;
a61af66fc99e Initial load
duke
parents:
diff changeset
314 } else if (safe_for_sender(thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 for (frame sender_frame = sender(&map);
a61af66fc99e Initial load
duke
parents:
diff changeset
316 sender_frame.safe_for_sender(thread) && !sender_frame.is_first_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
317 sender_frame = sender_frame.sender(&map)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if (sender_frame.is_java_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 first_java_frame = sender_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
324 return first_java_frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // Interpreter frames
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 void frame::interpreter_frame_set_locals(intptr_t* locs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
332 *interpreter_frame_locals_addr() = locs;
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 methodOop frame::interpreter_frame_method() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
336 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
337 methodOop m = *interpreter_frame_method_addr();
a61af66fc99e Initial load
duke
parents:
diff changeset
338 assert(m->is_perm(), "bad methodOop in interpreter frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
339 assert(m->is_method(), "not a methodOop");
a61af66fc99e Initial load
duke
parents:
diff changeset
340 return m;
a61af66fc99e Initial load
duke
parents:
diff changeset
341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 void frame::interpreter_frame_set_method(methodOop method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
344 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
345 *interpreter_frame_method_addr() = method;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 void frame::interpreter_frame_set_bcx(intptr_t bcx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
349 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (ProfileInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 bool formerly_bci = is_bci(interpreter_frame_bcx());
a61af66fc99e Initial load
duke
parents:
diff changeset
352 bool is_now_bci = is_bci(bcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 *interpreter_frame_bcx_addr() = bcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355 intptr_t mdx = interpreter_frame_mdx();
a61af66fc99e Initial load
duke
parents:
diff changeset
356
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (mdx != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 if (formerly_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (!is_now_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // The bcx was just converted from bci to bcp.
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // Convert the mdx in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
362 methodDataOop mdo = interpreter_frame_method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
363 assert(mdo != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
364 int mdi = mdx - 1; // We distinguish valid mdi from zero by adding one.
a61af66fc99e Initial load
duke
parents:
diff changeset
365 address mdp = mdo->di_to_dp(mdi);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 interpreter_frame_set_mdx((intptr_t)mdp);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 if (is_now_bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
370 // The bcx was just converted from bcp to bci.
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // Convert the mdx in parallel.
a61af66fc99e Initial load
duke
parents:
diff changeset
372 methodDataOop mdo = interpreter_frame_method()->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
373 assert(mdo != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
374 int mdi = mdo->dp_to_di((address)mdx);
a61af66fc99e Initial load
duke
parents:
diff changeset
375 interpreter_frame_set_mdx((intptr_t)mdi + 1); // distinguish valid from 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 *interpreter_frame_bcx_addr() = bcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 jint frame::interpreter_frame_bci() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
386 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
387 return is_bci(bcx) ? bcx : interpreter_frame_method()->bci_from((address)bcx);
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 void frame::interpreter_frame_set_bci(jint bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
392 assert(!is_bci(interpreter_frame_bcx()), "should not set bci during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
393 interpreter_frame_set_bcx((intptr_t)interpreter_frame_method()->bcp_from(bci));
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 address frame::interpreter_frame_bcp() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
398 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
399 return is_bci(bcx) ? interpreter_frame_method()->bcp_from(bcx) : (address)bcx;
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 void frame::interpreter_frame_set_bcp(address bcp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
404 assert(!is_bci(interpreter_frame_bcx()), "should not set bcp during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
405 interpreter_frame_set_bcx((intptr_t)bcp);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 void frame::interpreter_frame_set_mdx(intptr_t mdx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
409 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
410 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
411 *interpreter_frame_mdx_addr() = mdx;
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413
a61af66fc99e Initial load
duke
parents:
diff changeset
414 address frame::interpreter_frame_mdp() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
415 assert(ProfileInterpreter, "must be profiling interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
416 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
417 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
418 intptr_t mdx = interpreter_frame_mdx();
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 assert(!is_bci(bcx), "should not access mdp during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
421 return (address)mdx;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 void frame::interpreter_frame_set_mdp(address mdp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
425 assert(is_interpreted_frame(), "interpreted frame expected");
a61af66fc99e Initial load
duke
parents:
diff changeset
426 if (mdp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427 // Always allow the mdp to be cleared.
a61af66fc99e Initial load
duke
parents:
diff changeset
428 interpreter_frame_set_mdx((intptr_t)mdp);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 intptr_t bcx = interpreter_frame_bcx();
a61af66fc99e Initial load
duke
parents:
diff changeset
431 assert(!is_bci(bcx), "should not set mdp during GC");
a61af66fc99e Initial load
duke
parents:
diff changeset
432 interpreter_frame_set_mdx((intptr_t)mdp);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 BasicObjectLock* frame::next_monitor_in_interpreter_frame(BasicObjectLock* current) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
436 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
437 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
438 interpreter_frame_verify_monitor(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
440 BasicObjectLock* next = (BasicObjectLock*) (((intptr_t*) current) + interpreter_frame_monitor_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
441 return next;
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 BasicObjectLock* frame::previous_monitor_in_interpreter_frame(BasicObjectLock* current) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
446 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // // This verification needs to be checked before being enabled
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // interpreter_frame_verify_monitor(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
450 BasicObjectLock* previous = (BasicObjectLock*) (((intptr_t*) current) - interpreter_frame_monitor_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
451 return previous;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // Interpreter locals and expression stack locations.
a61af66fc99e Initial load
duke
parents:
diff changeset
455
a61af66fc99e Initial load
duke
parents:
diff changeset
456 intptr_t* frame::interpreter_frame_local_at(int index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 const int n = Interpreter::local_offset_in_bytes(index)/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
458 return &((*interpreter_frame_locals_addr())[n]);
a61af66fc99e Initial load
duke
parents:
diff changeset
459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 frame::Tag frame::interpreter_frame_local_tag(int index) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 const int n = Interpreter::local_tag_offset_in_bytes(index)/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 return (Tag)(*interpreter_frame_locals_addr()) [n];
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 void frame::interpreter_frame_set_local_tag(int index, Tag tag) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
467 const int n = Interpreter::local_tag_offset_in_bytes(index)/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
468 (*interpreter_frame_locals_addr())[n] = (intptr_t)tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
470
a61af66fc99e Initial load
duke
parents:
diff changeset
471 intptr_t* frame::interpreter_frame_expression_stack_at(jint offset) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 const int i = offset * interpreter_frame_expression_stack_direction();
a61af66fc99e Initial load
duke
parents:
diff changeset
473 const int n = ((i * Interpreter::stackElementSize()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
474 Interpreter::value_offset_in_bytes())/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
475 return &(interpreter_frame_expression_stack()[n]);
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 frame::Tag frame::interpreter_frame_expression_stack_tag(jint offset) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 const int i = offset * interpreter_frame_expression_stack_direction();
a61af66fc99e Initial load
duke
parents:
diff changeset
480 const int n = ((i * Interpreter::stackElementSize()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
481 Interpreter::tag_offset_in_bytes())/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 return (Tag)(interpreter_frame_expression_stack()[n]);
a61af66fc99e Initial load
duke
parents:
diff changeset
483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
484
a61af66fc99e Initial load
duke
parents:
diff changeset
485 void frame::interpreter_frame_set_expression_stack_tag(jint offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
486 Tag tag) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 const int i = offset * interpreter_frame_expression_stack_direction();
a61af66fc99e Initial load
duke
parents:
diff changeset
488 const int n = ((i * Interpreter::stackElementSize()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
489 Interpreter::tag_offset_in_bytes())/wordSize;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 interpreter_frame_expression_stack()[n] = (intptr_t)tag;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 jint frame::interpreter_frame_expression_stack_size() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // Number of elements on the interpreter expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
495 // Callers should span by stackElementWords
a61af66fc99e Initial load
duke
parents:
diff changeset
496 int element_size = Interpreter::stackElementWords();
a61af66fc99e Initial load
duke
parents:
diff changeset
497 if (frame::interpreter_frame_expression_stack_direction() < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 return (interpreter_frame_expression_stack() -
a61af66fc99e Initial load
duke
parents:
diff changeset
499 interpreter_frame_tos_address() + 1)/element_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
500 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 return (interpreter_frame_tos_address() -
a61af66fc99e Initial load
duke
parents:
diff changeset
502 interpreter_frame_expression_stack() + 1)/element_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
505
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // (frame::interpreter_frame_sender_sp accessor is in frame_<arch>.cpp)
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 const char* frame::print_name() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
510 if (is_native_frame()) return "Native";
a61af66fc99e Initial load
duke
parents:
diff changeset
511 if (is_interpreted_frame()) return "Interpreted";
a61af66fc99e Initial load
duke
parents:
diff changeset
512 if (is_compiled_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 if (is_deoptimized_frame()) return "Deoptimized";
a61af66fc99e Initial load
duke
parents:
diff changeset
514 return "Compiled";
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516 if (sp() == NULL) return "Empty";
a61af66fc99e Initial load
duke
parents:
diff changeset
517 return "C";
a61af66fc99e Initial load
duke
parents:
diff changeset
518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 void frame::print_value_on(outputStream* st, JavaThread *thread) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
521 NOT_PRODUCT(address begin = pc()-40;)
a61af66fc99e Initial load
duke
parents:
diff changeset
522 NOT_PRODUCT(address end = NULL;)
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp());
a61af66fc99e Initial load
duke
parents:
diff changeset
525 if (sp() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
526 st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
527
a61af66fc99e Initial load
duke
parents:
diff changeset
528 if (StubRoutines::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 st->print_cr(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
530 st->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
531 StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
532 st->print("~Stub::%s", desc->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
533 NOT_PRODUCT(begin = desc->begin(); end = desc->end();)
a61af66fc99e Initial load
duke
parents:
diff changeset
534 } else if (Interpreter::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 st->print_cr(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
536 st->print("(");
a61af66fc99e Initial load
duke
parents:
diff changeset
537 InterpreterCodelet* desc = Interpreter::codelet_containing(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
538 if (desc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 st->print("~");
a61af66fc99e Initial load
duke
parents:
diff changeset
540 desc->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
541 NOT_PRODUCT(begin = desc->code_begin(); end = desc->code_end();)
a61af66fc99e Initial load
duke
parents:
diff changeset
542 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
543 st->print("~interpreter");
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546 st->print_cr(")");
a61af66fc99e Initial load
duke
parents:
diff changeset
547
a61af66fc99e Initial load
duke
parents:
diff changeset
548 if (_cb != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
550 _cb->print_value_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
551 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
552 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
553 if (end == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 begin = _cb->instructions_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
555 end = _cb->instructions_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 NOT_PRODUCT(if (WizardMode && Verbose) Disassembler::decode(begin, end);)
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 void frame::print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 print_value_on(st,NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
565 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 interpreter_frame_print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 void frame::interpreter_frame_print_on(outputStream* st) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
572 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
573 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
574 jint i;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 intptr_t x = *interpreter_frame_local_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
577 st->print(" - local [" INTPTR_FORMAT "]", x);
a61af66fc99e Initial load
duke
parents:
diff changeset
578 if (TaggedStackInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 Tag x = interpreter_frame_local_tag(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 st->print(" - local tag [" INTPTR_FORMAT "]", x);
a61af66fc99e Initial load
duke
parents:
diff changeset
581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
582 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
583 st->print_cr("; #%d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 intptr_t x = *interpreter_frame_expression_stack_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
587 st->print(" - stack [" INTPTR_FORMAT "]", x);
a61af66fc99e Initial load
duke
parents:
diff changeset
588 if (TaggedStackInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
589 Tag x = interpreter_frame_expression_stack_tag(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
590 st->print(" - stack tag [" INTPTR_FORMAT "]", x);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 st->print_cr("; #%d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
594 }
a61af66fc99e Initial load
duke
parents:
diff changeset
595 // locks for synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
596 for (BasicObjectLock* current = interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
597 current < interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
598 current = next_monitor_in_interpreter_frame(current)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
599 st->print_cr(" [ - obj ");
a61af66fc99e Initial load
duke
parents:
diff changeset
600 current->obj()->print_value_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
602 st->print_cr(" - lock ");
a61af66fc99e Initial load
duke
parents:
diff changeset
603 current->lock()->print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
604 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
607 st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin());
a61af66fc99e Initial load
duke
parents:
diff changeset
608 // bcp
a61af66fc99e Initial load
duke
parents:
diff changeset
609 st->print(" - bcp [" INTPTR_FORMAT "]", interpreter_frame_bcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
610 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
611 st->print_cr("; @%d", interpreter_frame_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
612 // locals
a61af66fc99e Initial load
duke
parents:
diff changeset
613 st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // method
a61af66fc99e Initial load
duke
parents:
diff changeset
615 st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
616 st->fill_to(23);
a61af66fc99e Initial load
duke
parents:
diff changeset
617 st->print("; ");
a61af66fc99e Initial load
duke
parents:
diff changeset
618 interpreter_frame_method()->print_name(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
619 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
620 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623 // Return whether the frame is in the VM or os indicating a Hotspot problem.
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Otherwise, it's likely a bug in the native library that the Java code calls,
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // hopefully indicating where to submit bugs.
a61af66fc99e Initial load
duke
parents:
diff changeset
626 static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 // C/C++ frame
a61af66fc99e Initial load
duke
parents:
diff changeset
628 bool in_vm = os::address_is_in_vm(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
629 st->print(in_vm ? "V" : "C");
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
632 bool found;
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // libname
a61af66fc99e Initial load
duke
parents:
diff changeset
635 found = os::dll_address_to_library_name(pc, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
636 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // skip directory names
a61af66fc99e Initial load
duke
parents:
diff changeset
638 const char *p1, *p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 p1 = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
640 int len = (int)strlen(os::file_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
641 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 st->print(" [%s+0x%x]", p1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
643 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
644 st->print(" " PTR_FORMAT, pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // function name - os::dll_address_to_function_name() may return confusing
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // names if pc is within jvm.dll or libjvm.so, because JVM only has
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // JVM_xxxx and a few other symbols in the dynamic symbol table. Do this
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // only for native libraries.
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if (!in_vm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 found = os::dll_address_to_function_name(pc, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
655 st->print(" %s+0x%x", buf, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // frame::print_on_error() is called by fatal error handler. Notice that we may
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // crash inside this function if stack frame is corrupted. The fatal error
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // handler can catch and handle the crash. Here we assume the frame is valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
663 //
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // First letter indicates type of the frame:
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // J: Java frame (compiled)
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // j: Java frame (interpreted)
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // V: VM frame (C/C++)
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // v: Other frames running VM generated code (e.g. stubs, adapters, etc.)
a61af66fc99e Initial load
duke
parents:
diff changeset
669 // C: C/C++ frame
a61af66fc99e Initial load
duke
parents:
diff changeset
670 //
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // We don't need detailed frame type as that in frame::print_name(). "C"
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // suggests the problem is in user lib; everything else is likely a VM bug.
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 if (_cb != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 if (Interpreter::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 methodOop m = this->interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
678 if (m != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
679 m->name_and_sig_as_C_string(buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
680 st->print("j %s", buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 st->print("+%d", this->interpreter_frame_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
682 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
683 st->print("j " PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
685 } else if (StubRoutines::contains(pc())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
686 StubCodeDesc* desc = StubCodeDesc::desc_for(pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
687 if (desc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 st->print("v ~StubRoutines::%s", desc->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
689 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 st->print("v ~StubRoutines::" PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
692 } else if (_cb->is_buffer_blob()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
694 } else if (_cb->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 methodOop m = ((nmethod *)_cb)->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 if (m != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 m->name_and_sig_as_C_string(buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
698 st->print("J %s", buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
700 st->print("J " PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702 } else if (_cb->is_runtime_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
703 st->print("v ~RuntimeStub::%s", ((RuntimeStub *)_cb)->name());
a61af66fc99e Initial load
duke
parents:
diff changeset
704 } else if (_cb->is_deoptimization_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
705 st->print("v ~DeoptimizationBlob");
a61af66fc99e Initial load
duke
parents:
diff changeset
706 } else if (_cb->is_exception_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
707 st->print("v ~ExceptionBlob");
a61af66fc99e Initial load
duke
parents:
diff changeset
708 } else if (_cb->is_safepoint_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 st->print("v ~SafepointBlob");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 st->print("v blob " PTR_FORMAT, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
714 print_C_frame(st, buf, buflen, pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718
a61af66fc99e Initial load
duke
parents:
diff changeset
719 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
720 The interpreter_frame_expression_stack_at method in the case of SPARC needs the
a61af66fc99e Initial load
duke
parents:
diff changeset
721 max_stack value of the method in order to compute the expression stack address.
a61af66fc99e Initial load
duke
parents:
diff changeset
722 It uses the methodOop in order to get the max_stack value but during GC this
a61af66fc99e Initial load
duke
parents:
diff changeset
723 methodOop value saved on the frame is changed by reverse_and_push and hence cannot
a61af66fc99e Initial load
duke
parents:
diff changeset
724 be used. So we save the max_stack value in the FrameClosure object and pass it
a61af66fc99e Initial load
duke
parents:
diff changeset
725 down to the interpreter_frame_expression_stack_at method
a61af66fc99e Initial load
duke
parents:
diff changeset
726 */
a61af66fc99e Initial load
duke
parents:
diff changeset
727 class InterpreterFrameClosure : public OffsetClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
728 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
729 frame* _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
730 OopClosure* _f;
a61af66fc99e Initial load
duke
parents:
diff changeset
731 int _max_locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
732 int _max_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
735 InterpreterFrameClosure(frame* fr, int max_locals, int max_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
736 OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 _fr = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
738 _max_locals = max_locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
739 _max_stack = max_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 void offset_do(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
744 oop* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 if (offset < _max_locals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
746 addr = (oop*) _fr->interpreter_frame_local_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
747 assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
748 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
749 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
750 addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals));
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // In case of exceptions, the expression stack is invalid and the esp will be reset to express
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel).
a61af66fc99e Initial load
duke
parents:
diff changeset
753 bool in_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 if (frame::interpreter_frame_expression_stack_direction() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
755 in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
756 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
759 if (in_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764
a61af66fc99e Initial load
duke
parents:
diff changeset
765 int max_locals() { return _max_locals; }
a61af66fc99e Initial load
duke
parents:
diff changeset
766 frame* fr() { return _fr; }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 };
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 class InterpretedArgumentOopFinder: public SignatureInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
771 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
772 OopClosure* _f; // Closure to invoke
a61af66fc99e Initial load
duke
parents:
diff changeset
773 int _offset; // TOS-relative offset, decremented with each argument
a61af66fc99e Initial load
duke
parents:
diff changeset
774 bool _is_static; // true if the callee is a static method
a61af66fc99e Initial load
duke
parents:
diff changeset
775 frame* _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 void set(int size, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
778 _offset -= size;
a61af66fc99e Initial load
duke
parents:
diff changeset
779 if (type == T_OBJECT || type == T_ARRAY) oop_offset_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
781
a61af66fc99e Initial load
duke
parents:
diff changeset
782 void oop_offset_do() {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 oop* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 addr = (oop*)_fr->interpreter_frame_tos_at(_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
785 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
789 InterpretedArgumentOopFinder(symbolHandle signature, bool is_static, frame* fr, OopClosure* f) : SignatureInfo(signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // compute size of arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
791 int args_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert(!fr->is_interpreted_frame() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
793 args_size <= fr->interpreter_frame_expression_stack_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
794 "args cannot be on stack anymore");
a61af66fc99e Initial load
duke
parents:
diff changeset
795 // initialize InterpretedArgumentOopFinder
a61af66fc99e Initial load
duke
parents:
diff changeset
796 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
797 _fr = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
798 _offset = args_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
799 _is_static = is_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
801
a61af66fc99e Initial load
duke
parents:
diff changeset
802 void oops_do() {
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if (!_is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
804 --_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
805 oop_offset_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807 iterate_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
809 };
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // Entry frame has following form (n arguments)
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // sp -> | last arg |
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
816 // : ::: :
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // (sp+n)->| first arg|
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // +-----------+
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821
a61af66fc99e Initial load
duke
parents:
diff changeset
822
a61af66fc99e Initial load
duke
parents:
diff changeset
823 // visits and GC's all the arguments in entry frame
a61af66fc99e Initial load
duke
parents:
diff changeset
824 class EntryFrameOopFinder: public SignatureInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
825 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
826 bool _is_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
827 int _offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
828 frame* _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 OopClosure* _f;
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 void set(int size, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
832 assert (_offset >= 0, "illegal offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
833 if (type == T_OBJECT || type == T_ARRAY) oop_at_offset_do(_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
834 _offset -= size;
a61af66fc99e Initial load
duke
parents:
diff changeset
835 }
a61af66fc99e Initial load
duke
parents:
diff changeset
836
a61af66fc99e Initial load
duke
parents:
diff changeset
837 void oop_at_offset_do(int offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
838 assert (offset >= 0, "illegal offset")
a61af66fc99e Initial load
duke
parents:
diff changeset
839 oop* addr = (oop*) _fr->entry_frame_argument_at(offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
840 _f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842
a61af66fc99e Initial load
duke
parents:
diff changeset
843 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
844 EntryFrameOopFinder(frame* frame, symbolHandle signature, bool is_static) : SignatureInfo(signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
845 _f = NULL; // will be set later
a61af66fc99e Initial load
duke
parents:
diff changeset
846 _fr = frame;
a61af66fc99e Initial load
duke
parents:
diff changeset
847 _is_static = is_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
848 _offset = ArgumentSizeComputer(signature).size() - 1; // last parameter is at index 0
a61af66fc99e Initial load
duke
parents:
diff changeset
849 }
a61af66fc99e Initial load
duke
parents:
diff changeset
850
a61af66fc99e Initial load
duke
parents:
diff changeset
851 void arguments_do(OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
852 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
853 if (!_is_static) oop_at_offset_do(_offset+1); // do the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
854 iterate_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 };
a61af66fc99e Initial load
duke
parents:
diff changeset
858
a61af66fc99e Initial load
duke
parents:
diff changeset
859 oop* frame::interpreter_callee_receiver_addr(symbolHandle signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 ArgumentSizeComputer asc(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
861 int size = asc.size();
a61af66fc99e Initial load
duke
parents:
diff changeset
862 return (oop *)interpreter_frame_tos_at(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
864
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
867 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
868 assert(map != NULL, "map must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
869 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
870 methodHandle m (thread, interpreter_frame_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
871 jint bci = interpreter_frame_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873 assert(Universe::heap()->is_in(m()), "must be valid oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
874 assert(m->is_method(), "checking frame value");
a61af66fc99e Initial load
duke
parents:
diff changeset
875 assert((m->is_native() && bci == 0) || (!m->is_native() && bci >= 0 && bci < m->code_size()), "invalid bci value");
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // Handle the monitor elements in the activation
a61af66fc99e Initial load
duke
parents:
diff changeset
878 for (
a61af66fc99e Initial load
duke
parents:
diff changeset
879 BasicObjectLock* current = interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
880 current < interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
881 current = next_monitor_in_interpreter_frame(current)
a61af66fc99e Initial load
duke
parents:
diff changeset
882 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
883 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
884 interpreter_frame_verify_monitor(current);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
886 current->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // process fixed part
a61af66fc99e Initial load
duke
parents:
diff changeset
890 f->do_oop((oop*)interpreter_frame_method_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
891 f->do_oop((oop*)interpreter_frame_cache_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
892
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // Hmm what about the mdp?
a61af66fc99e Initial load
duke
parents:
diff changeset
894 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // Interpreter frame in the midst of a call have a methodOop within the
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // object.
a61af66fc99e Initial load
duke
parents:
diff changeset
897 interpreterState istate = get_interpreterState();
a61af66fc99e Initial load
duke
parents:
diff changeset
898 if (istate->msg() == BytecodeInterpreter::call_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
899 f->do_oop((oop*)&istate->_result._to_call._callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 if (m->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
905 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
906 f->do_oop((oop*)&istate->_oop_temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
907 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
908 f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset ));
a61af66fc99e Initial load
duke
parents:
diff changeset
909 #endif /* CC_INTERP */
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 symbolHandle signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
915 bool is_static = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // Process a callee's arguments if we are at a call site
a61af66fc99e Initial load
duke
parents:
diff changeset
918 // (i.e., if we are at an invoke bytecode)
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // This is used sometimes for calling into the VM, not for another
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // interpreted or compiled frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
921 if (!m->is_native()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
922 Bytecode_invoke *call = Bytecode_invoke_at_check(m, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
923 if (call != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
924 signature = symbolHandle(thread, call->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
925 is_static = call->is_invokestatic();
a61af66fc99e Initial load
duke
parents:
diff changeset
926 if (map->include_argument_oops() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
927 interpreter_frame_expression_stack_size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 ResourceMark rm(thread); // is this right ???
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // we are at a call site & the expression stack is not empty
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // => process callee's arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
931 //
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // Note: The expression stack can be empty if an exception
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // occured during method resolution/execution. In all
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // cases we empty the expression stack completely be-
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // fore handling the exception (the exception handling
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // code in the interpreter calls a blocking runtime
a61af66fc99e Initial load
duke
parents:
diff changeset
937 // routine which can cause this code to be executed).
a61af66fc99e Initial load
duke
parents:
diff changeset
938 // (was bug gri 7/27/98)
a61af66fc99e Initial load
duke
parents:
diff changeset
939 oops_interpreted_arguments_do(signature, is_static, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944 if (TaggedStackInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // process locals & expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
946 InterpreterOopMap *mask = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
947 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
948 InterpreterOopMap oopmap_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 OopMapCache::compute_one_oop_map(m, bci, &oopmap_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
950 mask = &oopmap_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
952 oops_interpreted_locals_do(f, max_locals, mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
953 oops_interpreted_expressions_do(f, signature, is_static,
a61af66fc99e Initial load
duke
parents:
diff changeset
954 m->max_stack(),
a61af66fc99e Initial load
duke
parents:
diff changeset
955 max_locals, mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
956 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f);
a61af66fc99e Initial load
duke
parents:
diff changeset
958
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // process locals & expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
960 InterpreterOopMap mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 if (query_oop_map_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
962 m->mask_for(bci, &mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 OopMapCache::compute_one_oop_map(m, bci, &mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
966 mask.iterate_oop(&blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 void frame::oops_interpreted_locals_do(OopClosure *f,
a61af66fc99e Initial load
duke
parents:
diff changeset
972 int max_locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
973 InterpreterOopMap *mask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // Process locals then interpreter expression stack
a61af66fc99e Initial load
duke
parents:
diff changeset
975 for (int i = 0; i < max_locals; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
976 Tag tag = interpreter_frame_local_tag(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
977 if (tag == TagReference) {
a61af66fc99e Initial load
duke
parents:
diff changeset
978 oop* addr = (oop*) interpreter_frame_local_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
979 assert((intptr_t*)addr >= sp(), "must be inside the frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
980 f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
981 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
982 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 assert(tag == TagValue, "bad tag value for locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
984 oop* p = (oop*) interpreter_frame_local_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // Not always true - too bad. May have dead oops without tags in locals.
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // assert(*p == NULL || !(*p)->is_oop(), "oop not tagged on interpreter locals");
a61af66fc99e Initial load
duke
parents:
diff changeset
987 assert(*p == NULL || !mask->is_oop(i), "local oop map mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
988 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 void frame::oops_interpreted_expressions_do(OopClosure *f,
a61af66fc99e Initial load
duke
parents:
diff changeset
994 symbolHandle signature,
a61af66fc99e Initial load
duke
parents:
diff changeset
995 bool is_static,
a61af66fc99e Initial load
duke
parents:
diff changeset
996 int max_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
997 int max_locals,
a61af66fc99e Initial load
duke
parents:
diff changeset
998 InterpreterOopMap *mask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
999 // There is no stack no matter what the esp is pointing to (native methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // might look like expression stack is nonempty).
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 if (max_stack == 0) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 // Point the top of the expression stack above arguments to a call so
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 // arguments aren't gc'ed as both stack values for callee and callee
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // arguments in callee's locals.
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 int args_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 if (!signature.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 args_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 intptr_t *tos_addr = interpreter_frame_tos_at(args_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 assert(args_size != 0 || tos_addr == interpreter_frame_tos_address(), "these are same");
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 intptr_t *frst_expr = interpreter_frame_expression_stack_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 // In case of exceptions, the expression stack is invalid and the esp
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 // will be reset to express this condition. Therefore, we call f only
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // if addr is 'inside' the stack (i.e., addr >= esp for Intel).
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 bool in_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 if (interpreter_frame_expression_stack_direction() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 in_stack = (intptr_t*)frst_expr <= tos_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 in_stack = (intptr_t*)frst_expr >= tos_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 if (!in_stack) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 jint stack_size = interpreter_frame_expression_stack_size() - args_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 for (int j = 0; j < stack_size; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 Tag tag = interpreter_frame_expression_stack_tag(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 if (tag == TagReference) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 oop *addr = (oop*) interpreter_frame_expression_stack_at(j);
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 f->do_oop(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 assert(tag == TagValue, "bad tag value for stack element");
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 oop *p = (oop*) interpreter_frame_expression_stack_at((j));
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 assert(*p == NULL || !mask->is_oop(j+max_locals), "stack oop map mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1040
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 void frame::oops_interpreted_arguments_do(symbolHandle signature, bool is_static, OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 InterpretedArgumentOopFinder finder(signature, is_static, this, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 finder.oops_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1045
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 void frame::oops_code_blob_do(OopClosure* f, const RegisterMap* reg_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 assert(_cb != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 if (_cb->oop_maps() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 OopMapSet::oops_do(this, reg_map, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // Preserve potential arguments for a callee. We handle this by dispatching
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // on the codeblob. For c2i, we do
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 if (reg_map->include_argument_oops()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 _cb->preserve_callee_argument_oops(*this, reg_map, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // In cases where perm gen is collected, GC will want to mark
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // oops referenced from nmethods active on thread stacks so as to
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 // prevent them from being collected. However, this visit should be
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // restricted to certain phases of the collection only. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // closure answers whether it wants nmethods to be traced.
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // (All CodeBlob subtypes other than NMethod currently have
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 // an empty oops_do() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 if (f->do_nmethods()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 _cb->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1068
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 void frame::nmethods_code_blob_do() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 assert(_cb != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1071
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 // If we see an activation belonging to a non_entrant nmethod, we mark it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 if (_cb->is_nmethod() && ((nmethod *)_cb)->is_not_entrant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 ((nmethod*)_cb)->mark_as_seen_on_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 class CompiledArgumentOopFinder: public SignatureInfo {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 OopClosure* _f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 int _offset; // the current offset, incremented with each argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 bool _is_static; // true if the callee is a static method
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 frame _fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 RegisterMap* _reg_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 int _arg_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 VMRegPair* _regs; // VMReg list of arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 void set(int size, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 _offset += size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 virtual void handle_oop_offset() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 // Extract low order register number from register array.
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // In LP64-land, the high-order bits are valid but unhelpful.
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 VMReg reg = _regs[_offset].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 oop *loc = _fr.oopmapreg_to_location(reg, _reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 _f->do_oop(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1100
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 CompiledArgumentOopFinder(symbolHandle signature, bool is_static, OopClosure* f, frame fr, const RegisterMap* reg_map)
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 : SignatureInfo(signature) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // initialize CompiledArgumentOopFinder
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 _f = f;
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 _offset = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 _is_static = is_static;
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 _fr = fr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 _reg_map = (RegisterMap*)reg_map;
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 _arg_size = ArgumentSizeComputer(signature).size() + (is_static ? 0 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 int arg_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 _regs = SharedRuntime::find_callee_arguments(signature(), is_static, &arg_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 assert(arg_size == _arg_size, "wrong arg size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 void oops_do() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 if (!_is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 handle_oop_offset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 _offset++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 iterate_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 void frame::oops_compiled_arguments_do(symbolHandle signature, bool is_static, const RegisterMap* reg_map, OopClosure* f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 CompiledArgumentOopFinder finder(signature, is_static, f, *this, reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 finder.oops_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1132
a61af66fc99e Initial load
duke
parents:
diff changeset
1133
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // Get receiver out of callers frame, i.e. find parameter 0 in callers
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // frame. Consult ADLC for where parameter 0 is to be found. Then
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // check local reg_map for it being a callee-save register or argument
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // register, both of which are saved in the local frame. If not found
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // there, it must be an in-stack argument of the caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Note: caller.sp() points to callee-arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 oop frame::retrieve_receiver(RegisterMap* reg_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 frame caller = *this;
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // First consult the ADLC on where it puts parameter 0 for this signature.
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 VMReg reg = SharedRuntime::name_for_receiver();
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 oop r = *caller.oopmapreg_to_location(reg, reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 assert( Universe::heap()->is_in_or_null(r), "bad receiver" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 return r;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149
a61af66fc99e Initial load
duke
parents:
diff changeset
1150
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 if(reg->is_reg()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // If it is passed in a register, it got spilled in the stub frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 return (oop *)reg_map->location(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 int sp_offset_in_stack_slots = reg->reg2stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 int sp_offset = sp_offset_in_stack_slots >> (LogBytesPerWord - LogBytesPerInt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 return (oop *)&unextended_sp()[sp_offset];
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 BasicLock* frame::compiled_synchronized_native_monitor(nmethod* nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (nm == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 assert(_cb != NULL && _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 nm->method()->is_native() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 nm->method()->is_synchronized(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 "should not call this otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 nm = (nmethod*) _cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_sp_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 assert(byte_offset >= 0, "should not see invalid offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 return (BasicLock*) &sp()[byte_offset / wordSize];
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 oop frame::compiled_synchronized_native_monitor_owner(nmethod* nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 if (nm == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 assert(_cb != NULL && _cb->is_nmethod() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 nm->method()->is_native() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 nm->method()->is_synchronized(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 "should not call this otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 nm = (nmethod*) _cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 int byte_offset = in_bytes(nm->compiled_synchronized_native_basic_lock_owner_sp_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 assert(byte_offset >= 0, "should not see invalid offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 oop owner = ((oop*) sp())[byte_offset / wordSize];
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 assert( Universe::heap()->is_in(owner), "bad receiver" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 return owner;
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1189
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 assert(map != NULL, "map must be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 if (map->include_argument_oops()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // must collect argument oops, as nobody else is doing it
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 Thread *thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 methodHandle m (thread, entry_frame_call_wrapper()->callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 symbolHandle signature (thread, m->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 EntryFrameOopFinder finder(this, signature, m->is_static());
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 finder.arguments_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // Traverse the Handle Block saved in the entry frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 entry_frame_call_wrapper()->oops_do(f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1203
a61af66fc99e Initial load
duke
parents:
diff changeset
1204
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 void frame::oops_do_internal(OopClosure* f, RegisterMap* map, bool use_interpreter_oop_map_cache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 if (is_interpreted_frame()) { oops_interpreted_do(f, map, use_interpreter_oop_map_cache);
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 } else if (is_entry_frame()) { oops_entry_do (f, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 } else if (CodeCache::contains(pc())) { oops_code_blob_do (f, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1213
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 void frame::nmethods_do() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 if (_cb != NULL && _cb->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 nmethods_code_blob_do();
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1219
a61af66fc99e Initial load
duke
parents:
diff changeset
1220
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 void frame::gc_prologue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 // set bcx to bci to become methodOop position independent during GC
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 interpreter_frame_set_bcx(interpreter_frame_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 void frame::gc_epilogue() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 // set bcx back to bcp for interpreter
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 interpreter_frame_set_bcx((intptr_t)interpreter_frame_bcp());
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // call processor specific epilog function
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 pd_gc_epilog();
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 # ifdef ENABLE_ZAP_DEAD_LOCALS
a61af66fc99e Initial load
duke
parents:
diff changeset
1240
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 void frame::CheckValueClosure::do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 if (CheckOopishValues && Universe::heap()->is_in_reserved(*p)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 warning("value @ " INTPTR_FORMAT " looks oopish (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 frame::CheckValueClosure frame::_check_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1247
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 void frame::CheckOopClosure::do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 if (*p != NULL && !(*p)->is_oop()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 warning("value @ " INTPTR_FORMAT " should be an oop (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current());
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 frame::CheckOopClosure frame::_check_oop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 void frame::check_derived_oop(oop* base, oop* derived) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 _check_oop.do_oop(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
a61af66fc99e Initial load
duke
parents:
diff changeset
1260
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 void frame::ZapDeadClosure::do_oop(oop* p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p);
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Need cast because on _LP64 the conversion to oop is ambiguous. Constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // can be either long or int.
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 *p = (oop)(int)0xbabebabe;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 frame::ZapDeadClosure frame::_zap_dead;
a61af66fc99e Initial load
duke
parents:
diff changeset
1268
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 void frame::zap_dead_locals(JavaThread* thread, const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 assert(thread == Thread::current(), "need to synchronize to do this to another thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 // Tracing - part 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 if (TraceZapDeadLocals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 tty->print_cr("--------------------------------------------------------------------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 tty->print("Zapping dead locals in ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 print_on(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 // Zapping
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 if (is_entry_frame ()) zap_dead_entry_locals (thread, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 else if (is_interpreted_frame()) zap_dead_interpreted_locals(thread, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 else if (is_compiled_frame()) zap_dead_compiled_locals (thread, map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1283
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // could be is_runtime_frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // so remove error: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // Tracing - part 2
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 if (TraceZapDeadLocals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1293
a61af66fc99e Initial load
duke
parents:
diff changeset
1294
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // get current interpreter 'pc'
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 methodOop m = interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 int bci = interpreter_frame_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
1300
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 if (TaggedStackInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 InterpreterOopMap *mask = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 InterpreterOopMap oopmap_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 methodHandle method(thread, m);
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 OopMapCache::compute_one_oop_map(method, bci, &oopmap_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 mask = &oopmap_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 #endif // ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 oops_interpreted_locals_do(&_check_oop, max_locals, mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // process dynamic part
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 &_check_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 &_check_oop );
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 &_zap_dead );
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // get frame map
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 InterpreterOopMap mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 m->mask_for(bci, &mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 mask.iterate_all( &oop_blk, &value_blk, &dead_blk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1327
a61af66fc99e Initial load
duke
parents:
diff changeset
1328
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 void frame::zap_dead_compiled_locals(JavaThread* thread, const RegisterMap* reg_map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 assert(_cb != NULL, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 if (_cb->oop_maps() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 OopMapSet::all_do(this, reg_map, &_check_oop, check_derived_oop,
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 &_check_value, &_zap_dead);
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 void frame::zap_dead_entry_locals(JavaThread*, const RegisterMap*) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 if (TraceZapDeadLocals) warning("frame::zap_dead_entry_locals unimplemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 void frame::zap_dead_deoptimized_locals(JavaThread*, const RegisterMap*) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 if (TraceZapDeadLocals) warning("frame::zap_dead_deoptimized_locals unimplemented");
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1348
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 # endif // ENABLE_ZAP_DEAD_LOCALS
a61af66fc99e Initial load
duke
parents:
diff changeset
1350
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 void frame::verify(const RegisterMap* map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 // for now make sure receiver type is correct
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 if (is_interpreted_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 methodOop method = interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 guarantee(method->is_method(), "method is wrong in frame::verify");
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 if (!method->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 // fetch the receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 oop* p = (oop*) interpreter_frame_local_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // make sure we have the right receiver type
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");)
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 oops_do_internal(&VerifyOopClosure::verify_oop, (RegisterMap*)map, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 bool frame::verify_return_pc(address x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 if (StubRoutines::returns_to_call_stub(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 if (CodeCache::contains(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 if (Interpreter::contains(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1381
a61af66fc99e Initial load
duke
parents:
diff changeset
1382
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 assert(is_interpreted_frame(), "Not an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // verify that the value is in the right part of the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 address low_mark = (address) interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 address high_mark = (address) interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 address current = (address) value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 const int monitor_size = frame::interpreter_frame_monitor_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 guarantee((high_mark - current) % monitor_size == 0 , "Misaligned top of BasicObjectLock*");
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 guarantee( high_mark > current , "Current BasicObjectLock* higher than high_mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
1394
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 guarantee((current - low_mark) % monitor_size == 0 , "Misaligned bottom of BasicObjectLock*");
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 guarantee( current >= low_mark , "Current BasicObjectLock* below than low_mark");
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1399
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 //-----------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // StackFrameStream implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1403
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 StackFrameStream::StackFrameStream(JavaThread *thread, bool update) : _reg_map(thread, update) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 assert(thread->has_last_Java_frame(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 _fr = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 _is_done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }