178 frame os::fetch_frame_from_context(const void* ucVoid) { |
179 frame os::fetch_frame_from_context(const void* ucVoid) { |
179 intptr_t* sp; |
180 intptr_t* sp; |
180 intptr_t* fp; |
181 intptr_t* fp; |
181 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); |
182 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); |
182 return frame(sp, fp, epc.pc()); |
183 return frame(sp, fp, epc.pc()); |
|
184 } |
|
185 |
|
186 bool os::Linux::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) { |
|
187 address pc = (address) os::Linux::ucontext_get_pc(uc); |
|
188 if (Interpreter::contains(pc)) { |
|
189 // interpreter performs stack banging after the fixed frame header has |
|
190 // been generated while the compilers perform it before. To maintain |
|
191 // semantic consistency between interpreted and compiled frames, the |
|
192 // method returns the Java sender of the current frame. |
|
193 *fr = os::fetch_frame_from_context(uc); |
|
194 if (!fr->is_first_java_frame()) { |
|
195 assert(fr->safe_for_sender(thread), "Safety check"); |
|
196 *fr = fr->java_sender(); |
|
197 } |
|
198 } else { |
|
199 // more complex code with compiled code |
|
200 assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); |
|
201 CodeBlob* cb = CodeCache::find_blob(pc); |
|
202 if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { |
|
203 // Not sure where the pc points to, fallback to default |
|
204 // stack overflow handling |
|
205 return false; |
|
206 } else { |
|
207 // In compiled code, the stack banging is performed before LR |
|
208 // has been saved in the frame. LR is live, and SP and FP |
|
209 // belong to the caller. |
|
210 intptr_t* fp = os::Linux::ucontext_get_fp(uc); |
|
211 intptr_t* sp = os::Linux::ucontext_get_sp(uc); |
|
212 address pc = (address)(uc->uc_mcontext.regs[REG_LR] |
|
213 - NativeInstruction::instruction_size); |
|
214 *fr = frame(sp, fp, pc); |
|
215 if (!fr->is_java_frame()) { |
|
216 assert(fr->safe_for_sender(thread), "Safety check"); |
|
217 assert(!fr->is_first_frame(), "Safety check"); |
|
218 *fr = fr->java_sender(); |
|
219 } |
|
220 } |
|
221 } |
|
222 assert(fr->is_java_frame(), "Safety check"); |
|
223 return true; |
183 } |
224 } |
184 |
225 |
185 // By default, gcc always saves frame pointer rfp on this stack. This |
226 // By default, gcc always saves frame pointer rfp on this stack. This |
186 // may get turned off by -fomit-frame-pointer. |
227 // may get turned off by -fomit-frame-pointer. |
187 frame os::get_sender_for_C_frame(frame* fr) { |
228 frame os::get_sender_for_C_frame(frame* fr) { |
311 if (thread->on_local_stack(addr)) { |
352 if (thread->on_local_stack(addr)) { |
312 // stack overflow |
353 // stack overflow |
313 if (thread->in_stack_yellow_reserved_zone(addr)) { |
354 if (thread->in_stack_yellow_reserved_zone(addr)) { |
314 thread->disable_stack_yellow_reserved_zone(); |
355 thread->disable_stack_yellow_reserved_zone(); |
315 if (thread->thread_state() == _thread_in_Java) { |
356 if (thread->thread_state() == _thread_in_Java) { |
|
357 if (thread->in_stack_reserved_zone(addr)) { |
|
358 frame fr; |
|
359 if (os::Linux::get_frame_at_stack_banging_point(thread, uc, &fr)) { |
|
360 assert(fr.is_java_frame(), "Must be a Java frame"); |
|
361 frame activation = |
|
362 SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr); |
|
363 if (activation.sp() != NULL) { |
|
364 thread->disable_stack_reserved_zone(); |
|
365 if (activation.is_interpreted_frame()) { |
|
366 thread->set_reserved_stack_activation((address)( |
|
367 activation.fp() + frame::interpreter_frame_initial_sp_offset)); |
|
368 } else { |
|
369 thread->set_reserved_stack_activation((address)activation.unextended_sp()); |
|
370 } |
|
371 return 1; |
|
372 } |
|
373 } |
|
374 } |
316 // Throw a stack overflow exception. Guard pages will be reenabled |
375 // Throw a stack overflow exception. Guard pages will be reenabled |
317 // while unwinding the stack. |
376 // while unwinding the stack. |
318 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
377 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW); |
319 } else { |
378 } else { |
320 // Thread was in the vm or native code. Return and try to finish. |
379 // Thread was in the vm or native code. Return and try to finish. |