Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/vframeArray.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | 3d2ab563047a |
children | be4ca325525a d2a62e0f25eb |
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:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
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:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/vmSymbols.hpp" | |
27 #include "interpreter/interpreter.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
29 #include "memory/resourceArea.hpp" | |
30 #include "memory/universe.inline.hpp" | |
31 #include "oops/methodDataOop.hpp" | |
32 #include "oops/oop.inline.hpp" | |
33 #include "prims/jvmtiThreadState.hpp" | |
34 #include "runtime/handles.inline.hpp" | |
35 #include "runtime/monitorChunk.hpp" | |
36 #include "runtime/sharedRuntime.hpp" | |
37 #include "runtime/vframe.hpp" | |
38 #include "runtime/vframeArray.hpp" | |
39 #include "runtime/vframe_hp.hpp" | |
40 #include "utilities/events.hpp" | |
41 #ifdef COMPILER2 | |
42 #include "opto/runtime.hpp" | |
43 #endif | |
0 | 44 |
45 | |
46 int vframeArrayElement:: bci(void) const { return (_bci == SynchronizationEntryBCI ? 0 : _bci); } | |
47 | |
48 void vframeArrayElement::free_monitors(JavaThread* jt) { | |
49 if (_monitors != NULL) { | |
50 MonitorChunk* chunk = _monitors; | |
51 _monitors = NULL; | |
52 jt->remove_monitor_chunk(chunk); | |
53 delete chunk; | |
54 } | |
55 } | |
56 | |
57 void vframeArrayElement::fill_in(compiledVFrame* vf) { | |
58 | |
59 // Copy the information from the compiled vframe to the | |
60 // interpreter frame we will be creating to replace vf | |
61 | |
62 _method = vf->method(); | |
63 _bci = vf->raw_bci(); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
64 _reexecute = vf->should_reexecute(); |
0 | 65 |
66 int index; | |
67 | |
68 // Get the monitors off-stack | |
69 | |
70 GrowableArray<MonitorInfo*>* list = vf->monitors(); | |
71 if (list->is_empty()) { | |
72 _monitors = NULL; | |
73 } else { | |
74 | |
75 // Allocate monitor chunk | |
76 _monitors = new MonitorChunk(list->length()); | |
77 vf->thread()->add_monitor_chunk(_monitors); | |
78 | |
79 // Migrate the BasicLocks from the stack to the monitor chunk | |
80 for (index = 0; index < list->length(); index++) { | |
81 MonitorInfo* monitor = list->at(index); | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
0
diff
changeset
|
82 assert(!monitor->owner_is_scalar_replaced(), "object should be reallocated already"); |
0 | 83 assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased"); |
84 BasicObjectLock* dest = _monitors->at(index); | |
85 dest->set_obj(monitor->owner()); | |
86 monitor->lock()->move_to(monitor->owner(), dest->lock()); | |
87 } | |
88 } | |
89 | |
90 // Convert the vframe locals and expressions to off stack | |
91 // values. Because we will not gc all oops can be converted to | |
92 // intptr_t (i.e. a stack slot) and we are fine. This is | |
93 // good since we are inside a HandleMark and the oops in our | |
94 // collection would go away between packing them here and | |
95 // unpacking them in unpack_on_stack. | |
96 | |
97 // First the locals go off-stack | |
98 | |
99 // FIXME this seems silly it creates a StackValueCollection | |
100 // in order to get the size to then copy them and | |
101 // convert the types to intptr_t size slots. Seems like it | |
102 // could do it in place... Still uses less memory than the | |
103 // old way though | |
104 | |
105 StackValueCollection *locs = vf->locals(); | |
106 _locals = new StackValueCollection(locs->size()); | |
107 for(index = 0; index < locs->size(); index++) { | |
108 StackValue* value = locs->at(index); | |
109 switch(value->type()) { | |
110 case T_OBJECT: | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
0
diff
changeset
|
111 assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); |
0 | 112 // preserve object type |
113 _locals->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); | |
114 break; | |
115 case T_CONFLICT: | |
116 // A dead local. Will be initialized to null/zero. | |
117 _locals->add( new StackValue()); | |
118 break; | |
119 case T_INT: | |
120 _locals->add( new StackValue(value->get_int())); | |
121 break; | |
122 default: | |
123 ShouldNotReachHere(); | |
124 } | |
125 } | |
126 | |
127 // Now the expressions off-stack | |
128 // Same silliness as above | |
129 | |
130 StackValueCollection *exprs = vf->expressions(); | |
131 _expressions = new StackValueCollection(exprs->size()); | |
132 for(index = 0; index < exprs->size(); index++) { | |
133 StackValue* value = exprs->at(index); | |
134 switch(value->type()) { | |
135 case T_OBJECT: | |
818
b109e761e927
6837472: com/sun/jdi/MonitorFrameInfo.java fails with AggressiveOpts in 6u14
kvn
parents:
0
diff
changeset
|
136 assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); |
0 | 137 // preserve object type |
138 _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); | |
139 break; | |
140 case T_CONFLICT: | |
141 // A dead stack element. Will be initialized to null/zero. | |
142 // This can occur when the compiler emits a state in which stack | |
143 // elements are known to be dead (because of an imminent exception). | |
144 _expressions->add( new StackValue()); | |
145 break; | |
146 case T_INT: | |
147 _expressions->add( new StackValue(value->get_int())); | |
148 break; | |
149 default: | |
150 ShouldNotReachHere(); | |
151 } | |
152 } | |
153 } | |
154 | |
155 int unpack_counter = 0; | |
156 | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
157 void vframeArrayElement::unpack_on_stack(int caller_actual_parameters, |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
158 int callee_parameters, |
0 | 159 int callee_locals, |
160 frame* caller, | |
161 bool is_top_frame, | |
162 int exec_mode) { | |
163 JavaThread* thread = (JavaThread*) Thread::current(); | |
164 | |
165 // Look at bci and decide on bcp and continuation pc | |
166 address bcp; | |
167 // C++ interpreter doesn't need a pc since it will figure out what to do when it | |
168 // begins execution | |
169 address pc; | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
170 bool use_next_mdp = false; // true if we should use the mdp associated with the next bci |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
171 // rather than the one associated with bcp |
0 | 172 if (raw_bci() == SynchronizationEntryBCI) { |
173 // We are deoptimizing while hanging in prologue code for synchronized method | |
174 bcp = method()->bcp_from(0); // first byte code | |
175 pc = Interpreter::deopt_entry(vtos, 0); // step = 0 since we don't skip current bytecode | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
176 } else if (should_reexecute()) { //reexecute this bytecode |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
177 assert(is_top_frame, "reexecute allowed only for the top frame"); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
178 bcp = method()->bcp_from(bci()); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
179 pc = Interpreter::deopt_reexecute_entry(method(), bcp); |
0 | 180 } else { |
181 bcp = method()->bcp_from(bci()); | |
900
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
182 pc = Interpreter::deopt_continue_after_entry(method(), bcp, callee_parameters, is_top_frame); |
9987d9d5eb0e
6833129: specjvm98 fails with NullPointerException in the compiler with -XX:DeoptimizeALot
cfang
parents:
818
diff
changeset
|
183 use_next_mdp = true; |
0 | 184 } |
185 assert(Bytecodes::is_defined(*bcp), "must be a valid bytecode"); | |
186 | |
187 // Monitorenter and pending exceptions: | |
188 // | |
189 // For Compiler2, there should be no pending exception when deoptimizing at monitorenter | |
190 // because there is no safepoint at the null pointer check (it is either handled explicitly | |
191 // or prior to the monitorenter) and asynchronous exceptions are not made "pending" by the | |
192 // runtime interface for the slow case (see JRT_ENTRY_FOR_MONITORENTER). If an asynchronous | |
193 // exception was processed, the bytecode pointer would have to be extended one bytecode beyond | |
194 // the monitorenter to place it in the proper exception range. | |
195 // | |
196 // For Compiler1, deoptimization can occur while throwing a NullPointerException at monitorenter, | |
197 // in which case bcp should point to the monitorenter since it is within the exception's range. | |
198 | |
199 assert(*bcp != Bytecodes::_monitorenter || is_top_frame, "a _monitorenter must be a top frame"); | |
1814
fd5d4527cdf5
6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents:
1603
diff
changeset
|
200 assert(thread->deopt_nmethod() != NULL, "nmethod should be known"); |
fd5d4527cdf5
6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents:
1603
diff
changeset
|
201 guarantee(!(thread->deopt_nmethod()->is_compiled_by_c2() && |
fd5d4527cdf5
6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents:
1603
diff
changeset
|
202 *bcp == Bytecodes::_monitorenter && |
fd5d4527cdf5
6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents:
1603
diff
changeset
|
203 exec_mode == Deoptimization::Unpack_exception), |
fd5d4527cdf5
6986270: guarantee(*bcp != Bytecodes::_monitorenter || exec_mode != Deoptimization::Unpack_exception) fails
iveresov
parents:
1603
diff
changeset
|
204 "shouldn't get exception during monitorenter"); |
0 | 205 |
206 int popframe_preserved_args_size_in_bytes = 0; | |
207 int popframe_preserved_args_size_in_words = 0; | |
208 if (is_top_frame) { | |
1255
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
903
diff
changeset
|
209 JvmtiThreadState *state = thread->jvmti_thread_state(); |
0 | 210 if (JvmtiExport::can_pop_frame() && |
211 (thread->has_pending_popframe() || thread->popframe_forcing_deopt_reexecution())) { | |
212 if (thread->has_pending_popframe()) { | |
213 // Pop top frame after deoptimization | |
214 #ifndef CC_INTERP | |
215 pc = Interpreter::remove_activation_preserving_args_entry(); | |
216 #else | |
217 // Do an uncommon trap type entry. c++ interpreter will know | |
218 // to pop frame and preserve the args | |
219 pc = Interpreter::deopt_entry(vtos, 0); | |
220 use_next_mdp = false; | |
221 #endif | |
222 } else { | |
223 // Reexecute invoke in top frame | |
224 pc = Interpreter::deopt_entry(vtos, 0); | |
225 use_next_mdp = false; | |
226 popframe_preserved_args_size_in_bytes = in_bytes(thread->popframe_preserved_args_size()); | |
227 // Note: the PopFrame-related extension of the expression stack size is done in | |
228 // Deoptimization::fetch_unroll_info_helper | |
229 popframe_preserved_args_size_in_words = in_words(thread->popframe_preserved_args_size_in_words()); | |
230 } | |
231 } else if (JvmtiExport::can_force_early_return() && state != NULL && state->is_earlyret_pending()) { | |
232 // Force early return from top frame after deoptimization | |
233 #ifndef CC_INTERP | |
234 pc = Interpreter::remove_activation_early_entry(state->earlyret_tos()); | |
235 #else | |
236 // TBD: Need to implement ForceEarlyReturn for CC_INTERP (ia64) | |
237 #endif | |
238 } else { | |
239 // Possibly override the previous pc computation of the top (youngest) frame | |
240 switch (exec_mode) { | |
241 case Deoptimization::Unpack_deopt: | |
242 // use what we've got | |
243 break; | |
244 case Deoptimization::Unpack_exception: | |
245 // exception is pending | |
1295 | 246 pc = SharedRuntime::raw_exception_handler_for_return_address(thread, pc); |
0 | 247 // [phh] We're going to end up in some handler or other, so it doesn't |
248 // matter what mdp we point to. See exception_handler_for_exception() | |
249 // in interpreterRuntime.cpp. | |
250 break; | |
251 case Deoptimization::Unpack_uncommon_trap: | |
252 case Deoptimization::Unpack_reexecute: | |
253 // redo last byte code | |
254 pc = Interpreter::deopt_entry(vtos, 0); | |
255 use_next_mdp = false; | |
256 break; | |
257 default: | |
258 ShouldNotReachHere(); | |
259 } | |
260 } | |
261 } | |
262 | |
263 // Setup the interpreter frame | |
264 | |
265 assert(method() != NULL, "method must exist"); | |
266 int temps = expressions()->size(); | |
267 | |
268 int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors(); | |
269 | |
270 Interpreter::layout_activation(method(), | |
271 temps + callee_parameters, | |
272 popframe_preserved_args_size_in_words, | |
273 locks, | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
274 caller_actual_parameters, |
0 | 275 callee_parameters, |
276 callee_locals, | |
277 caller, | |
278 iframe(), | |
279 is_top_frame); | |
280 | |
281 // Update the pc in the frame object and overwrite the temporary pc | |
282 // we placed in the skeletal frame now that we finally know the | |
283 // exact interpreter address we should use. | |
284 | |
285 _frame.patch_pc(thread, pc); | |
286 | |
287 assert (!method()->is_synchronized() || locks > 0, "synchronized methods must have monitors"); | |
288 | |
289 BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin(); | |
290 for (int index = 0; index < locks; index++) { | |
291 top = iframe()->previous_monitor_in_interpreter_frame(top); | |
292 BasicObjectLock* src = _monitors->at(index); | |
293 top->set_obj(src->obj()); | |
294 src->lock()->move_to(src->obj(), top->lock()); | |
295 } | |
296 if (ProfileInterpreter) { | |
297 iframe()->interpreter_frame_set_mdx(0); // clear out the mdp. | |
298 } | |
299 iframe()->interpreter_frame_set_bcx((intptr_t)bcp); // cannot use bcp because frame is not initialized yet | |
300 if (ProfileInterpreter) { | |
301 methodDataOop mdo = method()->method_data(); | |
302 if (mdo != NULL) { | |
303 int bci = iframe()->interpreter_frame_bci(); | |
304 if (use_next_mdp) ++bci; | |
305 address mdp = mdo->bci_to_dp(bci); | |
306 iframe()->interpreter_frame_set_mdp(mdp); | |
307 } | |
308 } | |
309 | |
310 // Unpack expression stack | |
311 // If this is an intermediate frame (i.e. not top frame) then this | |
312 // only unpacks the part of the expression stack not used by callee | |
313 // as parameters. The callee parameters are unpacked as part of the | |
314 // callee locals. | |
315 int i; | |
316 for(i = 0; i < expressions()->size(); i++) { | |
317 StackValue *value = expressions()->at(i); | |
318 intptr_t* addr = iframe()->interpreter_frame_expression_stack_at(i); | |
319 switch(value->type()) { | |
320 case T_INT: | |
321 *addr = value->get_int(); | |
322 break; | |
323 case T_OBJECT: | |
324 *addr = value->get_int(T_OBJECT); | |
325 break; | |
326 case T_CONFLICT: | |
327 // A dead stack slot. Initialize to null in case it is an oop. | |
328 *addr = NULL_WORD; | |
329 break; | |
330 default: | |
331 ShouldNotReachHere(); | |
332 } | |
333 } | |
334 | |
335 | |
336 // Unpack the locals | |
337 for(i = 0; i < locals()->size(); i++) { | |
338 StackValue *value = locals()->at(i); | |
339 intptr_t* addr = iframe()->interpreter_frame_local_at(i); | |
340 switch(value->type()) { | |
341 case T_INT: | |
342 *addr = value->get_int(); | |
343 break; | |
344 case T_OBJECT: | |
345 *addr = value->get_int(T_OBJECT); | |
346 break; | |
347 case T_CONFLICT: | |
348 // A dead location. If it is an oop then we need a NULL to prevent GC from following it | |
349 *addr = NULL_WORD; | |
350 break; | |
351 default: | |
352 ShouldNotReachHere(); | |
353 } | |
354 } | |
355 | |
356 if (is_top_frame && JvmtiExport::can_pop_frame() && thread->popframe_forcing_deopt_reexecution()) { | |
357 // An interpreted frame was popped but it returns to a deoptimized | |
358 // frame. The incoming arguments to the interpreted activation | |
359 // were preserved in thread-local storage by the | |
360 // remove_activation_preserving_args_entry in the interpreter; now | |
361 // we put them back into the just-unpacked interpreter frame. | |
362 // Note that this assumes that the locals arena grows toward lower | |
363 // addresses. | |
364 if (popframe_preserved_args_size_in_words != 0) { | |
365 void* saved_args = thread->popframe_preserved_args(); | |
366 assert(saved_args != NULL, "must have been saved by interpreter"); | |
367 #ifdef ASSERT | |
368 assert(popframe_preserved_args_size_in_words <= | |
1506 | 369 iframe()->interpreter_frame_expression_stack_size()*Interpreter::stackElementWords, |
0 | 370 "expression stack size should have been extended"); |
371 #endif // ASSERT | |
372 int top_element = iframe()->interpreter_frame_expression_stack_size()-1; | |
373 intptr_t* base; | |
374 if (frame::interpreter_frame_expression_stack_direction() < 0) { | |
375 base = iframe()->interpreter_frame_expression_stack_at(top_element); | |
376 } else { | |
377 base = iframe()->interpreter_frame_expression_stack(); | |
378 } | |
1603
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
379 Copy::conjoint_jbytes(saved_args, |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
380 base, |
d93949c5bdcc
6730276: JDI_REGRESSION tests fail with "Error: count must be non-zero" error on x86
kvn
parents:
1552
diff
changeset
|
381 popframe_preserved_args_size_in_bytes); |
0 | 382 thread->popframe_free_preserved_args(); |
383 } | |
384 } | |
385 | |
386 #ifndef PRODUCT | |
387 if (TraceDeoptimization && Verbose) { | |
388 ttyLocker ttyl; | |
389 tty->print_cr("[%d Interpreted Frame]", ++unpack_counter); | |
390 iframe()->print_on(tty); | |
391 RegisterMap map(thread); | |
392 vframe* f = vframe::new_vframe(iframe(), &map, thread); | |
393 f->print(); | |
394 | |
395 tty->print_cr("locals size %d", locals()->size()); | |
396 tty->print_cr("expression size %d", expressions()->size()); | |
397 | |
398 method()->print_value(); | |
399 tty->cr(); | |
400 // method()->print_codes(); | |
401 } else if (TraceDeoptimization) { | |
402 tty->print(" "); | |
403 method()->print_value(); | |
2142 | 404 Bytecodes::Code code = Bytecodes::java_code_at(method(), bcp); |
0 | 405 int bci = method()->bci_from(bcp); |
406 tty->print(" - %s", Bytecodes::name(code)); | |
407 tty->print(" @ bci %d ", bci); | |
408 tty->print_cr("sp = " PTR_FORMAT, iframe()->sp()); | |
409 } | |
410 #endif // PRODUCT | |
411 | |
412 // The expression stack and locals are in the resource area don't leave | |
413 // a dangling pointer in the vframeArray we leave around for debug | |
414 // purposes | |
415 | |
416 _locals = _expressions = NULL; | |
417 | |
418 } | |
419 | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
420 int vframeArrayElement::on_stack_size(int caller_actual_parameters, |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
421 int callee_parameters, |
0 | 422 int callee_locals, |
423 bool is_top_frame, | |
424 int popframe_extra_stack_expression_els) const { | |
425 assert(method()->max_locals() == locals()->size(), "just checking"); | |
426 int locks = monitors() == NULL ? 0 : monitors()->number_of_monitors(); | |
427 int temps = expressions()->size(); | |
428 return Interpreter::size_activation(method(), | |
429 temps + callee_parameters, | |
430 popframe_extra_stack_expression_els, | |
431 locks, | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
432 caller_actual_parameters, |
0 | 433 callee_parameters, |
434 callee_locals, | |
435 is_top_frame); | |
436 } | |
437 | |
438 | |
439 | |
440 vframeArray* vframeArray::allocate(JavaThread* thread, int frame_size, GrowableArray<compiledVFrame*>* chunk, | |
441 RegisterMap *reg_map, frame sender, frame caller, frame self) { | |
442 | |
443 // Allocate the vframeArray | |
444 vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part | |
445 sizeof(vframeArrayElement) * (chunk->length() - 1), // variable part | |
446 "vframeArray::allocate"); | |
447 result->_frames = chunk->length(); | |
448 result->_owner_thread = thread; | |
449 result->_sender = sender; | |
450 result->_caller = caller; | |
451 result->_original = self; | |
452 result->set_unroll_block(NULL); // initialize it | |
453 result->fill_in(thread, frame_size, chunk, reg_map); | |
454 return result; | |
455 } | |
456 | |
457 void vframeArray::fill_in(JavaThread* thread, | |
458 int frame_size, | |
459 GrowableArray<compiledVFrame*>* chunk, | |
460 const RegisterMap *reg_map) { | |
461 // Set owner first, it is used when adding monitor chunks | |
462 | |
463 _frame_size = frame_size; | |
464 for(int i = 0; i < chunk->length(); i++) { | |
465 element(i)->fill_in(chunk->at(i)); | |
466 } | |
467 | |
468 // Copy registers for callee-saved registers | |
469 if (reg_map != NULL) { | |
470 for(int i = 0; i < RegisterMap::reg_count; i++) { | |
471 #ifdef AMD64 | |
472 // The register map has one entry for every int (32-bit value), so | |
473 // 64-bit physical registers have two entries in the map, one for | |
474 // each half. Ignore the high halves of 64-bit registers, just like | |
475 // frame::oopmapreg_to_location does. | |
476 // | |
477 // [phh] FIXME: this is a temporary hack! This code *should* work | |
478 // correctly w/o this hack, possibly by changing RegisterMap::pd_location | |
479 // in frame_amd64.cpp and the values of the phantom high half registers | |
480 // in amd64.ad. | |
481 // if (VMReg::Name(i) < SharedInfo::stack0 && is_even(i)) { | |
482 intptr_t* src = (intptr_t*) reg_map->location(VMRegImpl::as_VMReg(i)); | |
483 _callee_registers[i] = src != NULL ? *src : NULL_WORD; | |
484 // } else { | |
485 // jint* src = (jint*) reg_map->location(VMReg::Name(i)); | |
486 // _callee_registers[i] = src != NULL ? *src : NULL_WORD; | |
487 // } | |
488 #else | |
489 jint* src = (jint*) reg_map->location(VMRegImpl::as_VMReg(i)); | |
490 _callee_registers[i] = src != NULL ? *src : NULL_WORD; | |
491 #endif | |
492 if (src == NULL) { | |
493 set_location_valid(i, false); | |
494 } else { | |
495 set_location_valid(i, true); | |
496 jint* dst = (jint*) register_location(i); | |
497 *dst = *src; | |
498 } | |
499 } | |
500 } | |
501 } | |
502 | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
503 void vframeArray::unpack_to_stack(frame &unpack_frame, int exec_mode, int caller_actual_parameters) { |
0 | 504 // stack picture |
505 // unpack_frame | |
506 // [new interpreter frames ] (frames are skeletal but walkable) | |
507 // caller_frame | |
508 // | |
509 // This routine fills in the missing data for the skeletal interpreter frames | |
510 // in the above picture. | |
511 | |
512 // Find the skeletal interpreter frames to unpack into | |
513 RegisterMap map(JavaThread::current(), false); | |
514 // Get the youngest frame we will unpack (last to be unpacked) | |
515 frame me = unpack_frame.sender(&map); | |
516 int index; | |
517 for (index = 0; index < frames(); index++ ) { | |
518 *element(index)->iframe() = me; | |
519 // Get the caller frame (possibly skeletal) | |
520 me = me.sender(&map); | |
521 } | |
522 | |
523 frame caller_frame = me; | |
524 | |
525 // Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee | |
526 | |
527 // Unpack the frames from the oldest (frames() -1) to the youngest (0) | |
528 | |
529 for (index = frames() - 1; index >= 0 ; index--) { | |
530 int callee_parameters = index == 0 ? 0 : element(index-1)->method()->size_of_parameters(); | |
531 int callee_locals = index == 0 ? 0 : element(index-1)->method()->max_locals(); | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
532 element(index)->unpack_on_stack(caller_actual_parameters, |
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
533 callee_parameters, |
0 | 534 callee_locals, |
535 &caller_frame, | |
536 index == 0, | |
537 exec_mode); | |
538 if (index == frames() - 1) { | |
539 Deoptimization::unwind_callee_save_values(element(index)->iframe(), this); | |
540 } | |
541 caller_frame = *element(index)->iframe(); | |
3369
3d2ab563047a
7043461: VM crashes in void LinkResolver::runtime_resolve_virtual_method
never
parents:
2142
diff
changeset
|
542 caller_actual_parameters = callee_parameters; |
0 | 543 } |
544 | |
545 | |
546 deallocate_monitor_chunks(); | |
547 } | |
548 | |
549 void vframeArray::deallocate_monitor_chunks() { | |
550 JavaThread* jt = JavaThread::current(); | |
551 for (int index = 0; index < frames(); index++ ) { | |
552 element(index)->free_monitors(jt); | |
553 } | |
554 } | |
555 | |
556 #ifndef PRODUCT | |
557 | |
558 bool vframeArray::structural_compare(JavaThread* thread, GrowableArray<compiledVFrame*>* chunk) { | |
559 if (owner_thread() != thread) return false; | |
560 int index = 0; | |
561 #if 0 // FIXME can't do this comparison | |
562 | |
563 // Compare only within vframe array. | |
564 for (deoptimizedVFrame* vf = deoptimizedVFrame::cast(vframe_at(first_index())); vf; vf = vf->deoptimized_sender_or_null()) { | |
565 if (index >= chunk->length() || !vf->structural_compare(chunk->at(index))) return false; | |
566 index++; | |
567 } | |
568 if (index != chunk->length()) return false; | |
569 #endif | |
570 | |
571 return true; | |
572 } | |
573 | |
574 #endif | |
575 | |
576 address vframeArray::register_location(int i) const { | |
577 assert(0 <= i && i < RegisterMap::reg_count, "index out of bounds"); | |
578 return (address) & _callee_registers[i]; | |
579 } | |
580 | |
581 | |
582 #ifndef PRODUCT | |
583 | |
584 // Printing | |
585 | |
586 // Note: we cannot have print_on as const, as we allocate inside the method | |
587 void vframeArray::print_on_2(outputStream* st) { | |
588 st->print_cr(" - sp: " INTPTR_FORMAT, sp()); | |
589 st->print(" - thread: "); | |
590 Thread::current()->print(); | |
591 st->print_cr(" - frame size: %d", frame_size()); | |
592 for (int index = 0; index < frames() ; index++ ) { | |
593 element(index)->print(st); | |
594 } | |
595 } | |
596 | |
597 void vframeArrayElement::print(outputStream* st) { | |
1255
e3a4305c6bc3
6925249: assert(last_sp < (intptr_t*) interpreter_frame_monitor_begin(),"bad tos")
kvn
parents:
903
diff
changeset
|
598 st->print_cr(" - interpreter_frame -> sp: " INTPTR_FORMAT, iframe()->sp()); |
0 | 599 } |
600 | |
601 void vframeArray::print_value_on(outputStream* st) const { | |
602 st->print_cr("vframeArray [%d] ", frames()); | |
603 } | |
604 | |
605 | |
606 #endif |