@@ -67,6 +67,12 @@ inline frame FreezeBase::sender(const frame& f) {
67
67
68
68
int slot = 0 ;
69
69
CodeBlob* sender_cb = CodeCache::find_blob_and_oopmap (sender_pc, slot);
70
+
71
+ // Repair the sender sp if the frame has been extended
72
+ if (sender_cb->is_nmethod ()) {
73
+ sender_sp = f.repair_sender_sp (sender_sp, link_addr);
74
+ }
75
+
70
76
return sender_cb != nullptr
71
77
? frame (sender_sp, sender_sp, *link_addr, sender_pc, sender_cb,
72
78
slot == -1 ? nullptr : sender_cb->oop_map_for_slot (slot, sender_pc),
@@ -75,7 +81,7 @@ inline frame FreezeBase::sender(const frame& f) {
75
81
}
76
82
77
83
template <typename FKind>
78
- frame FreezeBase::new_heap_frame (frame& f, frame& caller) {
84
+ frame FreezeBase::new_heap_frame (frame& f, frame& caller, int size_adjust ) {
79
85
assert (FKind::is_instance (f), " " );
80
86
assert (!caller.is_interpreted_frame ()
81
87
|| caller.unextended_sp () == (intptr_t *)caller.at (frame::interpreter_frame_last_sp_offset), " " );
@@ -106,8 +112,8 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
106
112
fp = *(intptr_t **)(f.sp () - frame::sender_sp_offset);
107
113
108
114
int fsize = FKind::size (f);
109
- sp = caller.unextended_sp () - fsize;
110
- if (caller.is_interpreted_frame ()) {
115
+ sp = caller.unextended_sp () - fsize - size_adjust ;
116
+ if (caller.is_interpreted_frame () && size_adjust == 0 ) {
111
117
// If the caller is interpreted, our stackargs are not supposed to overlap with it
112
118
// so we make more room by moving sp down by argsize
113
119
int argsize = FKind::stack_argsize (f);
@@ -180,11 +186,12 @@ inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) {
180
186
: (intptr_t )hf.fp ();
181
187
}
182
188
183
- inline void FreezeBase::patch_pd (frame& hf, const frame& caller) {
189
+ inline void FreezeBase::patch_pd (frame& hf, const frame& caller, bool is_bottom_frame ) {
184
190
if (caller.is_interpreted_frame ()) {
185
191
assert (!caller.is_empty (), " " );
186
192
patch_callee_link_relative (caller, caller.fp ());
187
- } else {
193
+ } else if (is_bottom_frame && caller.pc () != nullptr ) {
194
+ assert (caller.is_compiled_frame (), " " );
188
195
// If we're the bottom-most frame frozen in this freeze, the caller might have stayed frozen in the chunk,
189
196
// and its oop-containing fp fixed. We've now just overwritten it, so we must patch it back to its value
190
197
// as read from the chunk.
@@ -215,7 +222,7 @@ inline frame ThawBase::new_entry_frame() {
215
222
return frame (sp, sp, _cont.entryFP (), _cont.entryPC ()); // TODO PERF: This finds code blob and computes deopt state
216
223
}
217
224
218
- template <typename FKind> frame ThawBase::new_stack_frame (const frame& hf, frame& caller, bool bottom) {
225
+ template <typename FKind> frame ThawBase::new_stack_frame (const frame& hf, frame& caller, bool bottom, int size_adjust ) {
219
226
assert (FKind::is_instance (hf), " " );
220
227
// The values in the returned frame object will be written into the callee's stack in patch.
221
228
@@ -243,24 +250,23 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
243
250
return f;
244
251
} else {
245
252
int fsize = FKind::size (hf);
246
- intptr_t * frame_sp = caller.unextended_sp () - fsize;
253
+ intptr_t * frame_sp = caller.unextended_sp () - fsize - size_adjust ;
247
254
if (bottom || caller.is_interpreted_frame ()) {
248
- int argsize = FKind::stack_argsize (hf);
249
-
250
- fsize += argsize;
251
- frame_sp -= argsize;
252
- caller.set_sp (caller.sp () - argsize);
253
- assert (caller.sp () == frame_sp + (fsize-argsize), " " );
254
-
255
+ if (size_adjust == 0 ) {
256
+ int argsize = FKind::stack_argsize (hf);
257
+ frame_sp -= argsize;
258
+ }
255
259
frame_sp = align (hf, frame_sp, caller, bottom);
256
260
}
261
+ caller.set_sp (frame_sp + fsize);
262
+ assert (is_aligned (frame_sp, frame::frame_alignment), " " );
257
263
258
264
assert (hf.cb () != nullptr , " " );
259
265
assert (hf.oop_map () != nullptr , " " );
260
266
intptr_t * fp;
261
267
if (PreserveFramePointer) {
262
268
// we need to recreate a "real" frame pointer, pointing into the stack
263
- fp = frame_sp + FKind::size (hf) - frame::sender_sp_offset;
269
+ fp = frame_sp + fsize - frame::sender_sp_offset;
264
270
} else {
265
271
fp = FKind::stub || FKind::native
266
272
? frame_sp + fsize - frame::sender_sp_offset // fp always points to the address below the pushed return pc. We need correct address.
@@ -275,16 +281,16 @@ inline intptr_t* ThawBase::align(const frame& hf, intptr_t* frame_sp, frame& cal
275
281
if (((intptr_t )frame_sp & 0xf ) != 0 ) {
276
282
assert (caller.is_interpreted_frame () || (bottom && hf.compiled_frame_stack_argsize () % 2 != 0 ), " " );
277
283
frame_sp--;
278
- caller.set_sp (caller.sp () - 1 );
279
284
}
280
285
assert (is_aligned (frame_sp, frame::frame_alignment), " " );
281
286
#endif
282
-
283
287
return frame_sp;
284
288
}
285
289
286
290
inline void ThawBase::patch_pd (frame& f, const frame& caller) {
287
- patch_callee_link (caller, caller.fp ());
291
+ if (caller.is_interpreted_frame () || PreserveFramePointer) {
292
+ patch_callee_link (caller, caller.fp ());
293
+ }
288
294
}
289
295
290
296
inline void ThawBase::patch_pd (frame& f, intptr_t * caller_sp) {
0 commit comments