40 |
40 |
41 return frame(sp, pc); |
41 return frame(sp, pc); |
42 } |
42 } |
43 |
43 |
44 bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { |
44 bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { |
45 ucontext_t* uc = (ucontext_t*) ucontext; |
45 assert(this->is_Java_thread(), "must be JavaThread"); |
46 *fr_addr = frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], |
46 |
47 (address)uc->uc_mcontext.regs->nip); |
47 // If we have a last_Java_frame, then we should use it even if |
48 return true; |
48 // isInJava == true. It should be more reliable than ucontext info. |
|
49 if (has_last_Java_frame() && frame_anchor()->walkable()) { |
|
50 *fr_addr = pd_last_frame(); |
|
51 return true; |
|
52 } |
|
53 |
|
54 // At this point, we don't have a last_Java_frame, so |
|
55 // we try to glean some information out of the ucontext |
|
56 // if we were running Java code when SIGPROF came in. |
|
57 if (isInJava) { |
|
58 ucontext_t* uc = (ucontext_t*) ucontext; |
|
59 frame ret_frame((intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/], |
|
60 (address)uc->uc_mcontext.regs->nip); |
|
61 |
|
62 if (ret_frame.pc() == NULL) { |
|
63 // ucontext wasn't useful |
|
64 return false; |
|
65 } |
|
66 |
|
67 if (ret_frame.is_interpreted_frame()) { |
|
68 frame::ijava_state* istate = ret_frame.get_ijava_state(); |
|
69 if (!((Method*)(istate->method))->is_metaspace_object()) { |
|
70 return false; |
|
71 } |
|
72 uint64_t reg_bcp = uc->uc_mcontext.regs->gpr[14/*R14_bcp*/]; |
|
73 uint64_t istate_bcp = istate->bcp; |
|
74 uint64_t code_start = (uint64_t)(((Method*)(istate->method))->code_base()); |
|
75 uint64_t code_end = (uint64_t)(((Method*)istate->method)->code_base() + ((Method*)istate->method)->code_size()); |
|
76 if (istate_bcp >= code_start && istate_bcp < code_end) { |
|
77 // we have a valid bcp, don't touch it, do nothing |
|
78 } else if (reg_bcp >= code_start && reg_bcp < code_end) { |
|
79 istate->bcp = reg_bcp; |
|
80 } else { |
|
81 return false; |
|
82 } |
|
83 } |
|
84 if (!ret_frame.safe_for_sender(this)) { |
|
85 // nothing else to try if the frame isn't good |
|
86 return false; |
|
87 } |
|
88 *fr_addr = ret_frame; |
|
89 return true; |
|
90 } |
|
91 // nothing else to try |
|
92 return false; |
49 } |
93 } |
50 |
94 |
51 // Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Linux/PPC. |
95 // Forte Analyzer AsyncGetCallTrace profiling support is not implemented on Linux/PPC. |
52 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) { |
96 bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, bool isInJava) { |
53 Unimplemented(); |
97 assert(this->is_Java_thread(), "must be JavaThread"); |
54 return false; |
98 return pd_get_top_frame_for_profiling(fr_addr, ucontext, isInJava); |
55 } |
99 } |
56 |
100 |
57 void JavaThread::cache_global_variables() { } |
101 void JavaThread::cache_global_variables() { } |