218 epc = os::Solaris::ucontext_get_ExtendedPC(uc);
219 if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
220 if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
221 } else {
222 // construct empty ExtendedPC for return value checking
223 epc = ExtendedPC(NULL);
224 if (ret_sp) *ret_sp = (intptr_t *)NULL;
225 if (ret_fp) *ret_fp = (intptr_t *)NULL;
226 }
227
228 return epc;
229 }
230
231 frame os::fetch_frame_from_context(void* ucVoid) {
232 intptr_t* sp;
233 intptr_t* fp;
234 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
235 return frame(sp, fp, epc.pc());
236 }
237
238 frame os::get_sender_for_C_frame(frame* fr) {
239 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
240 }
241
242 extern "C" intptr_t *_get_current_sp(); // in .il file
243
244 address os::current_stack_pointer() {
245 return (address)_get_current_sp();
246 }
247
248 extern "C" intptr_t *_get_current_fp(); // in .il file
249
250 frame os::current_frame() {
251 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
252 frame myframe((intptr_t*)os::current_stack_pointer(),
253 (intptr_t*)fp,
254 CAST_FROM_FN_PTR(address, os::current_frame));
255 if (os::is_first_C_frame(&myframe)) {
256 // stack is not walkable
257 frame ret; // This will be a null useless frame
406
407 // decide if this trap can be handled by a stub
408 address stub = NULL;
409
410 address pc = NULL;
411
412 //%note os_trap_1
413 if (info != NULL && uc != NULL && thread != NULL) {
414 // factor me: getPCfromContext
415 pc = (address) uc->uc_mcontext.gregs[REG_PC];
416
417 if (StubRoutines::is_safefetch_fault(pc)) {
418 os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
419 return true;
420 }
421
422 // Handle ALL stack overflow variations here
423 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
424 address addr = (address) info->si_addr;
425 if (thread->in_stack_yellow_zone(addr)) {
426 thread->disable_stack_yellow_zone();
427 if (thread->thread_state() == _thread_in_Java) {
428 // Throw a stack overflow exception. Guard pages will be reenabled
429 // while unwinding the stack.
430 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
431 } else {
432 // Thread was in the vm or native code. Return and try to finish.
433 return true;
434 }
435 } else if (thread->in_stack_red_zone(addr)) {
436 // Fatal red zone violation. Disable the guard pages and fall through
437 // to handle_unexpected_exception way down below.
438 thread->disable_stack_red_zone();
439 tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
440 }
441 }
442
443 if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) {
444 // Verify that OS save/restore AVX registers.
445 stub = VM_Version::cpuinfo_cont_addr();
446 }
447
448 if (thread->thread_state() == _thread_in_vm) {
449 if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
450 stub = StubRoutines::handler_for_unsafe_access();
451 }
452 }
|
218 epc = os::Solaris::ucontext_get_ExtendedPC(uc);
219 if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc);
220 if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc);
221 } else {
222 // construct empty ExtendedPC for return value checking
223 epc = ExtendedPC(NULL);
224 if (ret_sp) *ret_sp = (intptr_t *)NULL;
225 if (ret_fp) *ret_fp = (intptr_t *)NULL;
226 }
227
228 return epc;
229 }
230
231 frame os::fetch_frame_from_context(void* ucVoid) {
232 intptr_t* sp;
233 intptr_t* fp;
234 ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp);
235 return frame(sp, fp, epc.pc());
236 }
237
238 frame os::fetch_frame_from_ucontext(Thread* thread, void* ucVoid) {
239 intptr_t* sp;
240 intptr_t* fp;
241 ExtendedPC epc = os::Solaris::fetch_frame_from_ucontext(thread, (ucontext_t*)ucVoid, &sp, &fp);
242 return frame(sp, fp, epc.pc());
243 }
244
245 bool os::Solaris::get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr) {
246 address pc = (address) os::Solaris::ucontext_get_pc(uc);
247 if (Interpreter::contains(pc)) {
248 // interpreter performs stack banging after the fixed frame header has
249 // been generated while the compilers perform it before. To maintain
250 // semantic consistency between interpreted and compiled frames, the
251 // method returns the Java sender of the current frame.
252 *fr = os::fetch_frame_from_ucontext(thread, uc);
253 assert(fr->safe_for_sender(thread), "Safety check");
254 if (!fr->is_first_java_frame()) {
255 *fr = fr->java_sender();
256 }
257 } else {
258 // more complex code with compiled code
259 assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
260 CodeBlob* cb = CodeCache::find_blob(pc);
261 if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
262 // Not sure where the pc points to, fallback to default
263 // stack overflow handling
264 return false;
265 } else {
266 // in compiled code, the stack banging is performed just after the return pc
267 // has been pushed on the stack
268 intptr_t* fp = os::Solaris::ucontext_get_fp(uc);
269 intptr_t* sp = os::Solaris::ucontext_get_sp(uc);
270 *fr = frame(sp + 1, fp, (address)*sp);
271 if (!fr->is_java_frame()) {
272 assert(fr->safe_for_sender(thread), "Safety check");
273 *fr = fr->java_sender();
274 }
275 }
276 }
277 assert(fr->is_java_frame(), "Safety check");
278 return true;
279 }
280
281 frame os::get_sender_for_C_frame(frame* fr) {
282 return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
283 }
284
285 extern "C" intptr_t *_get_current_sp(); // in .il file
286
287 address os::current_stack_pointer() {
288 return (address)_get_current_sp();
289 }
290
291 extern "C" intptr_t *_get_current_fp(); // in .il file
292
293 frame os::current_frame() {
294 intptr_t* fp = _get_current_fp(); // it's inlined so want current fp
295 frame myframe((intptr_t*)os::current_stack_pointer(),
296 (intptr_t*)fp,
297 CAST_FROM_FN_PTR(address, os::current_frame));
298 if (os::is_first_C_frame(&myframe)) {
299 // stack is not walkable
300 frame ret; // This will be a null useless frame
449
450 // decide if this trap can be handled by a stub
451 address stub = NULL;
452
453 address pc = NULL;
454
455 //%note os_trap_1
456 if (info != NULL && uc != NULL && thread != NULL) {
457 // factor me: getPCfromContext
458 pc = (address) uc->uc_mcontext.gregs[REG_PC];
459
460 if (StubRoutines::is_safefetch_fault(pc)) {
461 os::Solaris::ucontext_set_pc(uc, StubRoutines::continuation_for_safefetch_fault(pc));
462 return true;
463 }
464
465 // Handle ALL stack overflow variations here
466 if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) {
467 address addr = (address) info->si_addr;
468 if (thread->in_stack_yellow_zone(addr)) {
469 if (thread->thread_state() == _thread_in_Java) {
470 if (thread->in_stack_reserved_zone(addr)) {
471 frame fr;
472 if (os::Solaris::get_frame_at_stack_banging_point(thread, uc, &fr)) {
473 assert(fr.is_java_frame(), "Must be Java frame");
474 frame activation = SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr);
475 if (activation.sp() != NULL) {
476 thread->disable_stack_reserved_zone();
477 if (activation.is_interpreted_frame()) {
478 thread->set_reserved_stack_activation(
479 activation.fp() + frame::interpreter_frame_initial_sp_offset);
480 } else {
481 thread->set_reserved_stack_activation(activation.unextended_sp());
482 }
483 return true;
484 }
485 }
486 }
487 // Throw a stack overflow exception. Guard pages will be reenabled
488 // while unwinding the stack.
489 thread->disable_stack_yellow_zone();
490 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::STACK_OVERFLOW);
491 } else {
492 // Thread was in the vm or native code. Return and try to finish.
493 thread->disable_stack_yellow_zone();
494 return true;
495 }
496 } else if (thread->in_stack_red_zone(addr)) {
497 // Fatal red zone violation. Disable the guard pages and fall through
498 // to handle_unexpected_exception way down below.
499 thread->disable_stack_red_zone();
500 tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
501 }
502 }
503
504 if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) {
505 // Verify that OS save/restore AVX registers.
506 stub = VM_Version::cpuinfo_cont_addr();
507 }
508
509 if (thread->thread_state() == _thread_in_vm) {
510 if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) {
511 stub = StubRoutines::handler_for_unsafe_access();
512 }
513 }
|