equal
deleted
inserted
replaced
83 CON_O5, |
83 CON_O5, |
84 CON_O6, |
84 CON_O6, |
85 CON_O7, |
85 CON_O7, |
86 }; |
86 }; |
87 |
87 |
88 static inline void set_cont_address(sigcontext* ctx, address addr) { |
|
89 SIG_PC(ctx) = (intptr_t)addr; |
|
90 SIG_NPC(ctx) = (intptr_t)(addr+4); |
|
91 } |
|
92 |
|
93 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is |
88 // For Forte Analyzer AsyncGetCallTrace profiling support - thread is |
94 // currently interrupted by SIGPROF. |
89 // currently interrupted by SIGPROF. |
95 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested |
90 // os::Solaris::fetch_frame_from_ucontext() tries to skip nested |
96 // signal frames. Currently we don't do that on Linux, so it's the |
91 // signal frames. Currently we don't do that on Linux, so it's the |
97 // same as os::fetch_frame_from_context(). |
92 // same as os::fetch_frame_from_context(). |
349 |
344 |
350 address os::Linux::ucontext_get_pc(ucontext_t* uc) { |
345 address os::Linux::ucontext_get_pc(ucontext_t* uc) { |
351 return (address) SIG_PC((sigcontext*)uc); |
346 return (address) SIG_PC((sigcontext*)uc); |
352 } |
347 } |
353 |
348 |
|
349 void os::Linux::ucontext_set_pc(ucontext_t* uc, address pc) { |
|
350 sigcontext_t* ctx = (sigcontext_t*) uc; |
|
351 SIG_PC(ctx) = (intptr_t)addr; |
|
352 SIG_NPC(ctx) = (intptr_t)(addr+4); |
|
353 } |
|
354 |
354 intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) { |
355 intptr_t* os::Linux::ucontext_get_sp(ucontext_t *uc) { |
355 return (intptr_t*) |
356 return (intptr_t*) |
356 ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS); |
357 ((intptr_t)SIG_REGS((sigcontext*)uc).u_regs[CON_O6] + STACK_BIAS); |
357 } |
358 } |
358 |
359 |
364 |
365 |
365 // Utility functions |
366 // Utility functions |
366 |
367 |
367 inline static bool checkPrefetch(sigcontext* uc, address pc) { |
368 inline static bool checkPrefetch(sigcontext* uc, address pc) { |
368 if (StubRoutines::is_safefetch_fault(pc)) { |
369 if (StubRoutines::is_safefetch_fault(pc)) { |
369 set_cont_address(uc, address(StubRoutines::continuation_for_safefetch_fault(pc))); |
370 os::Linux::ucontext_set_pc((ucontext_t*)uc, StubRoutines::continuation_for_safefetch_fault(pc)); |
370 return true; |
371 return true; |
371 } |
372 } |
372 return false; |
373 return false; |
373 } |
374 } |
374 |
375 |
664 |
665 |
665 if (stub != NULL) { |
666 if (stub != NULL) { |
666 // save all thread context in case we need to restore it |
667 // save all thread context in case we need to restore it |
667 thread->set_saved_exception_pc(pc); |
668 thread->set_saved_exception_pc(pc); |
668 thread->set_saved_exception_npc(npc); |
669 thread->set_saved_exception_npc(npc); |
669 set_cont_address(uc, stub); |
670 os::Linux::ucontext_set_pc((ucontext_t*)uc, stub); |
670 return true; |
671 return true; |
671 } |
672 } |
672 } |
673 } |
673 |
674 |
674 // signal-chaining |
675 // signal-chaining |