Skip to content

Commit 304c45d

Browse files
committed
unroll frame syncs to 32, and use a loop for any constant frame descriptor
1 parent 7fb7230 commit 304c45d

File tree

1 file changed

+74
-2
lines changed

1 file changed

+74
-2
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ public SyncFrameValuesNode(boolean adoptable) {
309309

310310
public abstract void execute(VirtualFrame frame, PFrame pyframe, Frame frameToSync);
311311

312-
@Specialization(guards = {"hasLocalsStorage(pyFrame, frameToSync)", "frameToSync.getFrameDescriptor() == cachedFd", "cachedSlots.length < 64"}, //
312+
@Specialization(guards = {"hasLocalsStorage(pyFrame, frameToSync)", "frameToSync.getFrameDescriptor() == cachedFd", "cachedSlots.length < 32"}, //
313313
assumptions = "cachedFd.getVersion()", //
314314
limit = "1")
315315
@ExplodeLoop
@@ -382,7 +382,79 @@ static void doLocalsStorageCached(PFrame pyFrame, Frame frameToSync,
382382
}
383383
}
384384

385-
@Specialization(guards = "hasLocalsStorage(pyFrame, frameToSync)", replaces = "doLocalsStorageCached")
385+
@Specialization(guards = {"hasLocalsStorage(pyFrame, frameToSync)", "frameToSync.getFrameDescriptor() == cachedFd"}, //
386+
assumptions = "cachedFd.getVersion()", //
387+
limit = "1")
388+
static void doLocalsStorageLoop(PFrame pyFrame, Frame frameToSync,
389+
@Cached("frameToSync.getFrameDescriptor()") FrameDescriptor cachedFd,
390+
@Cached(value = "getSlots(cachedFd)", dimensions = 1) FrameSlot[] cachedSlots) {
391+
boolean invalidState = false;
392+
LocalsStorage localsStorage = getLocalsStorage(pyFrame);
393+
MaterializedFrame target = localsStorage.getFrame();
394+
assert cachedFd == target.getFrameDescriptor();
395+
396+
for (int i = 0; i < cachedSlots.length; i++) {
397+
FrameSlot slot = cachedSlots[i];
398+
if (FrameSlotIDs.isUserFrameSlot(slot.getIdentifier())) {
399+
if (frameToSync.isBoolean(slot)) {
400+
try {
401+
target.setBoolean(slot, frameToSync.getBoolean(slot));
402+
} catch (FrameSlotTypeException e) {
403+
CompilerDirectives.transferToInterpreter();
404+
invalidState = true;
405+
}
406+
} else if (frameToSync.isByte(slot)) {
407+
try {
408+
target.setByte(slot, frameToSync.getByte(slot));
409+
} catch (FrameSlotTypeException e) {
410+
CompilerDirectives.transferToInterpreter();
411+
invalidState = true;
412+
}
413+
} else if (frameToSync.isDouble(slot)) {
414+
try {
415+
target.setDouble(slot, frameToSync.getDouble(slot));
416+
} catch (FrameSlotTypeException e) {
417+
CompilerDirectives.transferToInterpreter();
418+
invalidState = true;
419+
}
420+
} else if (frameToSync.isFloat(slot)) {
421+
try {
422+
target.setFloat(slot, frameToSync.getFloat(slot));
423+
} catch (FrameSlotTypeException e) {
424+
CompilerDirectives.transferToInterpreter();
425+
invalidState = true;
426+
}
427+
} else if (frameToSync.isInt(slot)) {
428+
try {
429+
target.setInt(slot, frameToSync.getInt(slot));
430+
} catch (FrameSlotTypeException e) {
431+
CompilerDirectives.transferToInterpreter();
432+
invalidState = true;
433+
}
434+
} else if (frameToSync.isLong(slot)) {
435+
try {
436+
target.setLong(slot, frameToSync.getLong(slot));
437+
} catch (FrameSlotTypeException e) {
438+
CompilerDirectives.transferToInterpreter();
439+
invalidState = true;
440+
}
441+
} else if (frameToSync.isObject(slot)) {
442+
try {
443+
target.setObject(slot, frameToSync.getObject(slot));
444+
} catch (FrameSlotTypeException e) {
445+
CompilerDirectives.transferToInterpreter();
446+
invalidState = true;
447+
}
448+
}
449+
}
450+
}
451+
if (CompilerDirectives.inInterpreter() && invalidState) {
452+
// we're always in the interpreter if invalidState was set
453+
throw new IllegalStateException("the frame lied about the frame slot type");
454+
}
455+
}
456+
457+
@Specialization(guards = "hasLocalsStorage(pyFrame, frameToSync)", replaces = {"doLocalsStorageCached", "doLocalsStorageLoop"})
386458
static void doLocalsStorageUncached(PFrame pyFrame, Frame frameToSync) {
387459
FrameDescriptor fd = frameToSync.getFrameDescriptor();
388460
FrameSlot[] cachedSlots = getSlots(fd);

0 commit comments

Comments
 (0)