Skip to content

Commit bc6c739

Browse files
jirkamarsikbulasevich
authored andcommitted
Handle static slots in restoreParentFrame
(cherry picked from commit 92b2c377565ba43114a5257f2a5199b240fe7925)
1 parent 7332df5 commit bc6c739

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;
@@ -414,15 +415,15 @@ public void transferFrame(FrameWithoutBoxing source, FrameWithoutBoxing target,
414415

415416
OptimizedRuntimeAccessor.ACCESSOR.startOSRFrameTransfer(target);
416417
// Transfer indexed frame slots
417-
transferLoop(description.indexedFrameTags.length, source, target, description.indexedFrameTags);
418+
transferLoop(description.indexedFrameTags, source, target);
418419
// transfer auxiliary slots
419420
transferAuxiliarySlots(source, target, state);
420421
}
421422

422423
/**
423424
* Transfer state from {@code source} to {@code target}. Can be used to transfer state from an
424425
* OSR frame to a parent frame. Overall less efficient than its
425-
* {@link #transferFrame(FrameWithoutBoxing, FrameWithoutBoxing, int, Object) counterpart},
426+
* {@link #transferFrame(FrameWithoutBoxing, FrameWithoutBoxing, long, Object) counterpart},
426427
* mainly due to not being able to speculate on the source tags: While entering bytecode OSR is
427428
* done through specific entry points (likely back edges), returning could be done from anywhere
428429
* within a method body (through regular returns, or exception thrown).
@@ -464,10 +465,11 @@ public void restoreFrame(FrameWithoutBoxing source, FrameWithoutBoxing target) {
464465
// The frames should use the same descriptor.
465466
validateDescriptors(source, target, state);
466467

467-
// We can't reasonably have constant expected tags for parent frame restoration.
468+
// We can't reasonably have constant expected tags for parent frame restoration. We pass
469+
// state.frameDescriptor to restoreLoop in order to correctly account for static slots.
468470

469471
// transfer indexed frame slots
470-
transferLoop(state.frameDescriptor.getNumberOfSlots(), source, target, null);
472+
restoreLoop(state.frameDescriptor, source, target);
471473
// transfer auxiliary slots
472474
transferAuxiliarySlots(source, target, state);
473475
}
@@ -487,26 +489,23 @@ private static void validateDescriptors(FrameWithoutBoxing source, FrameWithoutB
487489
}
488490

489491
/**
490-
* Common transfer loop for copying over legacy frame slot or indexed slots from a source frame
491-
* to a target frame.
492+
* Transfer loop for copying over indexed frame slots from a source parent frame to a target OSR
493+
* frame.
492494
*
493-
* @param length Number of slots to transfer. Must be
494-
* {@link CompilerDirectives#isCompilationConstant(Object) compilation constant}
495+
* @param expectedTags The array of tags the source is expected to have. If compilation
496+
* constant, frame slot accesses may be simplified.
495497
* @param source The frame to copy from
496498
* @param target The frame to copy to
497-
* @param expectedTags The array of tags the source is expected to have, or null if no previous
498-
* knowledge of tags was collected. If compilation constant, frame slot accesses may
499-
* be simplified.
500499
*/
501500
@ExplodeLoop
502501
private static void transferLoop(
503-
int length,
504-
FrameWithoutBoxing source, FrameWithoutBoxing target,
505-
byte[] expectedTags) {
502+
byte[] expectedTags,
503+
FrameWithoutBoxing source, FrameWithoutBoxing target) {
504+
CompilerAsserts.partialEvaluationConstant(expectedTags.length);
506505
int i = 0;
507-
while (i < length) {
506+
while (i < expectedTags.length) {
508507
byte actualTag = source.getTag(i);
509-
byte expectedTag = expectedTags == null ? actualTag : expectedTags[i];
508+
byte expectedTag = expectedTags[i];
510509

511510
boolean incompatibleTags = expectedTag != actualTag;
512511
if (incompatibleTags) {
@@ -521,6 +520,33 @@ private static void transferLoop(
521520
}
522521
}
523522

523+
/**
524+
* Transfer loop for copying over indexed frame slots from a source OSR frame to a target parent
525+
* frame.
526+
*
527+
* @param frameDescriptor The common frame descriptor of source and target
528+
* @param source The frame to copy from
529+
* @param target The frame to copy to
530+
*/
531+
private static void restoreLoop(
532+
FrameDescriptor frameDescriptor,
533+
FrameWithoutBoxing source, FrameWithoutBoxing target) {
534+
CompilerAsserts.neverPartOfCompilation();
535+
for (int i = 0; i < frameDescriptor.getNumberOfSlots(); i++) {
536+
byte tag = source.getTag(i);
537+
538+
if (tag == 0 && frameDescriptor.getSlotKind(i) == FrameSlotKind.Static) {
539+
// When using static slots, the tags might never be initialized. We cannot rely
540+
// solely on the source frame instance tags in order to detect static slots and
541+
// distinguish them from non-static Object-type slots. Hence, if the tag is 0, we
542+
// check the FrameDescriptor whether the slot has a static kind.
543+
tag = FrameWithoutBoxing.STATIC_TAG;
544+
}
545+
546+
transferIndexedFrameSlot(source, target, i, tag);
547+
}
548+
}
549+
524550
@ExplodeLoop
525551
private static void transferAuxiliarySlots(FrameWithoutBoxing source, FrameWithoutBoxing target, LazyState state) {
526552
for (int auxSlot = 0; auxSlot < state.frameDescriptor.getNumberOfAuxiliarySlots(); auxSlot++) {

0 commit comments

Comments
 (0)