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