Mercurial > hg > truffle
comparison src/cpu/zero/vm/cppInterpreter_zero.cpp @ 1379:f9271ff9d324
6941224: Improved stack overflow handling for Zero
Summary: Adding stack overflow checking to Shark brought to light a bunch of deficiencies in Zero's stack overflow code.
Reviewed-by: twisti
Contributed-by: Gary Benson <gbenson@redhat.com>
author | twisti |
---|---|
date | Thu, 15 Apr 2010 02:40:12 -0700 |
parents | 747d26efc5fa |
children | 0c5b3cf3c1f5 |
comparison
equal
deleted
inserted
replaced
1377:ef74d6d1ac1e | 1379:f9271ff9d324 |
---|---|
37 thread->reset_last_Java_frame(); \ | 37 thread->reset_last_Java_frame(); \ |
38 fixup_after_potential_safepoint() | 38 fixup_after_potential_safepoint() |
39 | 39 |
40 void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { | 40 void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) { |
41 JavaThread *thread = (JavaThread *) THREAD; | 41 JavaThread *thread = (JavaThread *) THREAD; |
42 ZeroStack *stack = thread->zero_stack(); | |
43 | |
44 // Adjust the caller's stack frame to accomodate any additional | |
45 // local variables we have contiguously with our parameters. | |
46 int extra_locals = method->max_locals() - method->size_of_parameters(); | |
47 if (extra_locals > 0) { | |
48 if (extra_locals > stack->available_words()) { | |
49 Unimplemented(); | |
50 } | |
51 for (int i = 0; i < extra_locals; i++) | |
52 stack->push(0); | |
53 } | |
54 | 42 |
55 // Allocate and initialize our frame. | 43 // Allocate and initialize our frame. |
56 InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); | 44 InterpreterFrame *frame = InterpreterFrame::build(method, CHECK); |
57 thread->push_zero_frame(frame); | 45 thread->push_zero_frame(frame); |
58 | 46 |
59 // Execute those bytecodes! | 47 // Execute those bytecodes! |
60 main_loop(0, THREAD); | 48 main_loop(0, THREAD); |
61 } | 49 } |
73 interpreterState istate = frame->interpreter_state(); | 61 interpreterState istate = frame->interpreter_state(); |
74 methodOop method = istate->method(); | 62 methodOop method = istate->method(); |
75 | 63 |
76 intptr_t *result = NULL; | 64 intptr_t *result = NULL; |
77 int result_slots = 0; | 65 int result_slots = 0; |
78 | |
79 // Check we're not about to run out of stack | |
80 if (stack_overflow_imminent(thread)) { | |
81 CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); | |
82 goto unwind_and_return; | |
83 } | |
84 | 66 |
85 while (true) { | 67 while (true) { |
86 // We can set up the frame anchor with everything we want at | 68 // We can set up the frame anchor with everything we want at |
87 // this point as we are thread_in_Java and no safepoints can | 69 // this point as we are thread_in_Java and no safepoints can |
88 // occur until we go to vm mode. We do have to clear flags | 70 // occur until we go to vm mode. We do have to clear flags |
121 } | 103 } |
122 else if (istate->msg() == BytecodeInterpreter::more_monitors) { | 104 else if (istate->msg() == BytecodeInterpreter::more_monitors) { |
123 int monitor_words = frame::interpreter_frame_monitor_size(); | 105 int monitor_words = frame::interpreter_frame_monitor_size(); |
124 | 106 |
125 // Allocate the space | 107 // Allocate the space |
126 if (monitor_words > stack->available_words()) { | 108 stack->overflow_check(monitor_words, THREAD); |
127 Unimplemented(); | 109 if (HAS_PENDING_EXCEPTION) |
128 } | 110 break; |
129 stack->alloc(monitor_words * wordSize); | 111 stack->alloc(monitor_words * wordSize); |
130 | 112 |
131 // Move the expression stack contents | 113 // Move the expression stack contents |
132 for (intptr_t *p = istate->stack() + 1; p < istate->stack_base(); p++) | 114 for (intptr_t *p = istate->stack() + 1; p < istate->stack_base(); p++) |
133 *(p - monitor_words) = *p; | 115 *(p - monitor_words) = *p; |
170 else { | 152 else { |
171 ShouldNotReachHere(); | 153 ShouldNotReachHere(); |
172 } | 154 } |
173 } | 155 } |
174 | 156 |
175 unwind_and_return: | |
176 | |
177 // Unwind the current frame | 157 // Unwind the current frame |
178 thread->pop_zero_frame(); | 158 thread->pop_zero_frame(); |
179 | 159 |
180 // Pop our local variables | 160 // Pop our local variables |
181 stack->set_sp(stack->sp() + method->max_locals()); | 161 stack->set_sp(stack->sp() + method->max_locals()); |
191 | 171 |
192 JavaThread *thread = (JavaThread *) THREAD; | 172 JavaThread *thread = (JavaThread *) THREAD; |
193 ZeroStack *stack = thread->zero_stack(); | 173 ZeroStack *stack = thread->zero_stack(); |
194 | 174 |
195 // Allocate and initialize our frame | 175 // Allocate and initialize our frame |
196 InterpreterFrame *frame = InterpreterFrame::build(stack, method, thread); | 176 InterpreterFrame *frame = InterpreterFrame::build(method, CHECK); |
197 thread->push_zero_frame(frame); | 177 thread->push_zero_frame(frame); |
198 interpreterState istate = frame->interpreter_state(); | 178 interpreterState istate = frame->interpreter_state(); |
199 intptr_t *locals = istate->locals(); | 179 intptr_t *locals = istate->locals(); |
200 | |
201 // Check we're not about to run out of stack | |
202 if (stack_overflow_imminent(thread)) { | |
203 CALL_VM_NOCHECK(InterpreterRuntime::throw_StackOverflowError(thread)); | |
204 goto unwind_and_return; | |
205 } | |
206 | 180 |
207 // Update the invocation counter | 181 // Update the invocation counter |
208 if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) { | 182 if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) { |
209 InvocationCounter *counter = method->invocation_counter(); | 183 InvocationCounter *counter = method->invocation_counter(); |
210 counter->increment(); | 184 counter->increment(); |
262 address function; | 236 address function; |
263 function = method->native_function(); | 237 function = method->native_function(); |
264 assert(function != NULL, "should be set if signature handler is"); | 238 assert(function != NULL, "should be set if signature handler is"); |
265 | 239 |
266 // Build the argument list | 240 // Build the argument list |
267 if (handler->argument_count() * 2 > stack->available_words()) { | 241 stack->overflow_check(handler->argument_count() * 2, THREAD); |
268 Unimplemented(); | 242 if (HAS_PENDING_EXCEPTION) |
269 } | 243 goto unlock_unwind_and_return; |
244 | |
270 void **arguments; | 245 void **arguments; |
271 void *mirror; { | 246 void *mirror; { |
272 arguments = | 247 arguments = |
273 (void **) stack->alloc(handler->argument_count() * sizeof(void **)); | 248 (void **) stack->alloc(handler->argument_count() * sizeof(void **)); |
274 void **dst = arguments; | 249 void **dst = arguments; |
501 | 476 |
502 // Get the result and push it onto the stack | 477 // Get the result and push it onto the stack |
503 switch (entry->flag_state()) { | 478 switch (entry->flag_state()) { |
504 case ltos: | 479 case ltos: |
505 case dtos: | 480 case dtos: |
506 if (stack->available_words() < 1) { | 481 stack->overflow_check(1, CHECK); |
507 Unimplemented(); | |
508 } | |
509 stack->alloc(wordSize); | 482 stack->alloc(wordSize); |
510 break; | 483 break; |
511 } | 484 } |
512 if (entry->is_volatile()) { | 485 if (entry->is_volatile()) { |
513 switch (entry->flag_state()) { | 486 switch (entry->flag_state()) { |
599 | 572 |
600 // Pop our parameters | 573 // Pop our parameters |
601 stack->set_sp(stack->sp() + method->size_of_parameters()); | 574 stack->set_sp(stack->sp() + method->size_of_parameters()); |
602 } | 575 } |
603 | 576 |
604 bool CppInterpreter::stack_overflow_imminent(JavaThread *thread) { | 577 InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) { |
605 // How is the ABI stack? | 578 JavaThread *thread = (JavaThread *) THREAD; |
606 address stack_top = thread->stack_base() - thread->stack_size(); | 579 ZeroStack *stack = thread->zero_stack(); |
607 int free_stack = os::current_stack_pointer() - stack_top; | 580 |
608 if (free_stack < StackShadowPages * os::vm_page_size()) { | 581 // Calculate the size of the frame we'll build, including |
609 return true; | 582 // any adjustments to the caller's frame that we'll make. |
610 } | 583 int extra_locals = 0; |
611 | 584 int monitor_words = 0; |
612 // How is the Zero stack? | 585 int stack_words = 0; |
613 // Throwing a StackOverflowError involves a VM call, which means | 586 |
614 // we need a frame on the stack. We should be checking here to | 587 if (!method->is_native()) { |
615 // ensure that methods we call have enough room to install the | 588 extra_locals = method->max_locals() - method->size_of_parameters(); |
616 // largest possible frame, but that's more than twice the size | 589 stack_words = method->max_stack(); |
617 // of the entire Zero stack we get by default, so we just check | 590 } |
618 // we have *some* space instead... | 591 if (method->is_synchronized()) { |
619 free_stack = thread->zero_stack()->available_words() * wordSize; | 592 monitor_words = frame::interpreter_frame_monitor_size(); |
620 if (free_stack < StackShadowPages * os::vm_page_size()) { | 593 } |
621 return true; | 594 stack->overflow_check( |
622 } | 595 extra_locals + header_words + monitor_words + stack_words, CHECK_NULL); |
623 | 596 |
624 return false; | 597 // Adjust the caller's stack frame to accomodate any additional |
625 } | 598 // local variables we have contiguously with our parameters. |
626 | 599 for (int i = 0; i < extra_locals; i++) |
627 InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, | 600 stack->push(0); |
628 const methodOop method, | |
629 JavaThread* thread) { | |
630 int monitor_words = | |
631 method->is_synchronized() ? frame::interpreter_frame_monitor_size() : 0; | |
632 int stack_words = method->is_native() ? 0 : method->max_stack(); | |
633 | |
634 if (header_words + monitor_words + stack_words > stack->available_words()) { | |
635 Unimplemented(); | |
636 } | |
637 | 601 |
638 intptr_t *locals; | 602 intptr_t *locals; |
639 if (method->is_native()) | 603 if (method->is_native()) |
640 locals = stack->sp() + (method->size_of_parameters() - 1); | 604 locals = stack->sp() + (method->size_of_parameters() - 1); |
641 else | 605 else |
810 generate_all(); | 774 generate_all(); |
811 } | 775 } |
812 | 776 |
813 // Deoptimization helpers | 777 // Deoptimization helpers |
814 | 778 |
815 InterpreterFrame *InterpreterFrame::build(ZeroStack* stack, int size) { | 779 InterpreterFrame *InterpreterFrame::build(int size, TRAPS) { |
780 ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); | |
781 | |
816 int size_in_words = size >> LogBytesPerWord; | 782 int size_in_words = size >> LogBytesPerWord; |
817 assert(size_in_words * wordSize == size, "unaligned"); | 783 assert(size_in_words * wordSize == size, "unaligned"); |
818 assert(size_in_words >= header_words, "too small"); | 784 assert(size_in_words >= header_words, "too small"); |
819 | 785 stack->overflow_check(size_in_words, CHECK_NULL); |
820 if (size_in_words > stack->available_words()) { | |
821 Unimplemented(); | |
822 } | |
823 | 786 |
824 stack->push(0); // next_frame, filled in later | 787 stack->push(0); // next_frame, filled in later |
825 intptr_t *fp = stack->sp(); | 788 intptr_t *fp = stack->sp(); |
826 assert(fp - stack->sp() == next_frame_off, "should be"); | 789 assert(fp - stack->sp() == next_frame_off, "should be"); |
827 | 790 |