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