Mercurial > hg > truffle
annotate src/share/vm/runtime/frame.cpp @ 6862:8a5ea0a9ccc4
7127708: G1: change task num types from int to uint in concurrent mark
Summary: Change the type of various task num fields, parameters etc to unsigned and rename them to be more consistent with the other collectors. Code changes were also reviewed by Vitaly Davidovich.
Reviewed-by: johnc
Contributed-by: Kaushik Srenevasan <kaushik@twitter.com>
author | johnc |
---|---|
date | Sat, 06 Oct 2012 01:17:44 -0700 |
parents | da91efe96a93 |
children | e522a00b91aa d0aa87f04bd5 cd3d6a6b95d9 |
rev | line source |
---|---|
0 | 1 /* |
4806
eaa9557116a2
7120448: Fix FP values for compiled frames in frame::describe
bdelsart
parents:
4042
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_interface/collectedHeap.inline.hpp" | |
27 #include "interpreter/interpreter.hpp" | |
28 #include "interpreter/oopMapCache.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "memory/universe.inline.hpp" | |
31 #include "oops/markOop.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
32 #include "oops/methodData.hpp" |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
33 #include "oops/method.hpp" |
1972 | 34 #include "oops/oop.inline.hpp" |
35 #include "oops/oop.inline2.hpp" | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
36 #include "prims/methodHandles.hpp" |
1972 | 37 #include "runtime/frame.inline.hpp" |
38 #include "runtime/handles.inline.hpp" | |
39 #include "runtime/javaCalls.hpp" | |
40 #include "runtime/monitorChunk.hpp" | |
41 #include "runtime/sharedRuntime.hpp" | |
42 #include "runtime/signature.hpp" | |
43 #include "runtime/stubCodeGenerator.hpp" | |
44 #include "runtime/stubRoutines.hpp" | |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
45 #include "utilities/decoder.hpp" |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
46 |
1972 | 47 #ifdef TARGET_ARCH_x86 |
48 # include "nativeInst_x86.hpp" | |
49 #endif | |
50 #ifdef TARGET_ARCH_sparc | |
51 # include "nativeInst_sparc.hpp" | |
52 #endif | |
53 #ifdef TARGET_ARCH_zero | |
54 # include "nativeInst_zero.hpp" | |
55 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
56 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
57 # include "nativeInst_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
58 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
59 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
60 # include "nativeInst_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
61 #endif |
0 | 62 |
63 RegisterMap::RegisterMap(JavaThread *thread, bool update_map) { | |
64 _thread = thread; | |
65 _update_map = update_map; | |
66 clear(); | |
67 debug_only(_update_for_id = NULL;) | |
68 #ifndef PRODUCT | |
69 for (int i = 0; i < reg_count ; i++ ) _location[i] = NULL; | |
70 #endif /* PRODUCT */ | |
71 } | |
72 | |
73 RegisterMap::RegisterMap(const RegisterMap* map) { | |
74 assert(map != this, "bad initialization parameter"); | |
75 assert(map != NULL, "RegisterMap must be present"); | |
76 _thread = map->thread(); | |
77 _update_map = map->update_map(); | |
78 _include_argument_oops = map->include_argument_oops(); | |
79 debug_only(_update_for_id = map->_update_for_id;) | |
80 pd_initialize_from(map); | |
81 if (update_map()) { | |
82 for(int i = 0; i < location_valid_size; i++) { | |
83 LocationValidType bits = !update_map() ? 0 : map->_location_valid[i]; | |
84 _location_valid[i] = bits; | |
85 // for whichever bits are set, pull in the corresponding map->_location | |
86 int j = i*location_valid_type_size; | |
87 while (bits != 0) { | |
88 if ((bits & 1) != 0) { | |
89 assert(0 <= j && j < reg_count, "range check"); | |
90 _location[j] = map->_location[j]; | |
91 } | |
92 bits >>= 1; | |
93 j += 1; | |
94 } | |
95 } | |
96 } | |
97 } | |
98 | |
99 void RegisterMap::clear() { | |
100 set_include_argument_oops(true); | |
101 if (_update_map) { | |
102 for(int i = 0; i < location_valid_size; i++) { | |
103 _location_valid[i] = 0; | |
104 } | |
105 pd_clear(); | |
106 } else { | |
107 pd_initialize(); | |
108 } | |
109 } | |
110 | |
111 #ifndef PRODUCT | |
112 | |
113 void RegisterMap::print_on(outputStream* st) const { | |
114 st->print_cr("Register map"); | |
115 for(int i = 0; i < reg_count; i++) { | |
116 | |
117 VMReg r = VMRegImpl::as_VMReg(i); | |
118 intptr_t* src = (intptr_t*) location(r); | |
119 if (src != NULL) { | |
120 | |
417 | 121 r->print_on(st); |
122 st->print(" [" INTPTR_FORMAT "] = ", src); | |
0 | 123 if (((uintptr_t)src & (sizeof(*src)-1)) != 0) { |
417 | 124 st->print_cr("<misaligned>"); |
0 | 125 } else { |
417 | 126 st->print_cr(INTPTR_FORMAT, *src); |
0 | 127 } |
128 } | |
129 } | |
130 } | |
131 | |
132 void RegisterMap::print() const { | |
133 print_on(tty); | |
134 } | |
135 | |
136 #endif | |
137 // This returns the pc that if you were in the debugger you'd see. Not | |
138 // the idealized value in the frame object. This undoes the magic conversion | |
139 // that happens for deoptimized frames. In addition it makes the value the | |
140 // hardware would want to see in the native frame. The only user (at this point) | |
141 // is deoptimization. It likely no one else should ever use it. | |
142 | |
143 address frame::raw_pc() const { | |
144 if (is_deoptimized_frame()) { | |
1204 | 145 nmethod* nm = cb()->as_nmethod_or_null(); |
146 if (nm->is_method_handle_return(pc())) | |
147 return nm->deopt_mh_handler_begin() - pc_return_offset; | |
148 else | |
149 return nm->deopt_handler_begin() - pc_return_offset; | |
0 | 150 } else { |
151 return (pc() - pc_return_offset); | |
152 } | |
153 } | |
154 | |
155 // Change the pc in a frame object. This does not change the actual pc in | |
156 // actual frame. To do that use patch_pc. | |
157 // | |
158 void frame::set_pc(address newpc ) { | |
159 #ifdef ASSERT | |
160 if (_cb != NULL && _cb->is_nmethod()) { | |
161 assert(!((nmethod*)_cb)->is_deopt_pc(_pc), "invariant violation"); | |
162 } | |
163 #endif // ASSERT | |
164 | |
165 // Unsafe to use the is_deoptimzed tester after changing pc | |
166 _deopt_state = unknown; | |
167 _pc = newpc; | |
168 _cb = CodeCache::find_blob_unsafe(_pc); | |
169 | |
170 } | |
171 | |
172 // type testers | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4872
diff
changeset
|
173 bool frame::is_ignored_frame() const { |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4872
diff
changeset
|
174 return false; // FIXME: some LambdaForm frames should be ignored |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
175 } |
0 | 176 bool frame::is_deoptimized_frame() const { |
177 assert(_deopt_state != unknown, "not answerable"); | |
178 return _deopt_state == is_deoptimized; | |
179 } | |
180 | |
181 bool frame::is_native_frame() const { | |
182 return (_cb != NULL && | |
183 _cb->is_nmethod() && | |
184 ((nmethod*)_cb)->is_native_method()); | |
185 } | |
186 | |
187 bool frame::is_java_frame() const { | |
188 if (is_interpreted_frame()) return true; | |
189 if (is_compiled_frame()) return true; | |
190 return false; | |
191 } | |
192 | |
193 | |
194 bool frame::is_compiled_frame() const { | |
195 if (_cb != NULL && | |
196 _cb->is_nmethod() && | |
197 ((nmethod*)_cb)->is_java_method()) { | |
198 return true; | |
199 } | |
200 return false; | |
201 } | |
202 | |
203 | |
204 bool frame::is_runtime_frame() const { | |
205 return (_cb != NULL && _cb->is_runtime_stub()); | |
206 } | |
207 | |
208 bool frame::is_safepoint_blob_frame() const { | |
209 return (_cb != NULL && _cb->is_safepoint_stub()); | |
210 } | |
211 | |
212 // testers | |
213 | |
214 bool frame::is_first_java_frame() const { | |
215 RegisterMap map(JavaThread::current(), false); // No update | |
216 frame s; | |
217 for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map)); | |
218 return s.is_first_frame(); | |
219 } | |
220 | |
221 | |
222 bool frame::entry_frame_is_first() const { | |
223 return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL; | |
224 } | |
225 | |
226 | |
227 bool frame::should_be_deoptimized() const { | |
228 if (_deopt_state == is_deoptimized || | |
229 !is_compiled_frame() ) return false; | |
230 assert(_cb != NULL && _cb->is_nmethod(), "must be an nmethod"); | |
231 nmethod* nm = (nmethod *)_cb; | |
232 if (TraceDependencies) { | |
233 tty->print("checking (%s) ", nm->is_marked_for_deoptimization() ? "true" : "false"); | |
234 nm->print_value_on(tty); | |
235 tty->cr(); | |
236 } | |
237 | |
238 if( !nm->is_marked_for_deoptimization() ) | |
239 return false; | |
240 | |
241 // If at the return point, then the frame has already been popped, and | |
242 // only the return needs to be executed. Don't deoptimize here. | |
243 return !nm->is_at_poll_return(pc()); | |
244 } | |
245 | |
246 bool frame::can_be_deoptimized() const { | |
247 if (!is_compiled_frame()) return false; | |
248 nmethod* nm = (nmethod*)_cb; | |
249 | |
250 if( !nm->can_be_deoptimized() ) | |
251 return false; | |
252 | |
253 return !nm->is_at_poll_return(pc()); | |
254 } | |
255 | |
1727
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
256 void frame::deoptimize(JavaThread* thread) { |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
257 // Schedule deoptimization of an nmethod activation with this frame. |
0 | 258 assert(_cb != NULL && _cb->is_nmethod(), "must be"); |
259 nmethod* nm = (nmethod*)_cb; | |
260 | |
261 // This is a fix for register window patching race | |
1727
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
262 if (NeedsDeoptSuspend && Thread::current() != thread) { |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
263 assert(SafepointSynchronize::is_at_safepoint(), |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
264 "patching other threads for deopt may only occur at a safepoint"); |
0 | 265 |
266 // It is possible especially with DeoptimizeALot/DeoptimizeRandom that | |
267 // we could see the frame again and ask for it to be deoptimized since | |
268 // it might move for a long time. That is harmless and we just ignore it. | |
269 if (id() == thread->must_deopt_id()) { | |
270 assert(thread->is_deopt_suspend(), "lost suspension"); | |
271 return; | |
272 } | |
273 | |
274 // We are at a safepoint so the target thread can only be | |
275 // in 4 states: | |
276 // blocked - no problem | |
277 // blocked_trans - no problem (i.e. could have woken up from blocked | |
278 // during a safepoint). | |
279 // native - register window pc patching race | |
280 // native_trans - momentary state | |
281 // | |
282 // We could just wait out a thread in native_trans to block. | |
283 // Then we'd have all the issues that the safepoint code has as to | |
284 // whether to spin or block. It isn't worth it. Just treat it like | |
285 // native and be done with it. | |
286 // | |
1727
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
287 // Examine the state of the thread at the start of safepoint since |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
288 // threads that were in native at the start of the safepoint could |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
289 // come to a halt during the safepoint, changing the current value |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
290 // of the safepoint_state. |
da877bdc9000
6975006: assert(check.is_deoptimized_frame()) failed: missed deopt
never
parents:
1692
diff
changeset
|
291 JavaThreadState state = thread->safepoint_state()->orig_thread_state(); |
0 | 292 if (state == _thread_in_native || state == _thread_in_native_trans) { |
293 // Since we are at a safepoint the target thread will stop itself | |
294 // before it can return to java as long as we remain at the safepoint. | |
295 // Therefore we can put an additional request for the thread to stop | |
296 // no matter what no (like a suspend). This will cause the thread | |
297 // to notice it needs to do the deopt on its own once it leaves native. | |
298 // | |
299 // The only reason we must do this is because on machine with register | |
300 // windows we have a race with patching the return address and the | |
301 // window coming live as the thread returns to the Java code (but still | |
302 // in native mode) and then blocks. It is only this top most frame | |
303 // that is at risk. So in truth we could add an additional check to | |
304 // see if this frame is one that is at risk. | |
305 RegisterMap map(thread, false); | |
306 frame at_risk = thread->last_frame().sender(&map); | |
307 if (id() == at_risk.id()) { | |
308 thread->set_must_deopt_id(id()); | |
309 thread->set_deopt_suspend(); | |
310 return; | |
311 } | |
312 } | |
313 } // NeedsDeoptSuspend | |
314 | |
315 | |
1204 | 316 // If the call site is a MethodHandle call site use the MH deopt |
317 // handler. | |
318 address deopt = nm->is_method_handle_return(pc()) ? | |
319 nm->deopt_mh_handler_begin() : | |
320 nm->deopt_handler_begin(); | |
321 | |
0 | 322 // Save the original pc before we patch in the new one |
323 nm->set_original_pc(this, pc()); | |
324 patch_pc(thread, deopt); | |
1204 | 325 |
0 | 326 #ifdef ASSERT |
327 { | |
328 RegisterMap map(thread, false); | |
329 frame check = thread->last_frame(); | |
330 while (id() != check.id()) { | |
331 check = check.sender(&map); | |
332 } | |
333 assert(check.is_deoptimized_frame(), "missed deopt"); | |
334 } | |
335 #endif // ASSERT | |
336 } | |
337 | |
338 frame frame::java_sender() const { | |
339 RegisterMap map(JavaThread::current(), false); | |
340 frame s; | |
341 for (s = sender(&map); !(s.is_java_frame() || s.is_first_frame()); s = s.sender(&map)) ; | |
342 guarantee(s.is_java_frame(), "tried to get caller of first java frame"); | |
343 return s; | |
344 } | |
345 | |
346 frame frame::real_sender(RegisterMap* map) const { | |
347 frame result = sender(map); | |
3363
167b70ff3abc
6939861: JVM should handle more conversion operations
never
parents:
3336
diff
changeset
|
348 while (result.is_runtime_frame() || |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4872
diff
changeset
|
349 result.is_ignored_frame()) { |
0 | 350 result = result.sender(map); |
351 } | |
352 return result; | |
353 } | |
354 | |
355 // Note: called by profiler - NOT for current thread | |
356 frame frame::profile_find_Java_sender_frame(JavaThread *thread) { | |
357 // If we don't recognize this frame, walk back up the stack until we do | |
358 RegisterMap map(thread, false); | |
359 frame first_java_frame = frame(); | |
360 | |
361 // Find the first Java frame on the stack starting with input frame | |
362 if (is_java_frame()) { | |
363 // top frame is compiled frame or deoptimized frame | |
364 first_java_frame = *this; | |
365 } else if (safe_for_sender(thread)) { | |
366 for (frame sender_frame = sender(&map); | |
367 sender_frame.safe_for_sender(thread) && !sender_frame.is_first_frame(); | |
368 sender_frame = sender_frame.sender(&map)) { | |
369 if (sender_frame.is_java_frame()) { | |
370 first_java_frame = sender_frame; | |
371 break; | |
372 } | |
373 } | |
374 } | |
375 return first_java_frame; | |
376 } | |
377 | |
378 // Interpreter frames | |
379 | |
380 | |
381 void frame::interpreter_frame_set_locals(intptr_t* locs) { | |
382 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
383 *interpreter_frame_locals_addr() = locs; | |
384 } | |
385 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
386 Method* frame::interpreter_frame_method() const { |
0 | 387 assert(is_interpreted_frame(), "interpreted frame expected"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
388 Method* m = *interpreter_frame_method_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
389 assert(m->is_metadata(), "bad Method* in interpreter frame"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
390 assert(m->is_method(), "not a Method*"); |
0 | 391 return m; |
392 } | |
393 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
394 void frame::interpreter_frame_set_method(Method* method) { |
0 | 395 assert(is_interpreted_frame(), "interpreted frame expected"); |
396 *interpreter_frame_method_addr() = method; | |
397 } | |
398 | |
399 void frame::interpreter_frame_set_bcx(intptr_t bcx) { | |
400 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
401 if (ProfileInterpreter) { | |
402 bool formerly_bci = is_bci(interpreter_frame_bcx()); | |
403 bool is_now_bci = is_bci(bcx); | |
404 *interpreter_frame_bcx_addr() = bcx; | |
405 | |
406 intptr_t mdx = interpreter_frame_mdx(); | |
407 | |
408 if (mdx != 0) { | |
409 if (formerly_bci) { | |
410 if (!is_now_bci) { | |
411 // The bcx was just converted from bci to bcp. | |
412 // Convert the mdx in parallel. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
413 MethodData* mdo = interpreter_frame_method()->method_data(); |
0 | 414 assert(mdo != NULL, ""); |
415 int mdi = mdx - 1; // We distinguish valid mdi from zero by adding one. | |
416 address mdp = mdo->di_to_dp(mdi); | |
417 interpreter_frame_set_mdx((intptr_t)mdp); | |
418 } | |
419 } else { | |
420 if (is_now_bci) { | |
421 // The bcx was just converted from bcp to bci. | |
422 // Convert the mdx in parallel. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
423 MethodData* mdo = interpreter_frame_method()->method_data(); |
0 | 424 assert(mdo != NULL, ""); |
425 int mdi = mdo->dp_to_di((address)mdx); | |
426 interpreter_frame_set_mdx((intptr_t)mdi + 1); // distinguish valid from 0. | |
427 } | |
428 } | |
429 } | |
430 } else { | |
431 *interpreter_frame_bcx_addr() = bcx; | |
432 } | |
433 } | |
434 | |
435 jint frame::interpreter_frame_bci() const { | |
436 assert(is_interpreted_frame(), "interpreted frame expected"); | |
437 intptr_t bcx = interpreter_frame_bcx(); | |
438 return is_bci(bcx) ? bcx : interpreter_frame_method()->bci_from((address)bcx); | |
439 } | |
440 | |
441 void frame::interpreter_frame_set_bci(jint bci) { | |
442 assert(is_interpreted_frame(), "interpreted frame expected"); | |
443 assert(!is_bci(interpreter_frame_bcx()), "should not set bci during GC"); | |
444 interpreter_frame_set_bcx((intptr_t)interpreter_frame_method()->bcp_from(bci)); | |
445 } | |
446 | |
447 address frame::interpreter_frame_bcp() const { | |
448 assert(is_interpreted_frame(), "interpreted frame expected"); | |
449 intptr_t bcx = interpreter_frame_bcx(); | |
450 return is_bci(bcx) ? interpreter_frame_method()->bcp_from(bcx) : (address)bcx; | |
451 } | |
452 | |
453 void frame::interpreter_frame_set_bcp(address bcp) { | |
454 assert(is_interpreted_frame(), "interpreted frame expected"); | |
455 assert(!is_bci(interpreter_frame_bcx()), "should not set bcp during GC"); | |
456 interpreter_frame_set_bcx((intptr_t)bcp); | |
457 } | |
458 | |
459 void frame::interpreter_frame_set_mdx(intptr_t mdx) { | |
460 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
461 assert(ProfileInterpreter, "must be profiling interpreter"); | |
462 *interpreter_frame_mdx_addr() = mdx; | |
463 } | |
464 | |
465 address frame::interpreter_frame_mdp() const { | |
466 assert(ProfileInterpreter, "must be profiling interpreter"); | |
467 assert(is_interpreted_frame(), "interpreted frame expected"); | |
468 intptr_t bcx = interpreter_frame_bcx(); | |
469 intptr_t mdx = interpreter_frame_mdx(); | |
470 | |
471 assert(!is_bci(bcx), "should not access mdp during GC"); | |
472 return (address)mdx; | |
473 } | |
474 | |
475 void frame::interpreter_frame_set_mdp(address mdp) { | |
476 assert(is_interpreted_frame(), "interpreted frame expected"); | |
477 if (mdp == NULL) { | |
478 // Always allow the mdp to be cleared. | |
479 interpreter_frame_set_mdx((intptr_t)mdp); | |
480 } | |
481 intptr_t bcx = interpreter_frame_bcx(); | |
482 assert(!is_bci(bcx), "should not set mdp during GC"); | |
483 interpreter_frame_set_mdx((intptr_t)mdp); | |
484 } | |
485 | |
486 BasicObjectLock* frame::next_monitor_in_interpreter_frame(BasicObjectLock* current) const { | |
487 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
488 #ifdef ASSERT | |
489 interpreter_frame_verify_monitor(current); | |
490 #endif | |
491 BasicObjectLock* next = (BasicObjectLock*) (((intptr_t*) current) + interpreter_frame_monitor_size()); | |
492 return next; | |
493 } | |
494 | |
495 BasicObjectLock* frame::previous_monitor_in_interpreter_frame(BasicObjectLock* current) const { | |
496 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
497 #ifdef ASSERT | |
498 // // This verification needs to be checked before being enabled | |
499 // interpreter_frame_verify_monitor(current); | |
500 #endif | |
501 BasicObjectLock* previous = (BasicObjectLock*) (((intptr_t*) current) - interpreter_frame_monitor_size()); | |
502 return previous; | |
503 } | |
504 | |
505 // Interpreter locals and expression stack locations. | |
506 | |
507 intptr_t* frame::interpreter_frame_local_at(int index) const { | |
508 const int n = Interpreter::local_offset_in_bytes(index)/wordSize; | |
509 return &((*interpreter_frame_locals_addr())[n]); | |
510 } | |
511 | |
512 intptr_t* frame::interpreter_frame_expression_stack_at(jint offset) const { | |
513 const int i = offset * interpreter_frame_expression_stack_direction(); | |
1506 | 514 const int n = i * Interpreter::stackElementWords; |
0 | 515 return &(interpreter_frame_expression_stack()[n]); |
516 } | |
517 | |
518 jint frame::interpreter_frame_expression_stack_size() const { | |
519 // Number of elements on the interpreter expression stack | |
520 // Callers should span by stackElementWords | |
1506 | 521 int element_size = Interpreter::stackElementWords; |
0 | 522 if (frame::interpreter_frame_expression_stack_direction() < 0) { |
523 return (interpreter_frame_expression_stack() - | |
524 interpreter_frame_tos_address() + 1)/element_size; | |
525 } else { | |
526 return (interpreter_frame_tos_address() - | |
527 interpreter_frame_expression_stack() + 1)/element_size; | |
528 } | |
529 } | |
530 | |
531 | |
532 // (frame::interpreter_frame_sender_sp accessor is in frame_<arch>.cpp) | |
533 | |
534 const char* frame::print_name() const { | |
535 if (is_native_frame()) return "Native"; | |
536 if (is_interpreted_frame()) return "Interpreted"; | |
537 if (is_compiled_frame()) { | |
538 if (is_deoptimized_frame()) return "Deoptimized"; | |
539 return "Compiled"; | |
540 } | |
541 if (sp() == NULL) return "Empty"; | |
542 return "C"; | |
543 } | |
544 | |
545 void frame::print_value_on(outputStream* st, JavaThread *thread) const { | |
546 NOT_PRODUCT(address begin = pc()-40;) | |
547 NOT_PRODUCT(address end = NULL;) | |
548 | |
549 st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp()); | |
550 if (sp() != NULL) | |
551 st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc()); | |
552 | |
553 if (StubRoutines::contains(pc())) { | |
554 st->print_cr(")"); | |
555 st->print("("); | |
556 StubCodeDesc* desc = StubCodeDesc::desc_for(pc()); | |
557 st->print("~Stub::%s", desc->name()); | |
558 NOT_PRODUCT(begin = desc->begin(); end = desc->end();) | |
559 } else if (Interpreter::contains(pc())) { | |
560 st->print_cr(")"); | |
561 st->print("("); | |
562 InterpreterCodelet* desc = Interpreter::codelet_containing(pc()); | |
563 if (desc != NULL) { | |
564 st->print("~"); | |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4824
diff
changeset
|
565 desc->print_on(st); |
0 | 566 NOT_PRODUCT(begin = desc->code_begin(); end = desc->code_end();) |
567 } else { | |
568 st->print("~interpreter"); | |
569 } | |
570 } | |
571 st->print_cr(")"); | |
572 | |
573 if (_cb != NULL) { | |
574 st->print(" "); | |
575 _cb->print_value_on(st); | |
576 st->cr(); | |
577 #ifndef PRODUCT | |
578 if (end == NULL) { | |
1748 | 579 begin = _cb->code_begin(); |
580 end = _cb->code_end(); | |
0 | 581 } |
582 #endif | |
583 } | |
584 NOT_PRODUCT(if (WizardMode && Verbose) Disassembler::decode(begin, end);) | |
585 } | |
586 | |
587 | |
588 void frame::print_on(outputStream* st) const { | |
589 print_value_on(st,NULL); | |
590 if (is_interpreted_frame()) { | |
591 interpreter_frame_print_on(st); | |
592 } | |
593 } | |
594 | |
595 | |
596 void frame::interpreter_frame_print_on(outputStream* st) const { | |
597 #ifndef PRODUCT | |
598 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
599 jint i; | |
600 for (i = 0; i < interpreter_frame_method()->max_locals(); i++ ) { | |
601 intptr_t x = *interpreter_frame_local_at(i); | |
602 st->print(" - local [" INTPTR_FORMAT "]", x); | |
603 st->fill_to(23); | |
604 st->print_cr("; #%d", i); | |
605 } | |
606 for (i = interpreter_frame_expression_stack_size() - 1; i >= 0; --i ) { | |
607 intptr_t x = *interpreter_frame_expression_stack_at(i); | |
608 st->print(" - stack [" INTPTR_FORMAT "]", x); | |
609 st->fill_to(23); | |
610 st->print_cr("; #%d", i); | |
611 } | |
612 // locks for synchronization | |
613 for (BasicObjectLock* current = interpreter_frame_monitor_end(); | |
614 current < interpreter_frame_monitor_begin(); | |
615 current = next_monitor_in_interpreter_frame(current)) { | |
1255
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
1204
diff
changeset
|
616 st->print(" - obj ["); |
0 | 617 current->obj()->print_value_on(st); |
1255
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
1204
diff
changeset
|
618 st->print_cr("]"); |
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
1204
diff
changeset
|
619 st->print(" - lock ["); |
0 | 620 current->lock()->print_on(st); |
1255
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
1204
diff
changeset
|
621 st->print_cr("]"); |
0 | 622 } |
623 // monitor | |
624 st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin()); | |
625 // bcp | |
626 st->print(" - bcp [" INTPTR_FORMAT "]", interpreter_frame_bcp()); | |
627 st->fill_to(23); | |
628 st->print_cr("; @%d", interpreter_frame_bci()); | |
629 // locals | |
630 st->print_cr(" - locals [" INTPTR_FORMAT "]", interpreter_frame_local_at(0)); | |
631 // method | |
632 st->print(" - method [" INTPTR_FORMAT "]", (address)interpreter_frame_method()); | |
633 st->fill_to(23); | |
634 st->print("; "); | |
635 interpreter_frame_method()->print_name(st); | |
636 st->cr(); | |
637 #endif | |
638 } | |
639 | |
640 // Return whether the frame is in the VM or os indicating a Hotspot problem. | |
641 // Otherwise, it's likely a bug in the native library that the Java code calls, | |
642 // hopefully indicating where to submit bugs. | |
643 static void print_C_frame(outputStream* st, char* buf, int buflen, address pc) { | |
644 // C/C++ frame | |
645 bool in_vm = os::address_is_in_vm(pc); | |
646 st->print(in_vm ? "V" : "C"); | |
647 | |
648 int offset; | |
649 bool found; | |
650 | |
651 // libname | |
652 found = os::dll_address_to_library_name(pc, buf, buflen, &offset); | |
653 if (found) { | |
654 // skip directory names | |
655 const char *p1, *p2; | |
656 p1 = buf; | |
657 int len = (int)strlen(os::file_separator()); | |
658 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; | |
659 st->print(" [%s+0x%x]", p1, offset); | |
660 } else { | |
661 st->print(" " PTR_FORMAT, pc); | |
662 } | |
663 | |
664 // function name - os::dll_address_to_function_name() may return confusing | |
665 // names if pc is within jvm.dll or libjvm.so, because JVM only has | |
666 // JVM_xxxx and a few other symbols in the dynamic symbol table. Do this | |
667 // only for native libraries. | |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
668 if (!in_vm || Decoder::can_decode_C_frame_in_vm()) { |
0 | 669 found = os::dll_address_to_function_name(pc, buf, buflen, &offset); |
670 | |
671 if (found) { | |
672 st->print(" %s+0x%x", buf, offset); | |
673 } | |
674 } | |
675 } | |
676 | |
677 // frame::print_on_error() is called by fatal error handler. Notice that we may | |
678 // crash inside this function if stack frame is corrupted. The fatal error | |
679 // handler can catch and handle the crash. Here we assume the frame is valid. | |
680 // | |
681 // First letter indicates type of the frame: | |
682 // J: Java frame (compiled) | |
683 // j: Java frame (interpreted) | |
684 // V: VM frame (C/C++) | |
685 // v: Other frames running VM generated code (e.g. stubs, adapters, etc.) | |
686 // C: C/C++ frame | |
687 // | |
688 // We don't need detailed frame type as that in frame::print_name(). "C" | |
689 // suggests the problem is in user lib; everything else is likely a VM bug. | |
690 | |
691 void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const { | |
692 if (_cb != NULL) { | |
693 if (Interpreter::contains(pc())) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
694 Method* m = this->interpreter_frame_method(); |
0 | 695 if (m != NULL) { |
696 m->name_and_sig_as_C_string(buf, buflen); | |
697 st->print("j %s", buf); | |
698 st->print("+%d", this->interpreter_frame_bci()); | |
699 } else { | |
700 st->print("j " PTR_FORMAT, pc()); | |
701 } | |
702 } else if (StubRoutines::contains(pc())) { | |
703 StubCodeDesc* desc = StubCodeDesc::desc_for(pc()); | |
704 if (desc != NULL) { | |
705 st->print("v ~StubRoutines::%s", desc->name()); | |
706 } else { | |
707 st->print("v ~StubRoutines::" PTR_FORMAT, pc()); | |
708 } | |
709 } else if (_cb->is_buffer_blob()) { | |
710 st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); | |
711 } else if (_cb->is_nmethod()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
712 Method* m = ((nmethod *)_cb)->method(); |
0 | 713 if (m != NULL) { |
714 m->name_and_sig_as_C_string(buf, buflen); | |
715 st->print("J %s", buf); | |
716 } else { | |
717 st->print("J " PTR_FORMAT, pc()); | |
718 } | |
719 } else if (_cb->is_runtime_stub()) { | |
720 st->print("v ~RuntimeStub::%s", ((RuntimeStub *)_cb)->name()); | |
721 } else if (_cb->is_deoptimization_stub()) { | |
722 st->print("v ~DeoptimizationBlob"); | |
723 } else if (_cb->is_exception_stub()) { | |
724 st->print("v ~ExceptionBlob"); | |
725 } else if (_cb->is_safepoint_stub()) { | |
726 st->print("v ~SafepointBlob"); | |
727 } else { | |
728 st->print("v blob " PTR_FORMAT, pc()); | |
729 } | |
730 } else { | |
731 print_C_frame(st, buf, buflen, pc()); | |
732 } | |
733 } | |
734 | |
735 | |
736 /* | |
737 The interpreter_frame_expression_stack_at method in the case of SPARC needs the | |
738 max_stack value of the method in order to compute the expression stack address. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
739 It uses the Method* in order to get the max_stack value but during GC this |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
740 Method* value saved on the frame is changed by reverse_and_push and hence cannot |
0 | 741 be used. So we save the max_stack value in the FrameClosure object and pass it |
742 down to the interpreter_frame_expression_stack_at method | |
743 */ | |
744 class InterpreterFrameClosure : public OffsetClosure { | |
745 private: | |
746 frame* _fr; | |
747 OopClosure* _f; | |
748 int _max_locals; | |
749 int _max_stack; | |
750 | |
751 public: | |
752 InterpreterFrameClosure(frame* fr, int max_locals, int max_stack, | |
753 OopClosure* f) { | |
754 _fr = fr; | |
755 _max_locals = max_locals; | |
756 _max_stack = max_stack; | |
757 _f = f; | |
758 } | |
759 | |
760 void offset_do(int offset) { | |
761 oop* addr; | |
762 if (offset < _max_locals) { | |
763 addr = (oop*) _fr->interpreter_frame_local_at(offset); | |
764 assert((intptr_t*)addr >= _fr->sp(), "must be inside the frame"); | |
765 _f->do_oop(addr); | |
766 } else { | |
767 addr = (oop*) _fr->interpreter_frame_expression_stack_at((offset - _max_locals)); | |
768 // In case of exceptions, the expression stack is invalid and the esp will be reset to express | |
769 // this condition. Therefore, we call f only if addr is 'inside' the stack (i.e., addr >= esp for Intel). | |
770 bool in_stack; | |
771 if (frame::interpreter_frame_expression_stack_direction() > 0) { | |
772 in_stack = (intptr_t*)addr <= _fr->interpreter_frame_tos_address(); | |
773 } else { | |
774 in_stack = (intptr_t*)addr >= _fr->interpreter_frame_tos_address(); | |
775 } | |
776 if (in_stack) { | |
777 _f->do_oop(addr); | |
778 } | |
779 } | |
780 } | |
781 | |
782 int max_locals() { return _max_locals; } | |
783 frame* fr() { return _fr; } | |
784 }; | |
785 | |
786 | |
787 class InterpretedArgumentOopFinder: public SignatureInfo { | |
788 private: | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
789 OopClosure* _f; // Closure to invoke |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
790 int _offset; // TOS-relative offset, decremented with each argument |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
791 bool _has_receiver; // true if the callee has a receiver |
0 | 792 frame* _fr; |
793 | |
794 void set(int size, BasicType type) { | |
795 _offset -= size; | |
796 if (type == T_OBJECT || type == T_ARRAY) oop_offset_do(); | |
797 } | |
798 | |
799 void oop_offset_do() { | |
800 oop* addr; | |
801 addr = (oop*)_fr->interpreter_frame_tos_at(_offset); | |
802 _f->do_oop(addr); | |
803 } | |
804 | |
805 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
806 InterpretedArgumentOopFinder(Symbol* signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureInfo(signature), _has_receiver(has_receiver) { |
0 | 807 // compute size of arguments |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
808 int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
0 | 809 assert(!fr->is_interpreted_frame() || |
810 args_size <= fr->interpreter_frame_expression_stack_size(), | |
811 "args cannot be on stack anymore"); | |
812 // initialize InterpretedArgumentOopFinder | |
813 _f = f; | |
814 _fr = fr; | |
815 _offset = args_size; | |
816 } | |
817 | |
818 void oops_do() { | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
819 if (_has_receiver) { |
0 | 820 --_offset; |
821 oop_offset_do(); | |
822 } | |
823 iterate_parameters(); | |
824 } | |
825 }; | |
826 | |
827 | |
828 // Entry frame has following form (n arguments) | |
829 // +-----------+ | |
830 // sp -> | last arg | | |
831 // +-----------+ | |
832 // : ::: : | |
833 // +-----------+ | |
834 // (sp+n)->| first arg| | |
835 // +-----------+ | |
836 | |
837 | |
838 | |
839 // visits and GC's all the arguments in entry frame | |
840 class EntryFrameOopFinder: public SignatureInfo { | |
841 private: | |
842 bool _is_static; | |
843 int _offset; | |
844 frame* _fr; | |
845 OopClosure* _f; | |
846 | |
847 void set(int size, BasicType type) { | |
848 assert (_offset >= 0, "illegal offset"); | |
849 if (type == T_OBJECT || type == T_ARRAY) oop_at_offset_do(_offset); | |
850 _offset -= size; | |
851 } | |
852 | |
853 void oop_at_offset_do(int offset) { | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
1255
diff
changeset
|
854 assert (offset >= 0, "illegal offset"); |
0 | 855 oop* addr = (oop*) _fr->entry_frame_argument_at(offset); |
856 _f->do_oop(addr); | |
857 } | |
858 | |
859 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
860 EntryFrameOopFinder(frame* frame, Symbol* signature, bool is_static) : SignatureInfo(signature) { |
0 | 861 _f = NULL; // will be set later |
862 _fr = frame; | |
863 _is_static = is_static; | |
864 _offset = ArgumentSizeComputer(signature).size() - 1; // last parameter is at index 0 | |
865 } | |
866 | |
867 void arguments_do(OopClosure* f) { | |
868 _f = f; | |
869 if (!_is_static) oop_at_offset_do(_offset+1); // do the receiver | |
870 iterate_parameters(); | |
871 } | |
872 | |
873 }; | |
874 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
875 oop* frame::interpreter_callee_receiver_addr(Symbol* signature) { |
0 | 876 ArgumentSizeComputer asc(signature); |
877 int size = asc.size(); | |
878 return (oop *)interpreter_frame_tos_at(size); | |
879 } | |
880 | |
881 | |
882 void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) { | |
883 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
884 assert(map != NULL, "map must be set"); | |
885 Thread *thread = Thread::current(); | |
886 methodHandle m (thread, interpreter_frame_method()); | |
887 jint bci = interpreter_frame_bci(); | |
888 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
889 assert(!Universe::heap()->is_in(m()), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
890 "must be valid oop"); |
0 | 891 assert(m->is_method(), "checking frame value"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
892 assert((m->is_native() && bci == 0) || |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
893 (!m->is_native() && bci >= 0 && bci < m->code_size()), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
894 "invalid bci value"); |
0 | 895 |
896 // Handle the monitor elements in the activation | |
897 for ( | |
898 BasicObjectLock* current = interpreter_frame_monitor_end(); | |
899 current < interpreter_frame_monitor_begin(); | |
900 current = next_monitor_in_interpreter_frame(current) | |
901 ) { | |
902 #ifdef ASSERT | |
903 interpreter_frame_verify_monitor(current); | |
904 #endif | |
905 current->oops_do(f); | |
906 } | |
907 | |
908 // process fixed part | |
1908 | 909 #if !defined(PPC) || defined(ZERO) |
0 | 910 if (m->is_native()) { |
911 #ifdef CC_INTERP | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
912 interpreterState istate = get_interpreterState(); |
0 | 913 f->do_oop((oop*)&istate->_oop_temp); |
914 #else | |
915 f->do_oop((oop*)( fp() + interpreter_frame_oop_temp_offset )); | |
916 #endif /* CC_INTERP */ | |
917 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
918 #else // PPC |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
919 if (m->is_native() && m->is_static()) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
920 f->do_oop(interpreter_frame_mirror_addr()); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
921 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
922 #endif // PPC |
0 | 923 |
924 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); | |
925 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
926 Symbol* signature = NULL; |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
927 bool has_receiver = false; |
0 | 928 |
929 // Process a callee's arguments if we are at a call site | |
930 // (i.e., if we are at an invoke bytecode) | |
931 // This is used sometimes for calling into the VM, not for another | |
932 // interpreted or compiled frame. | |
933 if (!m->is_native()) { | |
2142 | 934 Bytecode_invoke call = Bytecode_invoke_check(m, bci); |
935 if (call.is_valid()) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
936 signature = call.signature(); |
2142 | 937 has_receiver = call.has_receiver(); |
0 | 938 if (map->include_argument_oops() && |
939 interpreter_frame_expression_stack_size() > 0) { | |
940 ResourceMark rm(thread); // is this right ??? | |
941 // we are at a call site & the expression stack is not empty | |
942 // => process callee's arguments | |
943 // | |
944 // Note: The expression stack can be empty if an exception | |
605 | 945 // occurred during method resolution/execution. In all |
0 | 946 // cases we empty the expression stack completely be- |
947 // fore handling the exception (the exception handling | |
948 // code in the interpreter calls a blocking runtime | |
949 // routine which can cause this code to be executed). | |
950 // (was bug gri 7/27/98) | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
951 oops_interpreted_arguments_do(signature, has_receiver, f); |
0 | 952 } |
953 } | |
954 } | |
955 | |
1506 | 956 InterpreterFrameClosure blk(this, max_locals, m->max_stack(), f); |
957 | |
958 // process locals & expression stack | |
959 InterpreterOopMap mask; | |
960 if (query_oop_map_cache) { | |
961 m->mask_for(bci, &mask); | |
0 | 962 } else { |
1506 | 963 OopMapCache::compute_one_oop_map(m, bci, &mask); |
0 | 964 } |
1506 | 965 mask.iterate_oop(&blk); |
0 | 966 } |
967 | |
968 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
969 void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) { |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
970 InterpretedArgumentOopFinder finder(signature, has_receiver, this, f); |
0 | 971 finder.oops_do(); |
972 } | |
973 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
974 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) { |
0 | 975 assert(_cb != NULL, "sanity check"); |
976 if (_cb->oop_maps() != NULL) { | |
977 OopMapSet::oops_do(this, reg_map, f); | |
978 | |
979 // Preserve potential arguments for a callee. We handle this by dispatching | |
980 // on the codeblob. For c2i, we do | |
981 if (reg_map->include_argument_oops()) { | |
982 _cb->preserve_callee_argument_oops(*this, reg_map, f); | |
983 } | |
984 } | |
985 // In cases where perm gen is collected, GC will want to mark | |
986 // oops referenced from nmethods active on thread stacks so as to | |
987 // prevent them from being collected. However, this visit should be | |
988 // restricted to certain phases of the collection only. The | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
989 // closure decides how it wants nmethods to be traced. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
990 if (cf != NULL) |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
991 cf->do_code_blob(_cb); |
0 | 992 } |
993 | |
994 class CompiledArgumentOopFinder: public SignatureInfo { | |
995 protected: | |
996 OopClosure* _f; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
997 int _offset; // the current offset, incremented with each argument |
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
998 bool _has_receiver; // true if the callee has a receiver |
0 | 999 frame _fr; |
1000 RegisterMap* _reg_map; | |
1001 int _arg_size; | |
1002 VMRegPair* _regs; // VMReg list of arguments | |
1003 | |
1004 void set(int size, BasicType type) { | |
1005 if (type == T_OBJECT || type == T_ARRAY) handle_oop_offset(); | |
1006 _offset += size; | |
1007 } | |
1008 | |
1009 virtual void handle_oop_offset() { | |
1010 // Extract low order register number from register array. | |
1011 // In LP64-land, the high-order bits are valid but unhelpful. | |
1012 VMReg reg = _regs[_offset].first(); | |
1013 oop *loc = _fr.oopmapreg_to_location(reg, _reg_map); | |
1014 _f->do_oop(loc); | |
1015 } | |
1016 | |
1017 public: | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1018 CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map) |
0 | 1019 : SignatureInfo(signature) { |
1020 | |
1021 // initialize CompiledArgumentOopFinder | |
1022 _f = f; | |
1023 _offset = 0; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
1024 _has_receiver = has_receiver; |
0 | 1025 _fr = fr; |
1026 _reg_map = (RegisterMap*)reg_map; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
1027 _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0); |
0 | 1028 |
1029 int arg_size; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1030 _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size); |
0 | 1031 assert(arg_size == _arg_size, "wrong arg size"); |
1032 } | |
1033 | |
1034 void oops_do() { | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
1035 if (_has_receiver) { |
0 | 1036 handle_oop_offset(); |
1037 _offset++; | |
1038 } | |
1039 iterate_parameters(); | |
1040 } | |
1041 }; | |
1042 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1043 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) { |
0 | 1044 ResourceMark rm; |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
989
diff
changeset
|
1045 CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map); |
0 | 1046 finder.oops_do(); |
1047 } | |
1048 | |
1049 | |
1050 // Get receiver out of callers frame, i.e. find parameter 0 in callers | |
1051 // frame. Consult ADLC for where parameter 0 is to be found. Then | |
1052 // check local reg_map for it being a callee-save register or argument | |
1053 // register, both of which are saved in the local frame. If not found | |
1054 // there, it must be an in-stack argument of the caller. | |
1055 // Note: caller.sp() points to callee-arguments | |
1056 oop frame::retrieve_receiver(RegisterMap* reg_map) { | |
1057 frame caller = *this; | |
1058 | |
1059 // First consult the ADLC on where it puts parameter 0 for this signature. | |
1060 VMReg reg = SharedRuntime::name_for_receiver(); | |
1061 oop r = *caller.oopmapreg_to_location(reg, reg_map); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
4872
diff
changeset
|
1062 assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (intptr_t) r, (intptr_t) r)); |
0 | 1063 return r; |
1064 } | |
1065 | |
1066 | |
1067 oop* frame::oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const { | |
1068 if(reg->is_reg()) { | |
1069 // If it is passed in a register, it got spilled in the stub frame. | |
1070 return (oop *)reg_map->location(reg); | |
1071 } else { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1072 int sp_offset_in_bytes = reg->reg2stack() * VMRegImpl::stack_slot_size; |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1073 return (oop*)(((address)unextended_sp()) + sp_offset_in_bytes); |
0 | 1074 } |
1075 } | |
1076 | |
2019 | 1077 BasicLock* frame::get_native_monitor() { |
1078 nmethod* nm = (nmethod*)_cb; | |
1079 assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(), | |
1080 "Should not call this unless it's a native nmethod"); | |
1081 int byte_offset = in_bytes(nm->native_basic_lock_sp_offset()); | |
0 | 1082 assert(byte_offset >= 0, "should not see invalid offset"); |
1083 return (BasicLock*) &sp()[byte_offset / wordSize]; | |
1084 } | |
1085 | |
2019 | 1086 oop frame::get_native_receiver() { |
1087 nmethod* nm = (nmethod*)_cb; | |
1088 assert(_cb != NULL && _cb->is_nmethod() && nm->method()->is_native(), | |
1089 "Should not call this unless it's a native nmethod"); | |
1090 int byte_offset = in_bytes(nm->native_receiver_sp_offset()); | |
0 | 1091 assert(byte_offset >= 0, "should not see invalid offset"); |
1092 oop owner = ((oop*) sp())[byte_offset / wordSize]; | |
1093 assert( Universe::heap()->is_in(owner), "bad receiver" ); | |
1094 return owner; | |
1095 } | |
1096 | |
1097 void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) { | |
1098 assert(map != NULL, "map must be set"); | |
1099 if (map->include_argument_oops()) { | |
1100 // must collect argument oops, as nobody else is doing it | |
1101 Thread *thread = Thread::current(); | |
1102 methodHandle m (thread, entry_frame_call_wrapper()->callee_method()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
1103 EntryFrameOopFinder finder(this, m->signature(), m->is_static()); |
0 | 1104 finder.arguments_do(f); |
1105 } | |
1106 // Traverse the Handle Block saved in the entry frame | |
1107 entry_frame_call_wrapper()->oops_do(f); | |
1108 } | |
1109 | |
1110 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
1111 void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) { |
1119
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1112 #ifndef PRODUCT |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1113 // simulate GC crash here to dump java thread in error report |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1114 if (CrashGCForDumpingJavaThread) { |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1115 char *t = NULL; |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1116 *t = 'c'; |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1117 } |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1118 #endif |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1119 if (is_interpreted_frame()) { |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1120 oops_interpreted_do(f, map, use_interpreter_oop_map_cache); |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1121 } else if (is_entry_frame()) { |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1122 oops_entry_do(f, map); |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1123 } else if (CodeCache::contains(pc())) { |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
989
diff
changeset
|
1124 oops_code_blob_do(f, cf, map); |
1692 | 1125 #ifdef SHARK |
1126 } else if (is_fake_stub_frame()) { | |
1127 // nothing to do | |
1128 #endif // SHARK | |
0 | 1129 } else { |
1130 ShouldNotReachHere(); | |
1131 } | |
1132 } | |
1133 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
1134 void frame::nmethods_do(CodeBlobClosure* cf) { |
0 | 1135 if (_cb != NULL && _cb->is_nmethod()) { |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
1136 cf->do_code_blob(_cb); |
0 | 1137 } |
1138 } | |
1139 | |
1140 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1141 // call f() on the interpreted Method*s in the stack. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1142 // Have to walk the entire code cache for the compiled frames Yuck. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1143 void frame::metadata_do(void f(Metadata*)) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1144 if (_cb != NULL && Interpreter::contains(pc())) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1145 Method* m = this->interpreter_frame_method(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1146 assert(m != NULL, "huh?"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1147 f(m); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1148 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1149 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1150 |
0 | 1151 void frame::gc_prologue() { |
1152 if (is_interpreted_frame()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1153 // set bcx to bci to become Method* position independent during GC |
0 | 1154 interpreter_frame_set_bcx(interpreter_frame_bci()); |
1155 } | |
1156 } | |
1157 | |
1158 | |
1159 void frame::gc_epilogue() { | |
1160 if (is_interpreted_frame()) { | |
1161 // set bcx back to bcp for interpreter | |
1162 interpreter_frame_set_bcx((intptr_t)interpreter_frame_bcp()); | |
1163 } | |
1164 // call processor specific epilog function | |
1165 pd_gc_epilog(); | |
1166 } | |
1167 | |
1168 | |
1169 # ifdef ENABLE_ZAP_DEAD_LOCALS | |
1170 | |
1171 void frame::CheckValueClosure::do_oop(oop* p) { | |
1172 if (CheckOopishValues && Universe::heap()->is_in_reserved(*p)) { | |
1173 warning("value @ " INTPTR_FORMAT " looks oopish (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current()); | |
1174 } | |
1175 } | |
1176 frame::CheckValueClosure frame::_check_value; | |
1177 | |
1178 | |
1179 void frame::CheckOopClosure::do_oop(oop* p) { | |
1180 if (*p != NULL && !(*p)->is_oop()) { | |
1181 warning("value @ " INTPTR_FORMAT " should be an oop (" INTPTR_FORMAT ") (thread = " INTPTR_FORMAT ")", p, (address)*p, Thread::current()); | |
1182 } | |
1183 } | |
1184 frame::CheckOopClosure frame::_check_oop; | |
1185 | |
1186 void frame::check_derived_oop(oop* base, oop* derived) { | |
1187 _check_oop.do_oop(base); | |
1188 } | |
1189 | |
1190 | |
1191 void frame::ZapDeadClosure::do_oop(oop* p) { | |
1192 if (TraceZapDeadLocals) tty->print_cr("zapping @ " INTPTR_FORMAT " containing " INTPTR_FORMAT, p, (address)*p); | |
1193 // Need cast because on _LP64 the conversion to oop is ambiguous. Constant | |
1194 // can be either long or int. | |
1195 *p = (oop)(int)0xbabebabe; | |
1196 } | |
1197 frame::ZapDeadClosure frame::_zap_dead; | |
1198 | |
1199 void frame::zap_dead_locals(JavaThread* thread, const RegisterMap* map) { | |
1200 assert(thread == Thread::current(), "need to synchronize to do this to another thread"); | |
1201 // Tracing - part 1 | |
1202 if (TraceZapDeadLocals) { | |
1203 ResourceMark rm(thread); | |
1204 tty->print_cr("--------------------------------------------------------------------------------"); | |
1205 tty->print("Zapping dead locals in "); | |
1206 print_on(tty); | |
1207 tty->cr(); | |
1208 } | |
1209 // Zapping | |
1210 if (is_entry_frame ()) zap_dead_entry_locals (thread, map); | |
1211 else if (is_interpreted_frame()) zap_dead_interpreted_locals(thread, map); | |
1212 else if (is_compiled_frame()) zap_dead_compiled_locals (thread, map); | |
1213 | |
1214 else | |
1215 // could be is_runtime_frame | |
1216 // so remove error: ShouldNotReachHere(); | |
1217 ; | |
1218 // Tracing - part 2 | |
1219 if (TraceZapDeadLocals) { | |
1220 tty->cr(); | |
1221 } | |
1222 } | |
1223 | |
1224 | |
1225 void frame::zap_dead_interpreted_locals(JavaThread *thread, const RegisterMap* map) { | |
1226 // get current interpreter 'pc' | |
1227 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1228 Method* m = interpreter_frame_method(); |
0 | 1229 int bci = interpreter_frame_bci(); |
1230 | |
1231 int max_locals = m->is_native() ? m->size_of_parameters() : m->max_locals(); | |
1232 | |
1506 | 1233 // process dynamic part |
1234 InterpreterFrameClosure value_blk(this, max_locals, m->max_stack(), | |
1235 &_check_value); | |
1236 InterpreterFrameClosure oop_blk(this, max_locals, m->max_stack(), | |
1237 &_check_oop ); | |
1238 InterpreterFrameClosure dead_blk(this, max_locals, m->max_stack(), | |
1239 &_zap_dead ); | |
0 | 1240 |
1506 | 1241 // get frame map |
1242 InterpreterOopMap mask; | |
1243 m->mask_for(bci, &mask); | |
1244 mask.iterate_all( &oop_blk, &value_blk, &dead_blk); | |
0 | 1245 } |
1246 | |
1247 | |
1248 void frame::zap_dead_compiled_locals(JavaThread* thread, const RegisterMap* reg_map) { | |
1249 | |
1250 ResourceMark rm(thread); | |
1251 assert(_cb != NULL, "sanity check"); | |
1252 if (_cb->oop_maps() != NULL) { | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1253 OopMapSet::all_do(this, reg_map, &_check_oop, check_derived_oop, &_check_value); |
0 | 1254 } |
1255 } | |
1256 | |
1257 | |
1258 void frame::zap_dead_entry_locals(JavaThread*, const RegisterMap*) { | |
1259 if (TraceZapDeadLocals) warning("frame::zap_dead_entry_locals unimplemented"); | |
1260 } | |
1261 | |
1262 | |
1263 void frame::zap_dead_deoptimized_locals(JavaThread*, const RegisterMap*) { | |
1264 if (TraceZapDeadLocals) warning("frame::zap_dead_deoptimized_locals unimplemented"); | |
1265 } | |
1266 | |
1267 # endif // ENABLE_ZAP_DEAD_LOCALS | |
1268 | |
1269 void frame::verify(const RegisterMap* map) { | |
1270 // for now make sure receiver type is correct | |
1271 if (is_interpreted_frame()) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1272 Method* method = interpreter_frame_method(); |
0 | 1273 guarantee(method->is_method(), "method is wrong in frame::verify"); |
1274 if (!method->is_static()) { | |
1275 // fetch the receiver | |
1276 oop* p = (oop*) interpreter_frame_local_at(0); | |
1277 // make sure we have the right receiver type | |
1278 } | |
1279 } | |
1280 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), "must be empty before verify");) | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
605
diff
changeset
|
1281 oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false); |
0 | 1282 } |
1283 | |
1284 | |
1285 #ifdef ASSERT | |
1286 bool frame::verify_return_pc(address x) { | |
1287 if (StubRoutines::returns_to_call_stub(x)) { | |
1288 return true; | |
1289 } | |
1290 if (CodeCache::contains(x)) { | |
1291 return true; | |
1292 } | |
1293 if (Interpreter::contains(x)) { | |
1294 return true; | |
1295 } | |
1296 return false; | |
1297 } | |
1298 #endif | |
1299 | |
1300 #ifdef ASSERT | |
1301 void frame::interpreter_frame_verify_monitor(BasicObjectLock* value) const { | |
1302 assert(is_interpreted_frame(), "Not an interpreted frame"); | |
1303 // verify that the value is in the right part of the frame | |
1304 address low_mark = (address) interpreter_frame_monitor_end(); | |
1305 address high_mark = (address) interpreter_frame_monitor_begin(); | |
1306 address current = (address) value; | |
1307 | |
1308 const int monitor_size = frame::interpreter_frame_monitor_size(); | |
1309 guarantee((high_mark - current) % monitor_size == 0 , "Misaligned top of BasicObjectLock*"); | |
1310 guarantee( high_mark > current , "Current BasicObjectLock* higher than high_mark"); | |
1311 | |
1312 guarantee((current - low_mark) % monitor_size == 0 , "Misaligned bottom of BasicObjectLock*"); | |
1313 guarantee( current >= low_mark , "Current BasicObjectLock* below than low_mark"); | |
1314 } | |
4824
5dbed2f542ff
7120468: SPARC/x86: use frame::describe to enhance trace_method_handle
bdelsart
parents:
4818
diff
changeset
|
1315 #endif |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1316 |
4824
5dbed2f542ff
7120468: SPARC/x86: use frame::describe to enhance trace_method_handle
bdelsart
parents:
4818
diff
changeset
|
1317 #ifndef PRODUCT |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1318 void frame::describe(FrameValues& values, int frame_no) { |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1319 // boundaries: sp and the 'real' frame pointer |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1320 values.describe(-1, sp(), err_msg("sp for #%d", frame_no), 1); |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1321 intptr_t* frame_pointer = real_fp(); // Note: may differ from fp() |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1322 |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1323 // print frame info at the highest boundary |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1324 intptr_t* info_address = MAX2(sp(), frame_pointer); |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1325 |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1326 if (info_address != frame_pointer) { |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1327 // print frame_pointer explicitly if not marked by the frame info |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1328 values.describe(-1, frame_pointer, err_msg("frame pointer for #%d", frame_no), 1); |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1329 } |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1330 |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1331 if (is_entry_frame() || is_compiled_frame() || is_interpreted_frame() || is_native_frame()) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1332 // Label values common to most frames |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1333 values.describe(-1, unextended_sp(), err_msg("unextended_sp for #%d", frame_no)); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1334 } |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1335 |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1336 if (is_interpreted_frame()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1337 Method* m = interpreter_frame_method(); |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1338 int bci = interpreter_frame_bci(); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1339 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1340 // Label the method and current bci |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1341 values.describe(-1, info_address, |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1342 FormatBuffer<1024>("#%d method %s @ %d", frame_no, m->name_and_sig_as_C_string(), bci), 2); |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1343 values.describe(-1, info_address, |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1344 err_msg("- %d locals %d max stack", m->max_locals(), m->max_stack()), 1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1345 if (m->max_locals() > 0) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1346 intptr_t* l0 = interpreter_frame_local_at(0); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1347 intptr_t* ln = interpreter_frame_local_at(m->max_locals() - 1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1348 values.describe(-1, MAX2(l0, ln), err_msg("locals for #%d", frame_no), 1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1349 // Report each local and mark as owned by this frame |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1350 for (int l = 0; l < m->max_locals(); l++) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1351 intptr_t* l0 = interpreter_frame_local_at(l); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1352 values.describe(frame_no, l0, err_msg("local %d", l)); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1353 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1354 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1355 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1356 // Compute the actual expression stack size |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1357 InterpreterOopMap mask; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1358 OopMapCache::compute_one_oop_map(m, bci, &mask); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1359 intptr_t* tos = NULL; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1360 // Report each stack element and mark as owned by this frame |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1361 for (int e = 0; e < mask.expression_stack_size(); e++) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1362 tos = MAX2(tos, interpreter_frame_expression_stack_at(e)); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1363 values.describe(frame_no, interpreter_frame_expression_stack_at(e), |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1364 err_msg("stack %d", e)); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1365 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1366 if (tos != NULL) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1367 values.describe(-1, tos, err_msg("expression stack for #%d", frame_no), 1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1368 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1369 if (interpreter_frame_monitor_begin() != interpreter_frame_monitor_end()) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1370 values.describe(frame_no, (intptr_t*)interpreter_frame_monitor_begin(), "monitors begin"); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1371 values.describe(frame_no, (intptr_t*)interpreter_frame_monitor_end(), "monitors end"); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1372 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1373 } else if (is_entry_frame()) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1374 // For now just label the frame |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1375 values.describe(-1, info_address, err_msg("#%d entry frame", frame_no), 2); |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1376 } else if (is_compiled_frame()) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1377 // For now just label the frame |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1378 nmethod* nm = cb()->as_nmethod_or_null(); |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1379 values.describe(-1, info_address, |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1380 FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for method %s%s", frame_no, |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1381 nm, nm->method()->name_and_sig_as_C_string(), |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1382 (_deopt_state == is_deoptimized) ? |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1383 " (deoptimized)" : |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1384 ((_deopt_state == unknown) ? " (state unknown)" : "")), |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1385 2); |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1386 } else if (is_native_frame()) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1387 // For now just label the frame |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1388 nmethod* nm = cb()->as_nmethod_or_null(); |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1389 values.describe(-1, info_address, |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1390 FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for native method %s", frame_no, |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1391 nm, nm->method()->name_and_sig_as_C_string()), 2); |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1392 } else { |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1393 // provide default info if not handled before |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1394 char *info = (char *) "special frame"; |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1395 if ((_cb != NULL) && |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1396 (_cb->name() != NULL)) { |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1397 info = (char *)_cb->name(); |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1398 } |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1399 values.describe(-1, info_address, err_msg("#%d <%s>", frame_no, info), 2); |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1400 } |
4818
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1401 |
82e5a84b7436
7120450: complete information dumped by frame_describe
bdelsart
parents:
4806
diff
changeset
|
1402 // platform dependent additional data |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1403 describe_pd(values, frame_no); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1404 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1405 |
0 | 1406 #endif |
1407 | |
1408 | |
1409 //----------------------------------------------------------------------------------- | |
1410 // StackFrameStream implementation | |
1411 | |
1412 StackFrameStream::StackFrameStream(JavaThread *thread, bool update) : _reg_map(thread, update) { | |
1413 assert(thread->has_last_Java_frame(), "sanity check"); | |
1414 _fr = thread->last_frame(); | |
1415 _is_done = false; | |
1416 } | |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1417 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1418 |
4824
5dbed2f542ff
7120468: SPARC/x86: use frame::describe to enhance trace_method_handle
bdelsart
parents:
4818
diff
changeset
|
1419 #ifndef PRODUCT |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1420 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1421 void FrameValues::describe(int owner, intptr_t* location, const char* description, int priority) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1422 FrameValue fv; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1423 fv.location = location; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1424 fv.owner = owner; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1425 fv.priority = priority; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1426 fv.description = NEW_RESOURCE_ARRAY(char, strlen(description) + 1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1427 strcpy(fv.description, description); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1428 _values.append(fv); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1429 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1430 |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1431 |
4824
5dbed2f542ff
7120468: SPARC/x86: use frame::describe to enhance trace_method_handle
bdelsart
parents:
4818
diff
changeset
|
1432 #ifdef ASSERT |
3365
3cfb240033d1
7043301: assert(locals < caller->fp() || locals > (caller->fp() + 16)) failed: locals in save area
never
parents:
3363
diff
changeset
|
1433 void FrameValues::validate() { |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1434 _values.sort(compare); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1435 bool error = false; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1436 FrameValue prev; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1437 prev.owner = -1; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1438 for (int i = _values.length() - 1; i >= 0; i--) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1439 FrameValue fv = _values.at(i); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1440 if (fv.owner == -1) continue; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1441 if (prev.owner == -1) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1442 prev = fv; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1443 continue; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1444 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1445 if (prev.location == fv.location) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1446 if (fv.owner != prev.owner) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1447 tty->print_cr("overlapping storage"); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1448 tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", prev.location, *prev.location, prev.description); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1449 tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", fv.location, *fv.location, fv.description); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1450 error = true; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1451 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1452 } else { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1453 prev = fv; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1454 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1455 } |
3365
3cfb240033d1
7043301: assert(locals < caller->fp() || locals > (caller->fp() + 16)) failed: locals in save area
never
parents:
3363
diff
changeset
|
1456 assert(!error, "invalid layout"); |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1457 } |
4824
5dbed2f542ff
7120468: SPARC/x86: use frame::describe to enhance trace_method_handle
bdelsart
parents:
4818
diff
changeset
|
1458 #endif // ASSERT |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1459 |
4042
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1460 void FrameValues::print(JavaThread* thread) { |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1461 _values.sort(compare); |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1462 |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1463 // Sometimes values like the fp can be invalid values if the |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1464 // register map wasn't updated during the walk. Trim out values |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1465 // that aren't actually in the stack of the thread. |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1466 int min_index = 0; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1467 int max_index = _values.length() - 1; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1468 intptr_t* v0 = _values.at(min_index).location; |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1469 intptr_t* v1 = _values.at(max_index).location; |
4042
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1470 |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1471 if (thread == Thread::current()) { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1472 while (!thread->is_in_stack((address)v0)) { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1473 v0 = _values.at(++min_index).location; |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1474 } |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1475 while (!thread->is_in_stack((address)v1)) { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1476 v1 = _values.at(--max_index).location; |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1477 } |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1478 } else { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1479 while (!thread->on_local_stack((address)v0)) { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1480 v0 = _values.at(++min_index).location; |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1481 } |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1482 while (!thread->on_local_stack((address)v1)) { |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1483 v1 = _values.at(--max_index).location; |
b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
twisti
parents:
3369
diff
changeset
|
1484 } |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1485 } |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1486 intptr_t* min = MIN2(v0, v1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1487 intptr_t* max = MAX2(v0, v1); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1488 intptr_t* cur = max; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1489 intptr_t* last = NULL; |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
3365
diff
changeset
|
1490 for (int i = max_index; i >= min_index; i--) { |
3336
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1491 FrameValue fv = _values.at(i); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1492 while (cur > fv.location) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1493 tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT, cur, *cur); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1494 cur--; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1495 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1496 if (last == fv.location) { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1497 const char* spacer = " " LP64_ONLY(" "); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1498 tty->print_cr(" %s %s %s", spacer, spacer, fv.description); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1499 } else { |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1500 tty->print_cr(" " INTPTR_FORMAT ": " INTPTR_FORMAT " %s", fv.location, *fv.location, fv.description); |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1501 last = fv.location; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1502 cur--; |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1503 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1504 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1505 } |
2e038ad0c1d0
7009361: JSR 292 Invalid value on stack on solaris-sparc with -Xcomp
never
parents:
2192
diff
changeset
|
1506 |
4824
5dbed2f542ff
7120468: SPARC/x86: use frame::describe to enhance trace_method_handle
bdelsart
parents:
4818
diff
changeset
|
1507 #endif // ndef PRODUCT |