comparison src/share/vm/runtime/vframeArray.cpp @ 3153:5ca1332171c8

Fixed an issue in the HotSpot code for rethrowing an exception at deopt (wrong values on the expression stack caused a crash when GC and deopt happened at the same time).
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Tue, 05 Jul 2011 18:55:22 +0200
parents 008adfd6d850
children be4ca325525a
comparison
equal deleted inserted replaced
3152:3e89c4c5f37f 3153:5ca1332171c8
22 * 22 *
23 */ 23 */
24 24
25 #include "precompiled.hpp" 25 #include "precompiled.hpp"
26 #include "classfile/vmSymbols.hpp" 26 #include "classfile/vmSymbols.hpp"
27 #include "code/scopeDesc.hpp"
27 #include "interpreter/interpreter.hpp" 28 #include "interpreter/interpreter.hpp"
28 #include "memory/allocation.inline.hpp" 29 #include "memory/allocation.inline.hpp"
29 #include "memory/resourceArea.hpp" 30 #include "memory/resourceArea.hpp"
30 #include "memory/universe.inline.hpp" 31 #include "memory/universe.inline.hpp"
31 #include "oops/methodDataOop.hpp" 32 #include "oops/methodDataOop.hpp"
60 // interpreter frame we will be creating to replace vf 61 // interpreter frame we will be creating to replace vf
61 62
62 _method = vf->method(); 63 _method = vf->method();
63 _bci = vf->raw_bci(); 64 _bci = vf->raw_bci();
64 _reexecute = vf->should_reexecute(); 65 _reexecute = vf->should_reexecute();
65 66
66 int index; 67 int index;
67 68
68 // Get the monitors off-stack 69 // Get the monitors off-stack
69 70
70 GrowableArray<MonitorInfo*>* list = vf->monitors(); 71 GrowableArray<MonitorInfo*>* list = vf->monitors();
124 } 125 }
125 } 126 }
126 127
127 // Now the expressions off-stack 128 // Now the expressions off-stack
128 // Same silliness as above 129 // Same silliness as above
129 130 bool rethrow_exception = vf->scope()->rethrow_exception();
130 StackValueCollection *exprs = vf->expressions(); 131 if (rethrow_exception) {
131 _expressions = new StackValueCollection(exprs->size()); 132 // (tw) Make sure there are only null pointers on the stack, because the stack values do not correspond to the GC map at the bytecode at which the exception is rethrown.
132 for(index = 0; index < exprs->size(); index++) { 133 _expressions = new StackValueCollection(vf->method()->max_stack());
133 StackValue* value = exprs->at(index); 134 assert(Thread::current()->has_pending_exception(), "just checking");
134 switch(value->type()) { 135 for (int i=0; i<vf->method()->max_stack(); ++i) {
135 case T_OBJECT: 136 _expressions->add( new StackValue());
136 assert(!value->obj_is_scalar_replaced(), "object should be reallocated already"); 137 }
137 // preserve object type 138 } else {
138 _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT )); 139 StackValueCollection *exprs = vf->expressions();
139 break; 140 _expressions = new StackValueCollection(exprs->size());
140 case T_CONFLICT: 141 for(index = 0; index < exprs->size(); index++) {
141 // A dead stack element. Will be initialized to null/zero. 142 StackValue* value = exprs->at(index);
142 // This can occur when the compiler emits a state in which stack 143 switch(value->type()) {
143 // elements are known to be dead (because of an imminent exception). 144 case T_OBJECT:
144 _expressions->add( new StackValue()); 145 assert(!value->obj_is_scalar_replaced(), "object should be reallocated already");
145 break; 146 // preserve object type
146 case T_INT: 147 _expressions->add( new StackValue((intptr_t) (value->get_obj()()), T_OBJECT ));
147 _expressions->add( new StackValue(value->get_int())); 148 break;
148 break; 149 case T_CONFLICT:
149 default: 150 // A dead stack element. Will be initialized to null/zero.
150 ShouldNotReachHere(); 151 // This can occur when the compiler emits a state in which stack
152 // elements are known to be dead (because of an imminent exception).
153 _expressions->add( new StackValue());
154 break;
155 case T_INT:
156 _expressions->add( new StackValue(value->get_int()));
157 break;
158 default:
159 ShouldNotReachHere();
160 }
151 } 161 }
152 } 162 }
153 } 163 }
154 164
155 int unpack_counter = 0; 165 int unpack_counter = 0;
312 // Unpack expression stack 322 // Unpack expression stack
313 // If this is an intermediate frame (i.e. not top frame) then this 323 // If this is an intermediate frame (i.e. not top frame) then this
314 // only unpacks the part of the expression stack not used by callee 324 // only unpacks the part of the expression stack not used by callee
315 // as parameters. The callee parameters are unpacked as part of the 325 // as parameters. The callee parameters are unpacked as part of the
316 // callee locals. 326 // callee locals.
317 int i; 327 for(int i = 0; i < expressions()->size(); i++) {
318 for(i = 0; i < expressions()->size(); i++) {
319 StackValue *value = expressions()->at(i); 328 StackValue *value = expressions()->at(i);
320 intptr_t* addr = iframe()->interpreter_frame_expression_stack_at(i); 329 intptr_t* addr = iframe()->interpreter_frame_expression_stack_at(i);
321 switch(value->type()) { 330 switch(value->type()) {
322 case T_INT: 331 case T_INT:
323 *addr = value->get_int(); 332 *addr = value->get_int();
350 } 359 }
351 } 360 }
352 361
353 362
354 // Unpack the locals 363 // Unpack the locals
355 for(i = 0; i < locals()->size(); i++) { 364 for(int i = 0; i < locals()->size(); i++) {
356 StackValue *value = locals()->at(i); 365 StackValue *value = locals()->at(i);
357 intptr_t* addr = iframe()->interpreter_frame_local_at(i); 366 intptr_t* addr = iframe()->interpreter_frame_local_at(i);
358 switch(value->type()) { 367 switch(value->type()) {
359 case T_INT: 368 case T_INT:
360 *addr = value->get_int(); 369 *addr = value->get_int();