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