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