@@ -115,6 +115,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
115
115
if (is_entry_frame ()) {
116
116
// an entry frame must have a valid fp.
117
117
return fp_safe && is_entry_frame_valid (thread);
118
+ } else if (is_optimized_entry_frame ()) {
119
+ return fp_safe;
118
120
}
119
121
120
122
intptr_t * sender_sp = NULL ;
@@ -211,6 +213,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
211
213
address jcw = (address)sender.entry_frame_call_wrapper ();
212
214
213
215
return thread->is_in_stack_range_excl (jcw, (address)sender.fp ());
216
+ } else if (sender_blob->is_optimized_entry_blob ()) {
217
+ return false ;
214
218
}
215
219
216
220
CompiledMethod* nm = sender_blob->as_compiled_method_or_null ();
@@ -363,18 +367,39 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
363
367
}
364
368
365
369
OptimizedEntryBlob::FrameData* OptimizedEntryBlob::frame_data_for_frame (const frame& frame) const {
366
- ShouldNotCallThis ();
367
- return nullptr ;
370
+ assert (frame.is_optimized_entry_frame (), " wrong frame" );
371
+ // need unextended_sp here, since normal sp is wrong for interpreter callees
372
+ return reinterpret_cast <OptimizedEntryBlob::FrameData*>(
373
+ reinterpret_cast <char *>(frame.unextended_sp ()) + in_bytes (_frame_data_offset));
368
374
}
369
375
370
376
bool frame::optimized_entry_frame_is_first () const {
371
- ShouldNotCallThis ();
372
- return false ;
377
+ assert (is_optimized_entry_frame (), " must be optimzed entry frame" );
378
+ OptimizedEntryBlob* blob = _cb->as_optimized_entry_blob ();
379
+ JavaFrameAnchor* jfa = blob->jfa_for_frame (*this );
380
+ return jfa->last_Java_sp () == NULL ;
373
381
}
374
382
375
383
frame frame::sender_for_optimized_entry_frame (RegisterMap* map) const {
376
- ShouldNotCallThis ();
377
- return {};
384
+ assert (map != NULL , " map must be set" );
385
+ OptimizedEntryBlob* blob = _cb->as_optimized_entry_blob ();
386
+ // Java frame called from C; skip all C frames and return top C
387
+ // frame of that chunk as the sender
388
+ JavaFrameAnchor* jfa = blob->jfa_for_frame (*this );
389
+ assert (!optimized_entry_frame_is_first (), " must have a frame anchor to go back to" );
390
+ assert (jfa->last_Java_sp () > sp (), " must be above this frame on stack" );
391
+ // Since we are walking the stack now this nested anchor is obviously walkable
392
+ // even if it wasn't when it was stacked.
393
+ if (!jfa->walkable ()) {
394
+ // Capture _last_Java_pc (if needed) and mark anchor walkable.
395
+ jfa->capture_last_Java_pc ();
396
+ }
397
+ map->clear ();
398
+ assert (map->include_argument_oops (), " should be set by clear" );
399
+ vmassert (jfa->last_Java_pc () != NULL , " not walkable" );
400
+ frame fr (jfa->last_Java_sp (), jfa->last_Java_fp (), jfa->last_Java_pc ());
401
+
402
+ return fr;
378
403
}
379
404
380
405
// ------------------------------------------------------------------------------
@@ -507,6 +532,8 @@ frame frame::sender_raw(RegisterMap* map) const {
507
532
508
533
if (is_entry_frame ())
509
534
return sender_for_entry_frame (map);
535
+ if (is_optimized_entry_frame ())
536
+ return sender_for_optimized_entry_frame (map);
510
537
if (is_interpreted_frame ())
511
538
return sender_for_interpreter_frame (map);
512
539
assert (_cb == CodeCache::find_blob (pc ())," Must be the same" );
0 commit comments