< prev index next >

src/hotspot/share/jfr/periodic/sampling/jfrThreadSampling.cpp

Print this page

195 
196   if (stream.current()->is_safepoint_blob_frame()) {
197     if (sampled_nm != nullptr) {
198       // Move to the physical sender frame of the SafepointBlob stub frame using the frame size, not the logical iterator.
199       const int safepoint_blob_stub_frame_size = stream.current()->cb()->frame_size();
200       intptr_t* const sender_sp = stream.current()->unextended_sp() + safepoint_blob_stub_frame_size;
201       if (sender_sp > sampled_sp) {
202         const address saved_exception_pc = jt->saved_exception_pc();
203         assert(saved_exception_pc != nullptr, "invariant");
204         const nmethod* const exception_nm = CodeCache::find_blob(saved_exception_pc)->as_nmethod();
205         assert(exception_nm != nullptr, "invariant");
206         if (exception_nm == sampled_nm && sampled_nm->is_at_poll_return(saved_exception_pc)) {
207           // We sit at the poll return site in the sampled compiled nmethod with only the return address on the stack.
208           // The sampled_nm compiled frame is no longer extant, but we might be able to reconstruct a synthetic
209           // compiled frame at this location. We do this by overlaying a reconstructed frame on top of
210           // the huge SafepointBlob stub frame. Of course, the synthetic frame only contains random stack memory,
211           // but it is safe because stack walking cares only about the form of the frame (i.e., an sp and a pc).
212           // We also do not have to worry about stackbanging because we currently have a huge SafepointBlob stub frame
213           // on the stack. For extra assurance, we know that we can create this frame size at this
214           // very location because we just popped such a frame before we hit the return poll site.


215           //
216           // Let's attempt to correct for the safepoint bias.
217           const PcDesc* const pc_desc = get_pc_desc(sampled_nm, sampled_pc);
218           if (is_valid(pc_desc)) {
219             intptr_t* const synthetic_sp = sender_sp - sampled_nm->frame_size();
220             top_frame = frame(synthetic_sp, synthetic_sp, sender_sp, pc_desc->real_pc(sampled_nm), sampled_nm);
221             in_continuation = is_in_continuation(top_frame, jt);
222             return true;
223           }
224         }
225       }
226     }
227     stream.next(); // skip the SafepointBlob stub frame
228   }
229 
230   assert(!stream.current()->is_safepoint_blob_frame(), "invariant");
231 
232   biased = true;
233 
234   // Search the first frame that is above the sampled sp.
235   for (; !stream.is_done(); stream.next()) {
236     frame* const current = stream.current();
237 
238     if (current->real_fp() <= sampled_sp) {

195 
196   if (stream.current()->is_safepoint_blob_frame()) {
197     if (sampled_nm != nullptr) {
198       // Move to the physical sender frame of the SafepointBlob stub frame using the frame size, not the logical iterator.
199       const int safepoint_blob_stub_frame_size = stream.current()->cb()->frame_size();
200       intptr_t* const sender_sp = stream.current()->unextended_sp() + safepoint_blob_stub_frame_size;
201       if (sender_sp > sampled_sp) {
202         const address saved_exception_pc = jt->saved_exception_pc();
203         assert(saved_exception_pc != nullptr, "invariant");
204         const nmethod* const exception_nm = CodeCache::find_blob(saved_exception_pc)->as_nmethod();
205         assert(exception_nm != nullptr, "invariant");
206         if (exception_nm == sampled_nm && sampled_nm->is_at_poll_return(saved_exception_pc)) {
207           // We sit at the poll return site in the sampled compiled nmethod with only the return address on the stack.
208           // The sampled_nm compiled frame is no longer extant, but we might be able to reconstruct a synthetic
209           // compiled frame at this location. We do this by overlaying a reconstructed frame on top of
210           // the huge SafepointBlob stub frame. Of course, the synthetic frame only contains random stack memory,
211           // but it is safe because stack walking cares only about the form of the frame (i.e., an sp and a pc).
212           // We also do not have to worry about stackbanging because we currently have a huge SafepointBlob stub frame
213           // on the stack. For extra assurance, we know that we can create this frame size at this
214           // very location because we just popped such a frame before we hit the return poll site.
215           // For frames that need stack repair we skip this trick. This is because the stack walking code reads
216           // the frame size from the stack, but the memory has already been overwritten by the SafepointBlob.
217           //
218           // Let's attempt to correct for the safepoint bias.
219           const PcDesc* const pc_desc = get_pc_desc(sampled_nm, sampled_pc);
220           if (is_valid(pc_desc) && !sampled_nm->needs_stack_repair()) {
221             intptr_t* const synthetic_sp = sender_sp - sampled_nm->frame_size();
222             top_frame = frame(synthetic_sp, synthetic_sp, sender_sp, pc_desc->real_pc(sampled_nm), sampled_nm);
223             in_continuation = is_in_continuation(top_frame, jt);
224             return true;
225           }
226         }
227       }
228     }
229     stream.next(); // skip the SafepointBlob stub frame
230   }
231 
232   assert(!stream.current()->is_safepoint_blob_frame(), "invariant");
233 
234   biased = true;
235 
236   // Search the first frame that is above the sampled sp.
237   for (; !stream.is_done(); stream.next()) {
238     frame* const current = stream.current();
239 
240     if (current->real_fp() <= sampled_sp) {
< prev index next >