1 /*
2 * Copyright (c) 2019, 2026, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2026 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26 #ifndef CPU_PPC_CONTINUATION_PPC_INLINE_HPP
27 #define CPU_PPC_CONTINUATION_PPC_INLINE_HPP
28
29 #include "oops/stackChunkOop.inline.hpp"
30 #include "runtime/frame.hpp"
31 #include "runtime/frame.inline.hpp"
32
33 inline void patch_callee_link(const frame& f, intptr_t* fp) {
34 *ContinuationHelper::Frame::callee_link_address(f) = fp;
35 }
36
37 inline void patch_callee_link_relative(const frame& f, intptr_t* fp) {
38 intptr_t* la = (intptr_t*)ContinuationHelper::Frame::callee_link_address(f);
39 intptr_t new_value = fp - la;
40 *la = new_value;
41 }
42
43 ////// Freeze
44
45 // Fast path
46
47 inline void FreezeBase::patch_stack_pd(intptr_t* frame_sp, intptr_t* heap_sp) {
48 // Nothing to do. The backchain is reconstructed when thawing (see Thaw<ConfigT>::patch_caller_links())
49 }
50
51 // Slow path
52
53 template<typename FKind>
54 inline frame FreezeBase::sender(const frame& f) {
55 assert(FKind::is_instance(f), "");
56 if (FKind::interpreted) {
57 return frame(f.sender_sp(), f.sender_pc(), f.interpreter_frame_sender_sp());
58 }
59
60 assert(f.cb() == nullptr || !f.cb()->is_nmethod() || !f.cb()->as_nmethod()->needs_stack_repair(),
61 "unsupported");
62
63 intptr_t* sender_sp = f.sender_sp();
64 address sender_pc = f.sender_pc();
65 assert(sender_sp != f.sp(), "must have changed");
66
67 int slot = 0;
68 CodeBlob* sender_cb = CodeCache::find_blob_and_oopmap(sender_pc, slot);
69 return sender_cb != nullptr
70 ? frame(sender_sp, sender_sp, nullptr, sender_pc, sender_cb, slot == -1 ? nullptr : sender_cb->oop_map_for_slot(slot, sender_pc))
71 : frame(sender_sp, sender_pc, sender_sp);
72 }
73
74 void FreezeBase::adjust_interpreted_frame_unextended_sp(frame& f) {
75 // nothing to do
76 }
77
78 inline void FreezeBase::prepare_freeze_interpreted_top_frame(frame& f) {
79 // Nothing to do. We don't save a last sp since we cannot use sp as esp.
80 // Instead the top frame is trimmed when making an i2i call. The original
81 // top_frame_sp is set when the frame is pushed (see generate_fixed_frame()).
82 // An interpreter top frame that was just thawed is resized to top_frame_sp by the
83 // resume adapter (see generate_cont_resume_interpreter_adapter()). So the assertion is
84 // false, if we freeze again right after thawing as we do when redoing a vm call wasn't
85 // successful.
86 assert(_thread->interp_redoing_vm_call() ||
87 ((intptr_t*)f.at_relative(ijava_idx(top_frame_sp)) == f.unextended_sp()),
88 "top_frame_sp:" PTR_FORMAT " usp:" PTR_FORMAT, f.at_relative(ijava_idx(top_frame_sp)), p2i(f.unextended_sp()));
89 }
90
91 inline void FreezeBase::relativize_interpreted_frame_metadata(const frame& f, const frame& hf) {
92 intptr_t* vfp = f.fp();
93 intptr_t* hfp = hf.fp();
94 assert(f.fp() > (intptr_t*)f.interpreter_frame_esp(), "");
95
96 // There is alignment padding between vfp and f's locals array in the original
97 // frame, because we freeze the padding (see recurse_freeze_interpreted_frame)
98 // in order to keep the same relativized locals pointer, we don't need to change it here.
99
100 // Make sure that monitors is already relativized.
101 assert(hf.at_absolute(ijava_idx(monitors)) <= -(frame::ijava_state_size / wordSize), "");
102
103 // Make sure that esp is already relativized.
104 assert(hf.at_absolute(ijava_idx(esp)) <= hf.at_absolute(ijava_idx(monitors)), "");
105
106 // top_frame_sp is already relativized
107
108 // hfp == hf.sp() + (f.fp() - f.sp()) is not true on ppc because the stack frame has room for
109 // the maximal expression stack and the expression stack in the heap frame is trimmed.
110 assert(hf.fp() == hf.interpreter_frame_esp() + (f.fp() - f.interpreter_frame_esp()), "");
111 assert(hf.fp() <= (intptr_t*)hf.at(ijava_idx(locals)), "");
112 }
113
114 inline void FreezeBase::set_top_frame_metadata_pd(const frame& hf) {
115 stackChunkOop chunk = _cont.tail();
116 assert(chunk->is_in_chunk(hf.sp()), "hf.sp()=" PTR_FORMAT, p2i(hf.sp()));
117
118 hf.own_abi()->lr = (uint64_t)hf.pc();
119 if (hf.is_interpreted_frame()) {
120 patch_callee_link_relative(hf, hf.fp());
121 }
122 #ifdef ASSERT
123 else {
124 // See also FreezeBase::patch_pd()
125 patch_callee_link(hf, (intptr_t*)badAddress);
126 }
127 #endif
128 }
129
130 //
131 // Heap frames differ from stack frames in the following aspects
132 //
133 // - they are just word aligned
134 // - the unextended sp of interpreted frames is set such that
135 // unextended sp + frame::metadata_words_at_top + 1 points to the last call parameter
136 // (the comment at the file end explains the unextended sp for interpreted frames on the stack)
137 //
138 // The difference in respect to the unextended sp is required to comply with shared code.
139 // Furthermore fast frozen and compiled frames have invalid back links (see
140 // Thaw<ConfigT>::patch_caller_links() and FreezeBase::patch_pd())
141 //
142 // === New Interpreted Frame ==========================================================================================
143 //
144 // ### Interpreted Caller: Overlap new frame with Caller
145 //
146 // Caller on entry New frame with resized Caller
147 //
148 // | frame::java_abi | | |
149 // | |<- FP of caller | Caller's SP |<- FP of caller
150 // ========================== ==========================
151 // | ijava_state | | ijava_state |
152 // | | | |
153 // |------------------------| ----- |------------------------|
154 // | P0 | ^ | L0 aka P0 |
155 // | : | | | : : |
156 // | Pn |<- unext. SP | | : Pn |<- unext. SP
157 // |------------------------| + metadata overlap | : | + metadata
158 // | frame::java_abi | | | Lm |
159 // | (metadata_words_at_top)|<- SP == unext. SP v |------------------------|<- unextended SP of caller (1)
160 // ========================== of caller ----- | frame::java_abi |
161 // | (metadata_words_at_top)|<- new SP of caller / FP of new frame
162 // overlap = stack_argsize(f) ========================== ^
163 // + frame::metadata_words_at_top | ijava_state | |
164 // | | |
165 // Where f is the frame to be relocated on the heap. |------------------------| |
166 // See also StackChunkFrameStream::frame_size(). | Expressions | FP - esp of f
167 // | P0 | |
168 // | : | |
169 // | Growth | | Pi | v
170 // v v |------------------------| ---
171 // | frame::java_abi |
172 // | (metadata_words_at_top)|<- unextended SP /
173 // ========================== SP of new frame
174 // ### Compiled Caller: No Overlap
175 //
176 // The caller is resized to accomodate the callee's locals and abi but there is _no_ overlap with
177 // the original caller frame.
178 //
179 // Caller on entry New frame with resized Caller
180 //
181 // | frame::java_abi | | |
182 // | (metadata_words_at_top)|<- FP of caller | Caller's SP |<- FP of caller
183 // ========================== ==========================
184 // | | | |
185 // | | | |
186 // |------------------------| |------------------------|
187 // | frame::java_abi | | frame::java_abi |
188 // | (metadata_words_at_top)|<- SP == unext. SP | (metadata_words_at_top)|<- unext. SP of caller
189 // ========================== of caller |------------------------|
190 // | L0 aka P0 |
191 // | : : |
192 // | : Pn |
193 // overlap = 0 | Lm |
194 // |------------------------|
195 // f is the frame to be relocated on the heap | frame::java_abi |
196 // | (metadata_words_at_top)|<- new SP of caller / FP of new frame
197 // ========================== ^
198 // | ijava_state | |
199 // | Growth | | | |
200 // v v |------------------------| |
201 // | Expressions | FP - esp of f
202 // | P0 | |
203 // | : | |
204 // | Pi | v
205 // |------------------------| ---
206 // | frame::java_abi |
207 // | (metadata_words_at_top)|<- unextended SP /
208 // ========================== SP of new frame
209 //
210 // (1) Caller's unextended SP is preserved in callee's frame::ijava_state::sender_sp
211 // (See ContinuationHelper::InterpretedFrame::patch_sender_sp). This is required
212 // by StackChunkFrameStream<frame_kind>::next_for_interpreter_frame().
213 //
214 // === New Compiled Frame =============================================================================================
215 //
216 // ### Interpreted Caller: No Overlap
217 //
218 // The caller is resized to accomodate the callee's stack arguments and abi but there is _no_ overlap with
219 // the original caller frame.
220 //
221 // Note: a new ABI is added to the caller even if there are no stackargs.
222 // This is necessary to comply with shared code.
223 //
224 // Caller on entry New frame with resized Caller
225 //
226 // | frame::java_abi | | frame::java_abi |
227 // | (metadata_words_at_top)|<- FP of caller | (metadata_words_at_top)|<- FP of caller
228 // ========================== ==========================
229 // | ijava_state | | ijava_state |
230 // | | | |
231 // |------------------------| |------------------------|
232 // | P0 | | P0 |
233 // | : | | : |
234 // | Pn |<- unext. SP | Pn |<- unext. SP
235 // |------------------------| + metadata |------------------------| + metadata
236 // | frame::java_abi | | frame::java_abi |
237 // | (metadata_words_at_top)|<- SP == unext. SP | (metadata_words_at_top)|<- unextended SP of caller (1)
238 // ========================== of caller |------------------------|
239 // | Stack Args |
240 // overlap = 0 | (if any) |
241 // |------------------------|
242 // f is the frame to be relocated on the heap | frame::java_abi |
243 // | (metadata_words_at_top)|<- new SP of caller / FP of new frame
244 // ==========================
245 // | |
246 // | Growth | | |
247 // v v |------------------------|
248 // | frame::java_abi |
249 // | (metadata_words_at_top)|<- SP == unext. SP of new frame
250 // ==========================
251 //
252 // ### Compiled Caller: Stackargs + ABI Overlap
253 //
254 // Caller on entry New frame with resized Caller
255 //
256 // | frame::java_abi | | frame::java_abi |
257 // | (metadata_words_at_top)|<- FP of caller | (metadata_words_at_top)|<- FP of caller
258 // ========================== ==========================
259 // | | | |
260 // | | | |
261 // |------------------------| ----- |------------------------|
262 // | Stack Args | ^ | Stack Args |
263 // | (if any) | | | (if any) |
264 // |------------------------| overlap |------------------------|
265 // | frame::java_abi | | | frame::java_abi |
266 // | (metadata_words_at_top)|<- SP == unext. SP v | (metadata_words_at_top)|<- SP == unext. SP of caller
267 // ========================== of caller ----- ========================== / FP of new frame
268 // | |
269 // overlap = stack_argsize(f) | |
270 // + frame::metadata_words_at_top |------------------------|
271 // | frame::java_abi |
272 // Where f is the frame to be relocated on the heap. | (metadata_words_at_top)|<- SP == unext. SP of new frame
273 // See also StackChunkFrameStream::frame_size(). ==========================
274 //
275 template<typename FKind>
276 frame FreezeBase::new_heap_frame(frame& f, frame& caller, int size_adjust) {
277 assert(size_adjust == 0, "unsupported");
278 assert(FKind::is_instance(f), "");
279
280 intptr_t *sp, *fp;
281 if (FKind::interpreted) {
282 intptr_t locals_offset = *f.addr_at(ijava_idx(locals));
283 // If the caller.is_empty(), i.e. we're freezing into an empty chunk, then we set
284 // the chunk's argsize in finalize_freeze and make room for it above the unextended_sp
285 // See also comment on StackChunkFrameStream<frame_kind>::interpreter_frame_size()
286 int overlap =
287 (caller.is_interpreted_frame() || caller.is_empty())
288 ? ContinuationHelper::InterpretedFrame::stack_argsize(f) + frame::metadata_words_at_top
289 : 0;
290 fp = caller.unextended_sp() - 1 - locals_offset + overlap;
291 // esp points one slot below the last argument
292 intptr_t* x86_64_like_unextended_sp = f.interpreter_frame_esp() + 1 - frame::metadata_words_at_top;
293 sp = fp - (f.fp() - x86_64_like_unextended_sp);
294
295 assert (sp <= fp && (fp <= caller.unextended_sp() || caller.is_interpreted_frame()),
296 "sp=" PTR_FORMAT " fp=" PTR_FORMAT " caller.unextended_sp()=" PTR_FORMAT " caller.is_interpreted_frame()=%d",
297 p2i(sp), p2i(fp), p2i(caller.unextended_sp()), caller.is_interpreted_frame());
298 caller.set_sp(fp);
299
300 assert(_cont.tail()->is_in_chunk(sp), "");
301
302 frame hf(sp, sp, fp, f.pc(), nullptr, nullptr, true /* on_heap */);
303 // frame_top() and frame_bottom() read these before relativize_interpreted_frame_metadata() is called
304 *hf.addr_at(ijava_idx(locals)) = locals_offset;
305 *hf.addr_at(ijava_idx(esp)) = f.interpreter_frame_esp() - f.fp();
306 return hf;
307 } else {
308 int fsize = FKind::size(f);
309 sp = caller.unextended_sp() - fsize;
310 if (caller.is_interpreted_frame()) {
311 // If the caller is interpreted, our stackargs are not supposed to overlap with it
312 // so we make more room by moving sp down by argsize
313 int argsize = FKind::stack_argsize(f);
314 sp -= argsize + frame::metadata_words_at_top;
315 }
316 fp = sp + fsize;
317 caller.set_sp(fp);
318
319 assert(_cont.tail()->is_in_chunk(sp), "");
320
321 return frame(sp, sp, fp, f.pc(), nullptr, nullptr, true /* on_heap */);
322 }
323 }
324
325 inline void FreezeBase::patch_pd(frame& hf, const frame& caller, bool is_bottom_frame) {
326 if (caller.is_interpreted_frame()) {
327 assert(!caller.is_empty(), "");
328 patch_callee_link_relative(caller, caller.fp());
329 }
330 #ifdef ASSERT
331 else {
332 // For compiled frames the back link is actually redundant. It gets computed
333 // as unextended_sp + frame_size.
334
335 // Note the difference on x86_64: the link is not made relative if the caller
336 // is a compiled frame because there rbp is used as a non-volatile register by
337 // c1/c2 so it could be a computed value local to the caller.
338
339 // See also:
340 // - FreezeBase::set_top_frame_metadata_pd
341 // - StackChunkFrameStream<frame_kind>::fp()
342 // - UseContinuationFastPath: compiled frames are copied in a batch w/o patching the back link.
343 // The backlinks are restored when thawing (see Thaw<ConfigT>::patch_caller_links())
344 patch_callee_link(hf, (intptr_t*)badAddress);
345 }
346 #endif
347 }
348
349 inline void FreezeBase::patch_pd_unused(intptr_t* sp) {
350 }
351
352 inline intptr_t* AnchorMark::anchor_mark_set_pd() {
353 // Nothing to do on PPC because the interpreter does not use SP as expression stack pointer.
354 // Instead there is a dedicated register R15_esp which is not affected by VM calls.
355 return _top_frame.sp();
356 }
357
358 inline void AnchorMark::anchor_mark_clear_pd() {
359 }
360
361 //////// Thaw
362
363 // Fast path
364
365 inline void ThawBase::prefetch_chunk_pd(void* start, int size) {
366 size <<= LogBytesPerWord;
367 Prefetch::read(start, size);
368 Prefetch::read(start, size - 64);
369 }
370
371 // Set back chain links of fast thawed frames such that *sp == callers_sp.
372 // See https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#STACK
373 template <typename ConfigT>
374 inline void Thaw<ConfigT>::patch_caller_links(intptr_t* sp, intptr_t* bottom) {
375 for (intptr_t* callers_sp; sp < bottom; sp = callers_sp) {
376 address pc = (address)((frame::java_abi*) sp)->lr;
377 assert(pc != nullptr, "");
378 // see ThawBase::patch_return() which gets called just before
379 bool is_entry_frame = pc == StubRoutines::cont_returnBarrier() || pc == _cont.entryPC();
380 if (is_entry_frame) {
381 callers_sp = _cont.entryFP();
382 } else {
383 assert(!Interpreter::contains(pc), "sp:" PTR_FORMAT " pc:" PTR_FORMAT, p2i(sp), p2i(pc));
384 CodeBlob* cb = CodeCache::find_blob_fast(pc);
385 callers_sp = sp + cb->frame_size();
386 }
387 // set the back link
388 ((frame::java_abi*) sp)->callers_sp = (intptr_t) callers_sp;
389 }
390 }
391
392 // Slow path
393
394 inline frame ThawBase::new_entry_frame() {
395 intptr_t* sp = _cont.entrySP();
396 return frame(sp, _cont.entryPC(), sp, _cont.entryFP());
397 }
398
399 // === New Interpreted Frame ================================================================================================================
400 //
401 // ### Non-Interpreted Caller (compiled, enterSpecial): No Overlap
402 //
403 // Heap Frame `hf` `hf` gets copied to stack _without_ overlapping the caller
404 //
405 // | | Non-Interpreted | |
406 // | |<- bottom Caller |----------------------|
407 // |----------------------| ^ | frame::java_abi |<- unextended SP
408 // | L0 aka P0 | | --- ========================
409 // | : : | | ^ | L0 aka P0 |
410 // | : Pn | | | | : : | Parameters do
411 // | : | | | | : Pn | not overlap with
412 // | Lm | | | | : | caller!
413 // |----------------------| `fsize` | | : |
414 // | frame::java_abi | | | : |
415 // ======================== | `fsize` + padding | Lm |
416 // | | | |----------------------|
417 // | ijava_state | | | | Opt. Align. Padding |
418 // | | | | |----------------------|
419 // |----------------------| | | | frame::java_abi |<- new SP of caller
420 // | L0 aka P0 | | | ======================== / FP of new frame
421 // | : : | | | | | (aligned)
422 // | : Pn |<- unext. SP + metadata | | ijava_state |
423 // | : | | | | |
424 // | Lm | | | |----------------------|
425 // |----------------------| v | | P0 |
426 // | frame::java_abi |<- SP / unextended SP | | : |
427 // ======================== | | Pi |<- unextended SP + metadata
428 // | |----------------------|
429 // | Growth | v | frame::java_abi |<- unextended SP / SP of new frame
430 // v v --- ======================== (not yet aligned(1))
431 //
432 //
433 // ### Interpreted Caller: Overlap with Caller
434 //
435 // Caller New frame with resized/aligned Caller
436 //
437 // | | | |
438 // | ijava_state | | ijava_state |
439 // |----------------------| |----------------------|
440 // | non param. expr. | bottom | non param. expr. |
441 // | - - - - - - - - - - | --- ^ | - - - - - - - - - - |
442 // | P0 | ^ | | L0 aka P0 |
443 // | : | | | | : : |
444 // | Pn |<- unextended SP overlap | | : Pn |<- unextended SP
445 // |----------------------| + metadata_words_at_top | | | : | + metadata_words_at_top
446 // | frame::java_abi |<- unextended SP v | | : | (unaligned)
447 // ======================== / SP of new frame --- | | : | of caller
448 // (not yet aligned(1)) | | Lm |
449 // `fsize` |----------------------|
450 // overlap = stack_argsize(hf) + padding| Opt. Align. Padding |
451 // + frame::metadata_words_at_top | |----------------------|
452 // | | frame::java_abi |<- new SP of caller
453 // | ======================== / FP of new frame
454 // | | | (aligned)
455 // | Growth | | | ijava_state |
456 // v v | | |
457 // | |----------------------|
458 // | | P0 |
459 // | | : |
460 // | | Pi |<- unextended SP
461 // | |----------------------| + metadata_words_at_top
462 // v | frame::java_abi |<- unextended SP / SP of new frame
463 // --- ======================== (not yet aligned(1))
464 //
465 //
466 // (1) The SP / unextended SP of the new interpreted frame is not aligned. It
467 // gets aligned when its callee is pushed on stack or in finish_thaw() if
468 // it is the top frame. This allows addressing parameters: unextended SP + metadata_words_at_top
469 //
470 // (2) If caller is interpreted then its ijava_state::top_frame_sp will be used as sender sp
471 // of the new frame (see ContinuationHelper::InterpretedFrame::patch_sender_sp() and diagram at the end of this file)
472 //
473 // (3) The size of alignment padding required when thawing frames is accounted for
474 // in FreezeBase::_align_size.
475 //
476 // === New Compiled Frame ===================================================================================================================
477 //
478 // Compiled Caller Interpreted Caller
479 //
480 // - stackargs+abi overlap with caller - gets resized for stackargs
481 // - no alignment padding - SP gets aligned
482 // - no overlap with orig.
483 // caller
484 // O C
485 // r a | | | |
486 // i l | | | |
487 // g l |----------------------| | |
488 // i e | Stack Args | | |
489 // n r | (if any) | |----------------------|
490 // a |----------------------| | frame::java_abi |
491 // l | frame::java_abi |<- unext. SP / SP | (unused) |<- unal.unext.SP
492 // - - - ======================== - - - - - - - - - - |----------------------|- - - - - - - - - - - - - - - - - - - - - - - - - - - -
493 // N | | | Opt. Align. Padding |
494 // e | | |----------------------|
495 // w |----------------------| | Stack Args |
496 // | frame::java_abi |<- unext. SP / SP | (if any) |
497 // F ======================== |----------------------|
498 // r | frame::java_abi |<- caller's SP
499 // a ======================== / new frame's FP
500 // m | | (aligned)
501 // e | |
502 // |----------------------|
503 // | frame::java_abi |<- unext. SP / SP
504 // ========================
505 //
506 // If the new frame is at the bottom just above the ContinuationEntry frame then the stackargs
507 // don't overlap the caller either even though it is compiled because the size is not
508 // limited/known. In contrast to the interpreted caller case the abi overlaps with the caller
509 // if there are no stackargs. This is to comply with shared code (see e.g. StackChunkFrameStream::frame_size())
510 //
511 template<typename FKind> frame ThawBase::new_stack_frame(const frame& hf, frame& caller, bool bottom, int size_adjust) {
512 assert(size_adjust == 0, "unsupported");
513 assert(FKind::is_instance(hf), "");
514
515 assert(is_aligned(caller.fp(), frame::frame_alignment), PTR_FORMAT, p2i(caller.fp()));
516 // caller.sp() can be unaligned. This is fixed below.
517 if (FKind::interpreted) {
518 // Note: we have to overlap with the caller, at least if it is interpreted, to match the
519 // max_thawing_size calculation during freeze. See also comment above.
520 intptr_t* heap_sp = hf.unextended_sp();
521 const int fsize = ContinuationHelper::InterpretedFrame::frame_bottom(hf) - hf.unextended_sp();
522 const int overlap = !caller.is_interpreted_frame() ? 0
523 : ContinuationHelper::InterpretedFrame::stack_argsize(hf) + frame::metadata_words_at_top;
524 intptr_t* frame_sp = caller.unextended_sp() + overlap - fsize;
525 intptr_t* fp = frame_sp + (hf.fp() - heap_sp);
526 // align fp
527 int padding = fp - align_down(fp, frame::frame_alignment);
528 fp -= padding;
529 // alignment of sp is done by callee or in finish_thaw()
530 frame_sp -= padding;
531
532 // On ppc esp points to the next free slot on the expression stack and sp + metadata points to the last parameter
533 DEBUG_ONLY(intptr_t* esp = fp + *hf.addr_at(ijava_idx(esp));)
534 assert(frame_sp + frame::metadata_words_at_top == esp+1, " frame_sp=" PTR_FORMAT " esp=" PTR_FORMAT, p2i(frame_sp), p2i(esp));
535 caller.set_sp(fp);
536 frame f(frame_sp, hf.pc(), frame_sp, fp);
537 // we need to set the locals so that the caller of new_stack_frame() can call
538 // ContinuationHelper::InterpretedFrame::frame_bottom
539 // copy relativized locals from the heap frame
540 *f.addr_at(ijava_idx(locals)) = *hf.addr_at(ijava_idx(locals));
541
542 return f;
543 } else {
544 int fsize = FKind::size(hf);
545 int argsize = FKind::stack_argsize(hf);
546 intptr_t* frame_sp = caller.sp() - fsize;
547
548 if ((bottom && argsize > 0) || caller.is_interpreted_frame()) {
549 assert(!_should_patch_caller_pc, "");
550 _should_patch_caller_pc = caller.is_interpreted_frame();
551 frame_sp -= argsize + frame::metadata_words_at_top;
552 frame_sp = align_down(frame_sp, frame::alignment_in_bytes);
553 caller.set_sp(frame_sp + fsize);
554 }
555
556 assert(hf.cb() != nullptr, "");
557 assert(hf.oop_map() != nullptr, "");
558 intptr_t* fp = frame_sp + fsize;
559 return frame(frame_sp, frame_sp, fp, hf.pc(), hf.cb(), hf.oop_map(), false);
560 }
561 }
562
563 inline intptr_t* ThawBase::align(const frame& hf, intptr_t* frame_sp, frame& caller, bool bottom) {
564 // Unused. Alignment is done directly in new_stack_frame() / finish_thaw().
565 return nullptr;
566 }
567
568 inline void ThawBase::derelativize_interpreted_frame_metadata(const frame& hf, const frame& f) {
569 intptr_t* vfp = f.fp();
570
571 // Make sure that monitors is still relativized.
572 assert(f.at_absolute(ijava_idx(monitors)) <= -(frame::ijava_state_size / wordSize), "");
573
574 // Make sure that esp is still relativized.
575 assert(f.at_absolute(ijava_idx(esp)) <= f.at_absolute(ijava_idx(monitors)), "");
576
577 // Keep top_frame_sp relativized.
578 }
579
580 inline intptr_t* ThawBase::push_cleanup_continuation() {
581 frame enterSpecial = new_entry_frame();
582 frame::common_abi* enterSpecial_abi = (frame::common_abi*)enterSpecial.sp();
583
584 enterSpecial_abi->lr = (intptr_t)ContinuationEntry::cleanup_pc();
585
586 log_develop_trace(continuations, preempt)("push_cleanup_continuation enterSpecial sp: " INTPTR_FORMAT " cleanup pc: " INTPTR_FORMAT,
587 p2i(enterSpecial_abi),
588 p2i(ContinuationEntry::cleanup_pc()));
589
590 return enterSpecial.sp();
591 }
592
593 inline intptr_t* ThawBase::push_preempt_adapter() {
594 frame enterSpecial = new_entry_frame();
595 frame::common_abi* enterSpecial_abi = (frame::common_abi*)enterSpecial.sp();
596
597 enterSpecial_abi->lr = (intptr_t)StubRoutines::cont_preempt_stub();
598
599 log_develop_trace(continuations, preempt)("push_preempt_adapter enterSpecial sp: " INTPTR_FORMAT " adapter pc: " INTPTR_FORMAT,
600 p2i(enterSpecial_abi),
601 p2i(StubRoutines::cont_preempt_stub()));
602
603 return enterSpecial.sp();
604 }
605
606 inline void ThawBase::patch_pd(frame& f, const frame& caller) {
607 patch_callee_link(caller, caller.fp());
608 // Prevent assertion if f gets deoptimized right away before it's fully initialized
609 f.mark_not_fully_initialized();
610 }
611
612 inline void ThawBase::patch_pd(frame& f, intptr_t* caller_sp) {
613 assert(f.own_abi()->callers_sp == (uint64_t)caller_sp, "should have been fixed by patch_caller_links");
614 }
615
616 //
617 // Interpreter Calling Procedure on PPC
618 //
619 // Caller Resized Caller before the Call New Callee Frame
620 //
621 // - SP/FP are 16 byte aligned. - The unused part of the expression stack - The caller's original SP is passed as
622 // Padding is added as necessary. is removed sender SP (in R21_sender_SP) also by
623 // - SP is _not_ used as esp - Slots for the callee's nonparameter locals compiled callers. It is saved in the
624 // (expression stack pointer) are added. ijava_state::sender_sp slot and
625 // - Has reserved slots for the - The large ABI is replaced with a minimal restored when returning.
626 // maximal expression stack ABI. This removes a c2i extension if there
627 // - Has a larger ABI section on - The original SP was saved in is one.
628 // top that is required to call ijava_state::top_frame_sp slot. - ijava_state::sender_sp will be set
629 // C++ code From there it is restored as SP _after_ as the caller's unextended sp when
630 // returning from a call. This reverts the iterating stack frames
631 // resizing described above. It is also (see frame::unextended_sp() and
632 // required to undo potential i2c extensions frame::sender_for_interpreter_frame())
633 // if the calle should be compiled.
634 // - Note that unextended SP < SP
635 // is possible on ppc.
636 //
637 // | | | | | |
638 // | (frame::java_abi) | | (frame::java_abi) | | (frame::java_abi) |
639 // | 4 words | | 4 words | | 4 words |
640 // | Caller's SP |<- FP of caller | Caller's SP |<- FP of caller | Caller's SP |<- FP of caller
641 // ======================== (aligned) ======================== ========================
642 // | frame:: | | frame:: | | frame:: |
643 // | ijava_state | | ijava_state | | ijava_state |
644 // | | | | | |
645 // |----------------------| |----------------------| |----------------------|
646 // | P0 | | L0 aka P0 | | L0 aka P0 |
647 // | | | : | | : |
648 // | Pn | | : Pn | | : Pn |
649 // |----------------------| | : | | : |
650 // | | | Lm | | Lm |
651 // | Reserved Expr. Stack | |----------------------| |----------------------|
652 // | | | Opt. Alignm. Padding | | Opt. Alignm. Padding |
653 // | |<- ConstMethod |----------------------| |----------------------|
654 // |----------------------| ::_max_stack | | | |
655 // | Opt. Alignm. Padding | | (frame::java_abi) | | (frame::java_abi) |
656 // |----------------------| | 4 words | | 4 words |
657 // | Large ABI | | Caller's SP |<- new SP of caller | Caller's SP |<- SP of caller /
658 // | for C++ calls | ======================== (aligned) ======================== FP of callee
659 // | (frame:: | | frame:: | (aligned)
660 // | native_abi_reg_args)| | ijava_state |
661 // | | | |
662 // | | |----------------------|
663 // | | | |
664 // | Caller's SP |<- SP of caller <- unextended SP | Reserved Expr. Stack |<- unextended SP
665 // ======================== (aligned) of caller | | of caller
666 // (aligned) | |
667 // | |
668 // | |
669 // | |
670 // | |<- ConstMethod
671 // |----------------------| ::_max_stack
672 // Resize Caller Push new Callee Frame | Opt. Alignm. Padding |
673 // --------------------> ------------------------> |----------------------|
674 // (ABI, expressions, locals) | Large ABI |
675 // | for C++ calls |
676 // | (frame:: |
677 // | native_abi_reg_args)|
678 // | Growth | | |
679 // v v | |
680 // | |
681 // | Caller's SP |<- SP of callee
682 // ======================== (aligned)
683 //
684 //
685 #endif // CPU_PPC_CONTINUATION_PPC_INLINE_HPP