Skip to content

Commit ad761fd

Browse files
committed
[GR-34551] Ensure that slot kind checks can fold in WriteGeneratorFrameVariableNode.
PullRequest: graalpython/2124
2 parents e3b2bd7 + 423da93 commit ad761fd

File tree

2 files changed

+68
-20
lines changed

2 files changed

+68
-20
lines changed

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

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -42,6 +42,7 @@
4242

4343
import com.oracle.truffle.api.CompilerDirectives;
4444
import com.oracle.truffle.api.frame.Frame;
45+
import com.oracle.truffle.api.frame.FrameDescriptor;
4546
import com.oracle.truffle.api.frame.FrameSlotKind;
4647

4748
public abstract class FrameSlotGuards {
@@ -55,41 +56,73 @@ public static boolean isNotIllegal(Frame frame, int frameSlot) {
5556
}
5657

5758
public static boolean isBooleanKind(Frame frame, int frameSlot) {
58-
return isKind(frame, frameSlot, FrameSlotKind.Boolean);
59+
return isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Boolean);
5960
}
6061

6162
public static boolean isIntegerKind(Frame frame, int frameSlot) {
62-
return isKind(frame, frameSlot, FrameSlotKind.Int);
63+
return isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Int);
6364
}
6465

6566
public static boolean isLongKind(Frame frame, int frameSlot) {
66-
return isKind(frame, frameSlot, FrameSlotKind.Long);
67+
return isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Long);
6768
}
6869

6970
public static boolean isDoubleKind(Frame frame, int frameSlot) {
70-
return isKind(frame, frameSlot, FrameSlotKind.Double);
71+
return isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Double);
7172
}
7273

7374
public static boolean isIntOrObjectKind(Frame frame, int frameSlot) {
74-
return isKind(frame, frameSlot, FrameSlotKind.Int) || isKind(frame, frameSlot, FrameSlotKind.Object);
75+
return isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Int) || isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Object);
7576
}
7677

7778
public static boolean isLongOrObjectKind(Frame frame, int frameSlot) {
78-
return isKind(frame, frameSlot, FrameSlotKind.Long) || isKind(frame, frameSlot, FrameSlotKind.Object);
79+
return isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Long) || isKind(frame.getFrameDescriptor(), frameSlot, FrameSlotKind.Object);
7980
}
8081

8182
public static void ensureObjectKind(Frame frame, int frameSlot) {
8283
frame.getFrameDescriptor().setSlotKind(frameSlot, FrameSlotKind.Object);
8384
}
8485

85-
private static boolean isKind(Frame frame, int frameSlot, FrameSlotKind kind) {
86-
return frame.getFrameDescriptor().getSlotKind(frameSlot) == kind || initialSetKind(frame, frameSlot, kind);
86+
public static boolean isNotIllegal(FrameDescriptor descriptor, int frameSlot) {
87+
return descriptor.getSlotKind(frameSlot) != FrameSlotKind.Illegal;
8788
}
8889

89-
private static boolean initialSetKind(Frame frame, int frameSlot, FrameSlotKind kind) {
90-
if (frame.getFrameDescriptor().getSlotKind(frameSlot) == FrameSlotKind.Illegal) {
90+
public static boolean isBooleanKind(FrameDescriptor descriptor, int frameSlot) {
91+
return isKind(descriptor, frameSlot, FrameSlotKind.Boolean);
92+
}
93+
94+
public static boolean isIntegerKind(FrameDescriptor descriptor, int frameSlot) {
95+
return isKind(descriptor, frameSlot, FrameSlotKind.Int);
96+
}
97+
98+
public static boolean isLongKind(FrameDescriptor descriptor, int frameSlot) {
99+
return isKind(descriptor, frameSlot, FrameSlotKind.Long);
100+
}
101+
102+
public static boolean isDoubleKind(FrameDescriptor descriptor, int frameSlot) {
103+
return isKind(descriptor, frameSlot, FrameSlotKind.Double);
104+
}
105+
106+
public static boolean isIntOrObjectKind(FrameDescriptor descriptor, int frameSlot) {
107+
return isKind(descriptor, frameSlot, FrameSlotKind.Int) || isKind(descriptor, frameSlot, FrameSlotKind.Object);
108+
}
109+
110+
public static boolean isLongOrObjectKind(FrameDescriptor descriptor, int frameSlot) {
111+
return isKind(descriptor, frameSlot, FrameSlotKind.Long) || isKind(descriptor, frameSlot, FrameSlotKind.Object);
112+
}
113+
114+
public static void ensureObjectKind(FrameDescriptor descriptor, int frameSlot) {
115+
descriptor.setSlotKind(frameSlot, FrameSlotKind.Object);
116+
}
117+
118+
private static boolean isKind(FrameDescriptor descriptor, int frameSlot, FrameSlotKind kind) {
119+
return descriptor.getSlotKind(frameSlot) == kind || initialSetKind(descriptor, frameSlot, kind);
120+
}
121+
122+
private static boolean initialSetKind(FrameDescriptor descriptor, int frameSlot, FrameSlotKind kind) {
123+
if (descriptor.getSlotKind(frameSlot) == FrameSlotKind.Illegal) {
91124
CompilerDirectives.transferToInterpreterAndInvalidate();
92-
frame.getFrameDescriptor().setSlotKind(frameSlot, kind);
125+
descriptor.setSlotKind(frameSlot, kind);
93126
return true;
94127
}
95128
return false;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/generator/WriteGeneratorFrameVariableNode.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -31,10 +31,13 @@
3131
import com.oracle.graal.python.nodes.frame.FrameSlotNode;
3232
import com.oracle.graal.python.nodes.frame.WriteIdentifierNode;
3333
import com.oracle.graal.python.nodes.statement.StatementNode;
34+
import com.oracle.truffle.api.CompilerDirectives;
35+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
3436
import com.oracle.truffle.api.dsl.ImportStatic;
3537
import com.oracle.truffle.api.dsl.NodeChild;
3638
import com.oracle.truffle.api.dsl.Specialization;
3739
import com.oracle.truffle.api.frame.Frame;
40+
import com.oracle.truffle.api.frame.FrameDescriptor;
3841
import com.oracle.truffle.api.frame.VirtualFrame;
3942
import com.oracle.truffle.api.profiles.ValueProfile;
4043

@@ -43,6 +46,7 @@
4346
public abstract class WriteGeneratorFrameVariableNode extends StatementNode implements WriteIdentifierNode, FrameSlotNode {
4447

4548
protected final int frameSlot;
49+
@CompilationFinal private FrameDescriptor descriptor;
4650
private final ValueProfile frameProfile = ValueProfile.createClassProfile();
4751

4852
public WriteGeneratorFrameVariableNode(int frameSlot) {
@@ -74,30 +78,41 @@ protected final Frame getGeneratorFrame(VirtualFrame frame) {
7478
return frameProfile.profile(PArguments.getGeneratorFrame(frame));
7579
}
7680

77-
@Specialization(guards = "isBooleanKind(getGeneratorFrame(frame), frameSlot)")
81+
/**
82+
* The descriptor is kept in a compilation-final field (as opposed to getting it from the frame
83+
* every time) to ensure that it is a compilation constant.
84+
*/
85+
protected final FrameDescriptor getFrameDescriptor(VirtualFrame frame) {
86+
if (descriptor == null) {
87+
CompilerDirectives.transferToInterpreterAndInvalidate();
88+
descriptor = getGeneratorFrame(frame).getFrameDescriptor();
89+
}
90+
return descriptor;
91+
}
92+
93+
@Specialization(guards = "isBooleanKind(getFrameDescriptor(frame), frameSlot)")
7894
void writeBoolean(VirtualFrame frame, boolean value) {
7995
getGeneratorFrame(frame).setBoolean(frameSlot, value);
8096
}
8197

82-
@Specialization(guards = "isIntegerKind(getGeneratorFrame(frame), frameSlot)")
98+
@Specialization(guards = "isIntegerKind(getFrameDescriptor(frame), frameSlot)")
8399
void writeInt(VirtualFrame frame, int value) {
84100
getGeneratorFrame(frame).setInt(frameSlot, value);
85101
}
86102

87-
@Specialization(guards = "isLongKind(getGeneratorFrame(frame), frameSlot)")
103+
@Specialization(guards = "isLongKind(getFrameDescriptor(frame), frameSlot)")
88104
void writeLong(VirtualFrame frame, long value) {
89105
getGeneratorFrame(frame).setLong(frameSlot, value);
90106
}
91107

92-
@Specialization(guards = "isDoubleKind(getGeneratorFrame(frame), frameSlot)")
108+
@Specialization(guards = "isDoubleKind(getFrameDescriptor(frame), frameSlot)")
93109
void writeDouble(VirtualFrame frame, double value) {
94110
getGeneratorFrame(frame).setDouble(frameSlot, value);
95111
}
96112

97113
@Specialization(replaces = {"writeBoolean", "writeInt", "writeLong", "writeDouble"})
98114
void writeObject(VirtualFrame frame, Object value) {
99-
Frame generatorFrame = getGeneratorFrame(frame);
100-
FrameSlotGuards.ensureObjectKind(generatorFrame, frameSlot);
101-
generatorFrame.setObject(frameSlot, value);
115+
FrameSlotGuards.ensureObjectKind(getFrameDescriptor(frame), frameSlot);
116+
getGeneratorFrame(frame).setObject(frameSlot, value);
102117
}
103118
}

0 commit comments

Comments
 (0)