Skip to content

Commit a8d16de

Browse files
fbredberreinrich
authored andcommitted
8300197: Freeze/thaw an interpreter frame using a single copy_to_chunk() call
Reviewed-by: rrich, pchilanomate, fyang
1 parent 1532a1b commit a8d16de

8 files changed

+45
-96
lines changed

src/hotspot/cpu/aarch64/continuationFreezeThaw_aarch64.inline.hpp

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
8484
if (FKind::interpreted) {
8585
assert((intptr_t*)f.at(frame::interpreter_frame_last_sp_offset) == nullptr
8686
|| f.unextended_sp() == (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset), "");
87-
int locals = f.interpreter_frame_method()->max_locals();
87+
intptr_t locals_offset = *f.addr_at(frame::interpreter_frame_locals_offset);
8888
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
8989
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
9090
bool overlap_caller = caller.is_interpreted_frame() || caller.is_empty();
91-
fp = caller.unextended_sp() - (locals + frame::sender_sp_offset) + (overlap_caller ? ContinuationHelper::InterpretedFrame::stack_argsize(f) : 0);
91+
fp = caller.unextended_sp() - 1 - locals_offset + (overlap_caller ? ContinuationHelper::InterpretedFrame::stack_argsize(f) : 0);
9292
sp = fp - (f.fp() - f.unextended_sp());
9393
assert(sp <= fp, "");
9494
assert(fp <= caller.unextended_sp(), "");
@@ -97,7 +97,8 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
9797
assert(_cont.tail()->is_in_chunk(sp), "");
9898

9999
frame hf(sp, sp, fp, f.pc(), nullptr, nullptr, true /* on_heap */);
100-
*hf.addr_at(frame::interpreter_frame_locals_offset) = frame::sender_sp_offset + locals - 1;
100+
// copy relativized locals from the stack frame
101+
*hf.addr_at(frame::interpreter_frame_locals_offset) = locals_offset;
101102
return hf;
102103
} else {
103104
// We need to re-read fp out of the frame because it may be an oop and we might have
@@ -145,13 +146,11 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
145146

146147
// on AARCH64, we may insert padding between the locals and the rest of the frame
147148
// (see TemplateInterpreterGenerator::generate_normal_entry, and AbstractInterpreter::layout_activation)
148-
// so we compute locals "from scratch" rather than relativizing the value in the stack frame, which might include padding,
149-
// since we don't freeze the padding word (see recurse_freeze_interpreted_frame).
149+
// because we freeze the padding word (see recurse_freeze_interpreted_frame) in order to keep the same relativized
150+
// locals value, we don't need to change the locals value here.
150151

151152
// at(frame::interpreter_frame_last_sp_offset) can be NULL at safepoint preempts
152153
*hf.addr_at(frame::interpreter_frame_last_sp_offset) = hf.unextended_sp() - hf.fp();
153-
// This line can be changed into an assert when we have fixed the "frame padding problem", see JDK-8300197
154-
*hf.addr_at(frame::interpreter_frame_locals_offset) = frame::sender_sp_offset + f.interpreter_frame_method()->max_locals() - 1;
155154

156155
relativize_one(vfp, hfp, frame::interpreter_frame_initial_sp_offset); // == block_top == block_bottom
157156
relativize_one(vfp, hfp, frame::interpreter_frame_extended_sp_offset);
@@ -222,11 +221,9 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
222221
const int locals = hf.interpreter_frame_method()->max_locals();
223222
intptr_t* frame_sp = caller.unextended_sp() - fsize;
224223
intptr_t* fp = frame_sp + (hf.fp() - heap_sp);
225-
int padding = 0;
226224
if ((intptr_t)fp % frame::frame_alignment != 0) {
227225
fp--;
228226
frame_sp--;
229-
padding++;
230227
log_develop_trace(continuations)("Adding internal interpreted frame alignment");
231228
}
232229
DEBUG_ONLY(intptr_t* unextended_sp = fp + *hf.addr_at(frame::interpreter_frame_last_sp_offset);)
@@ -235,10 +232,8 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
235232
frame f(frame_sp, frame_sp, fp, hf.pc());
236233
// we need to set the locals so that the caller of new_stack_frame() can call
237234
// ContinuationHelper::InterpretedFrame::frame_bottom
238-
intptr_t offset = *hf.addr_at(frame::interpreter_frame_locals_offset);
239-
assert((int)offset == frame::sender_sp_offset + locals - 1, "");
240-
// set relativized locals
241-
*f.addr_at(frame::interpreter_frame_locals_offset) = padding + offset;
235+
// copy relativized locals from the heap frame
236+
*f.addr_at(frame::interpreter_frame_locals_offset) = *hf.addr_at(frame::interpreter_frame_locals_offset);
242237
assert((intptr_t)f.fp() % frame::frame_alignment == 0, "");
243238
return f;
244239
} else {
@@ -300,10 +295,4 @@ inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, c
300295
derelativize_one(vfp, frame::interpreter_frame_extended_sp_offset);
301296
}
302297

303-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
304-
// set relativized locals
305-
// this line can be changed into an assert when we have fixed the "frame padding problem", see JDK-8300197
306-
*f.addr_at(frame::interpreter_frame_locals_offset) = (bottom - 1) - f.fp();
307-
}
308-
309298
#endif // CPU_AARCH64_CONTINUATIONFREEZETHAW_AARCH64_INLINE_HPP

src/hotspot/cpu/arm/continuationFreezeThaw_arm.inline.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
7070
return frame();
7171
}
7272

73-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
74-
Unimplemented();
75-
}
76-
7773
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
7874
Unimplemented();
7975
}

src/hotspot/cpu/ppc/continuationFreezeThaw_ppc.inline.hpp

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
8484
assert(f.fp() > (intptr_t*)f.interpreter_frame_esp(), "");
8585

8686
// There is alignment padding between vfp and f's locals array in the original
87-
// frame, therefore we cannot use it to relativize the locals pointer.
88-
// This line can be changed into an assert when we have fixed the "frame padding problem", see JDK-8300197
89-
*hf.addr_at(ijava_idx(locals)) = frame::metadata_words + f.interpreter_frame_method()->max_locals() - 1;
87+
// frame, because we freeze the padding (see recurse_freeze_interpreted_frame)
88+
// in order to keep the same relativized locals pointer, we don't need to change it here.
89+
9090
relativize_one(vfp, hfp, ijava_idx(monitors));
9191
relativize_one(vfp, hfp, ijava_idx(esp));
9292
relativize_one(vfp, hfp, ijava_idx(top_frame_sp));
@@ -264,15 +264,15 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
264264

265265
intptr_t *sp, *fp;
266266
if (FKind::interpreted) {
267-
int locals = f.interpreter_frame_method()->max_locals();
267+
intptr_t locals_offset = *f.addr_at(ijava_idx(locals));
268268
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
269269
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
270270
// See also comment on StackChunkFrameStream<frame_kind>::interpreter_frame_size()
271271
int overlap =
272272
(caller.is_interpreted_frame() || caller.is_empty())
273273
? ContinuationHelper::InterpretedFrame::stack_argsize(f) + frame::metadata_words_at_top
274274
: 0;
275-
fp = caller.unextended_sp() + overlap - locals - frame::metadata_words_at_top;
275+
fp = caller.unextended_sp() - 1 - locals_offset + overlap;
276276
// esp points one slot below the last argument
277277
intptr_t* x86_64_like_unextended_sp = f.interpreter_frame_esp() + 1 - frame::metadata_words_at_top;
278278
sp = fp - (f.fp() - x86_64_like_unextended_sp);
@@ -286,7 +286,7 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
286286

287287
frame hf(sp, sp, fp, f.pc(), nullptr, nullptr, true /* on_heap */);
288288
// frame_top() and frame_bottom() read these before relativize_interpreted_frame_metadata() is called
289-
*hf.addr_at(ijava_idx(locals)) = frame::metadata_words + locals - 1;
289+
*hf.addr_at(ijava_idx(locals)) = locals_offset;
290290
*hf.addr_at(ijava_idx(esp)) = f.interpreter_frame_esp() - f.fp();
291291
return hf;
292292
} else {
@@ -507,10 +507,8 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
507507
frame f(frame_sp, hf.pc(), frame_sp, fp);
508508
// we need to set the locals so that the caller of new_stack_frame() can call
509509
// ContinuationHelper::InterpretedFrame::frame_bottom
510-
intptr_t offset = *hf.addr_at(ijava_idx(locals)) + padding;
511-
assert((int)offset == hf.interpreter_frame_method()->max_locals() + frame::metadata_words_at_top + padding - 1, "");
512-
// set relativized locals
513-
*f.addr_at(ijava_idx(locals)) = offset;
510+
// copy relativized locals from the heap frame
511+
*f.addr_at(ijava_idx(locals)) = *hf.addr_at(ijava_idx(locals));
514512

515513
return f;
516514
} else {
@@ -549,12 +547,6 @@ inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, c
549547
derelativize_one(vfp, ijava_idx(top_frame_sp));
550548
}
551549

552-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
553-
// set relativized locals
554-
// This line can be changed into an assert when we have fixed the "frame padding problem", see JDK-8300197
555-
*f.addr_at(ijava_idx(locals)) = (bottom - 1) - f.fp();
556-
}
557-
558550
inline void ThawBase::patch_pd(frame& f, const frame& caller) {
559551
patch_callee_link(caller, caller.fp());
560552
// Prevent assertion if f gets deoptimized right away before it's fully initialized

src/hotspot/cpu/riscv/continuationFreezeThaw_riscv.inline.hpp

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ template<typename FKind> frame FreezeBase::new_heap_frame(frame& f, frame& calle
8383
if (FKind::interpreted) {
8484
assert((intptr_t*)f.at(frame::interpreter_frame_last_sp_offset) == nullptr
8585
|| f.unextended_sp() == (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset), "");
86-
int locals = f.interpreter_frame_method()->max_locals();
86+
intptr_t locals_offset = *f.addr_at(frame::interpreter_frame_locals_offset);
8787
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
8888
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
8989
bool overlap_caller = caller.is_interpreted_frame() || caller.is_empty();
90-
fp = caller.unextended_sp() - (locals + frame::sender_sp_offset) + (overlap_caller ? ContinuationHelper::InterpretedFrame::stack_argsize(f) : 0);
90+
fp = caller.unextended_sp() - 1 - locals_offset + (overlap_caller ? ContinuationHelper::InterpretedFrame::stack_argsize(f) : 0);
9191
sp = fp - (f.fp() - f.unextended_sp());
9292
assert(sp <= fp, "");
9393
assert(fp <= caller.unextended_sp(), "");
@@ -96,7 +96,7 @@ template<typename FKind> frame FreezeBase::new_heap_frame(frame& f, frame& calle
9696
assert(_cont.tail()->is_in_chunk(sp), "");
9797

9898
frame hf(sp, sp, fp, f.pc(), nullptr, nullptr, true /* on_heap */);
99-
*hf.addr_at(frame::interpreter_frame_locals_offset) = frame::sender_sp_offset + locals - 1;
99+
*hf.addr_at(frame::interpreter_frame_locals_offset) = locals_offset;
100100
return hf;
101101
} else {
102102
// We need to re-read fp out of the frame because it may be an oop and we might have
@@ -144,13 +144,11 @@ inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, co
144144

145145
// On RISCV, we may insert padding between the locals and the rest of the frame
146146
// (see TemplateInterpreterGenerator::generate_normal_entry, and AbstractInterpreter::layout_activation)
147-
// so we compute locals "from scratch" rather than relativizing the value in the stack frame, which might include padding,
148-
// since we don't freeze the padding word (see recurse_freeze_interpreted_frame).
147+
// because we freeze the padding word (see recurse_freeze_interpreted_frame) in order to keep the same relativized
148+
// locals value, we don't need to change the locals value here.
149149

150150
// at(frame::interpreter_frame_last_sp_offset) can be null at safepoint preempts
151151
*hf.addr_at(frame::interpreter_frame_last_sp_offset) = hf.unextended_sp() - hf.fp();
152-
// this line can be changed into an assert when we have fixed the "frame padding problem", see JDK-8300197
153-
*hf.addr_at(frame::interpreter_frame_locals_offset) = frame::sender_sp_offset + f.interpreter_frame_method()->max_locals() - 1;
154152

155153
relativize_one(vfp, hfp, frame::interpreter_frame_initial_sp_offset); // == block_top == block_bottom
156154
relativize_one(vfp, hfp, frame::interpreter_frame_extended_sp_offset);
@@ -225,11 +223,9 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
225223
const int locals = hf.interpreter_frame_method()->max_locals();
226224
intptr_t* frame_sp = caller.unextended_sp() - fsize;
227225
intptr_t* fp = frame_sp + (hf.fp() - heap_sp);
228-
int padding = 0;
229226
if ((intptr_t)fp % frame::frame_alignment != 0) {
230227
fp--;
231228
frame_sp--;
232-
padding++;
233229
log_develop_trace(continuations)("Adding internal interpreted frame alignment");
234230
}
235231
DEBUG_ONLY(intptr_t* unextended_sp = fp + *hf.addr_at(frame::interpreter_frame_last_sp_offset);)
@@ -238,10 +234,8 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
238234
frame f(frame_sp, frame_sp, fp, hf.pc());
239235
// we need to set the locals so that the caller of new_stack_frame() can call
240236
// ContinuationHelper::InterpretedFrame::frame_bottom
241-
intptr_t offset = *hf.addr_at(frame::interpreter_frame_locals_offset);
242-
assert((int)offset == frame::sender_sp_offset + locals - 1, "");
243-
// set relativized locals
244-
*f.addr_at(frame::interpreter_frame_locals_offset) = padding + offset;
237+
// copy relativized locals from the heap frame
238+
*f.addr_at(frame::interpreter_frame_locals_offset) = *hf.addr_at(frame::interpreter_frame_locals_offset);
245239
assert((intptr_t)f.fp() % frame::frame_alignment == 0, "");
246240
return f;
247241
} else {
@@ -303,10 +297,4 @@ inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, c
303297
derelativize_one(vfp, frame::interpreter_frame_extended_sp_offset);
304298
}
305299

306-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
307-
// set relativized locals
308-
// This line can be changed into an assert when we have fixed the "frame padding problem", see JDK-8300197
309-
*f.addr_at(frame::interpreter_frame_locals_offset) = (bottom - 1) - f.fp();
310-
}
311-
312300
#endif // CPU_RISCV_CONTINUATIONFREEZETHAW_RISCV_INLINE_HPP

src/hotspot/cpu/s390/continuationFreezeThaw_s390.inline.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
7070
return frame();
7171
}
7272

73-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
74-
Unimplemented();
75-
}
76-
7773
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
7874
Unimplemented();
7975
}

src/hotspot/cpu/x86/continuationFreezeThaw_x86.inline.hpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
8181
if (FKind::interpreted) {
8282
assert((intptr_t*)f.at(frame::interpreter_frame_last_sp_offset) == nullptr
8383
|| f.unextended_sp() == (intptr_t*)f.at(frame::interpreter_frame_last_sp_offset), "");
84-
int locals = f.interpreter_frame_method()->max_locals();
84+
intptr_t locals_offset = *f.addr_at(frame::interpreter_frame_locals_offset);
8585
// If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
8686
// the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
8787
bool overlap_caller = caller.is_interpreted_frame() || caller.is_empty();
88-
fp = caller.unextended_sp() - (locals + frame::sender_sp_offset) + (overlap_caller ? ContinuationHelper::InterpretedFrame::stack_argsize(f) : 0);
88+
fp = caller.unextended_sp() - 1 - locals_offset + (overlap_caller ? ContinuationHelper::InterpretedFrame::stack_argsize(f) : 0);
8989
sp = fp - (f.fp() - f.unextended_sp());
9090
assert(sp <= fp, "");
9191
assert(fp <= caller.unextended_sp(), "");
@@ -94,7 +94,8 @@ frame FreezeBase::new_heap_frame(frame& f, frame& caller) {
9494
assert(_cont.tail()->is_in_chunk(sp), "");
9595

9696
frame hf(sp, sp, fp, f.pc(), nullptr, nullptr, true /* on_heap */);
97-
*hf.addr_at(frame::interpreter_frame_locals_offset) = frame::sender_sp_offset + locals - 1;
97+
// copy relativized locals from the stack frame
98+
*hf.addr_at(frame::interpreter_frame_locals_offset) = locals_offset;
9899
return hf;
99100
} else {
100101
// We need to re-read fp out of the frame because it may be an oop and we might have
@@ -223,10 +224,10 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
223224
frame f(frame_sp, frame_sp, fp, hf.pc());
224225
// we need to set the locals so that the caller of new_stack_frame() can call
225226
// ContinuationHelper::InterpretedFrame::frame_bottom
226-
intptr_t offset = *hf.addr_at(frame::interpreter_frame_locals_offset);
227-
assert((int)offset == frame::sender_sp_offset + locals - 1, "");
228-
// set relativized locals
229-
*f.addr_at(frame::interpreter_frame_locals_offset) = offset;
227+
intptr_t locals_offset = *hf.addr_at(frame::interpreter_frame_locals_offset);
228+
assert((int)locals_offset == frame::sender_sp_offset + locals - 1, "");
229+
// copy relativized locals from the heap frame
230+
*f.addr_at(frame::interpreter_frame_locals_offset) = locals_offset;
230231
return f;
231232
} else {
232233
int fsize = FKind::size(hf);
@@ -285,8 +286,4 @@ inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, c
285286
derelativize_one(vfp, frame::interpreter_frame_initial_sp_offset);
286287
}
287288

288-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
289-
// Nothing to do. Just make sure the relativized locals is already set.
290-
assert((*f.addr_at(frame::interpreter_frame_locals_offset) == (bottom - 1) - f.fp()), "");
291-
}
292289
#endif // CPU_X86_CONTINUATIONFREEZE_THAW_X86_INLINE_HPP

src/hotspot/cpu/zero/continuationFreezeThaw_zero.inline.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame&
7070
return frame();
7171
}
7272

73-
inline void ThawBase::set_interpreter_frame_bottom(const frame& f, intptr_t* bottom) {
74-
Unimplemented();
75-
}
76-
7773
inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
7874
Unimplemented();
7975
}

0 commit comments

Comments
 (0)