Skip to content

Commit 7194373

Browse files
OracleLabsAutomationelkorchi
authored andcommitted
[GR-60090] Backport to 24.1: Handle static frame slots in BytecodeOSRMetadata#restoreParentFrame.
PullRequest: graal/19480
2 parents 627c343 + 57d6662 commit 7194373

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BytecodeOSRMetadata.java

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5353
import com.oracle.truffle.api.TruffleLanguage;
5454
import com.oracle.truffle.api.frame.FrameDescriptor;
55+
import com.oracle.truffle.api.frame.FrameSlotKind;
5556
import com.oracle.truffle.api.frame.FrameSlotTypeException;
5657
import com.oracle.truffle.api.frame.VirtualFrame;
5758
import com.oracle.truffle.api.impl.FrameWithoutBoxing;
@@ -433,15 +434,15 @@ public void transferFrame(FrameWithoutBoxing source, FrameWithoutBoxing target,
433434

434435
OptimizedRuntimeAccessor.ACCESSOR.startOSRFrameTransfer(target);
435436
// Transfer indexed frame slots
436-
transferLoop(description.indexedFrameTags.length, source, target, description.indexedFrameTags);
437+
transferLoop(description.indexedFrameTags, source, target);
437438
// transfer auxiliary slots
438439
transferAuxiliarySlots(source, target, state);
439440
}
440441

441442
/**
442443
* Transfer state from {@code source} to {@code target}. Can be used to transfer state from an
443444
* OSR frame to a parent frame. Overall less efficient than its
444-
* {@link #transferFrame(FrameWithoutBoxing, FrameWithoutBoxing, int, Object) counterpart},
445+
* {@link #transferFrame(FrameWithoutBoxing, FrameWithoutBoxing, long, Object) counterpart},
445446
* mainly due to not being able to speculate on the source tags: While entering bytecode OSR is
446447
* done through specific entry points (likely back edges), returning could be done from anywhere
447448
* within a method body (through regular returns, or exception thrown).
@@ -483,10 +484,11 @@ public void restoreFrame(FrameWithoutBoxing source, FrameWithoutBoxing target) {
483484
// The frames should use the same descriptor.
484485
validateDescriptors(source, target, state);
485486

486-
// We can't reasonably have constant expected tags for parent frame restoration.
487+
// We can't reasonably have constant expected tags for parent frame restoration. We pass
488+
// state.frameDescriptor to restoreLoop in order to correctly account for static slots.
487489

488490
// transfer indexed frame slots
489-
transferLoop(state.frameDescriptor.getNumberOfSlots(), source, target, null);
491+
restoreLoop(state.frameDescriptor, source, target);
490492
// transfer auxiliary slots
491493
transferAuxiliarySlots(source, target, state);
492494
}
@@ -506,26 +508,23 @@ private static void validateDescriptors(FrameWithoutBoxing source, FrameWithoutB
506508
}
507509

508510
/**
509-
* Common transfer loop for copying over legacy frame slot or indexed slots from a source frame
510-
* to a target frame.
511+
* Transfer loop for copying over indexed frame slots from a source parent frame to a target OSR
512+
* frame.
511513
*
512-
* @param length Number of slots to transfer. Must be
513-
* {@link CompilerDirectives#isCompilationConstant(Object) compilation constant}
514+
* @param expectedTags The array of tags the source is expected to have. If compilation
515+
* constant, frame slot accesses may be simplified.
514516
* @param source The frame to copy from
515517
* @param target The frame to copy to
516-
* @param expectedTags The array of tags the source is expected to have, or null if no previous
517-
* knowledge of tags was collected. If compilation constant, frame slot accesses may
518-
* be simplified.
519518
*/
520519
@ExplodeLoop
521520
private static void transferLoop(
522-
int length,
523-
FrameWithoutBoxing source, FrameWithoutBoxing target,
524-
byte[] expectedTags) {
521+
byte[] expectedTags,
522+
FrameWithoutBoxing source, FrameWithoutBoxing target) {
523+
CompilerAsserts.partialEvaluationConstant(expectedTags.length);
525524
int i = 0;
526-
while (i < length) {
525+
while (i < expectedTags.length) {
527526
byte actualTag = source.getTag(i);
528-
byte expectedTag = expectedTags == null ? actualTag : expectedTags[i];
527+
byte expectedTag = expectedTags[i];
529528

530529
if (expectedTag == FrameWithoutBoxing.STATIC_TAG) {
531530
// Here we can skip incompatible tag check in case of static slot since the frame
@@ -547,6 +546,33 @@ private static void transferLoop(
547546
}
548547
}
549548

549+
/**
550+
* Transfer loop for copying over indexed frame slots from a source OSR frame to a target parent
551+
* frame.
552+
*
553+
* @param frameDescriptor The common frame descriptor of source and target
554+
* @param source The frame to copy from
555+
* @param target The frame to copy to
556+
*/
557+
private static void restoreLoop(
558+
FrameDescriptor frameDescriptor,
559+
FrameWithoutBoxing source, FrameWithoutBoxing target) {
560+
CompilerAsserts.neverPartOfCompilation();
561+
for (int i = 0; i < frameDescriptor.getNumberOfSlots(); i++) {
562+
byte tag = source.getTag(i);
563+
564+
if (tag == 0 && frameDescriptor.getSlotKind(i) == FrameSlotKind.Static) {
565+
// When using static slots, the tags might never be initialized. We cannot rely
566+
// solely on the source frame instance tags in order to detect static slots and
567+
// distinguish them from non-static Object-type slots. Hence, if the tag is 0, we
568+
// check the FrameDescriptor whether the slot has a static kind.
569+
tag = FrameWithoutBoxing.STATIC_TAG;
570+
}
571+
572+
transferIndexedFrameSlot(source, target, i, tag);
573+
}
574+
}
575+
550576
@ExplodeLoop
551577
private static void transferAuxiliarySlots(FrameWithoutBoxing source, FrameWithoutBoxing target, LazyState state) {
552578
for (int auxSlot = 0; auxSlot < state.frameDescriptor.getNumberOfAuxiliarySlots(); auxSlot++) {

0 commit comments

Comments
 (0)