|
42 | 42 |
|
43 | 43 | import java.util.Arrays;
|
44 | 44 |
|
45 |
| -import com.oracle.truffle.api.dsl.Bind; |
46 | 45 | import org.graalvm.polyglot.io.ByteSequence;
|
47 | 46 |
|
48 | 47 | import com.oracle.graal.python.PythonLanguage;
|
49 | 48 | import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltins;
|
| 49 | +import com.oracle.graal.python.builtins.objects.code.CodeNodesFactory.GetCodeCallTargetNodeGen; |
50 | 50 | import com.oracle.graal.python.builtins.objects.function.Signature;
|
51 | 51 | import com.oracle.graal.python.compiler.CodeUnit;
|
52 | 52 | import com.oracle.graal.python.nodes.IndirectCallNode;
|
|
63 | 63 | import com.oracle.truffle.api.Assumption;
|
64 | 64 | import com.oracle.truffle.api.CallTarget;
|
65 | 65 | import com.oracle.truffle.api.CompilerDirectives;
|
66 |
| -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; |
67 | 66 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
68 | 67 | import com.oracle.truffle.api.RootCallTarget;
|
69 | 68 | import com.oracle.truffle.api.Truffle;
|
| 69 | +import com.oracle.truffle.api.dsl.Bind; |
70 | 70 | import com.oracle.truffle.api.dsl.Cached;
|
71 | 71 | import com.oracle.truffle.api.dsl.GenerateUncached;
|
72 | 72 | import com.oracle.truffle.api.dsl.NeverDefault;
|
73 | 73 | import com.oracle.truffle.api.dsl.Specialization;
|
74 | 74 | import com.oracle.truffle.api.frame.VirtualFrame;
|
75 | 75 | import com.oracle.truffle.api.nodes.Node;
|
76 | 76 | import com.oracle.truffle.api.nodes.RootNode;
|
77 |
| -import com.oracle.truffle.api.profiles.ConditionProfile; |
78 | 77 | import com.oracle.truffle.api.profiles.InlinedConditionProfile;
|
79 | 78 | import com.oracle.truffle.api.source.Source;
|
80 | 79 | import com.oracle.truffle.api.strings.TruffleString;
|
@@ -183,69 +182,40 @@ public static CreateCodeNode create() {
|
183 | 182 | }
|
184 | 183 | }
|
185 | 184 |
|
186 |
| - public static final class GetCodeCallTargetNode extends Node { |
187 |
| - private static final GetCodeCallTargetNode UNCACHED = new GetCodeCallTargetNode(false); |
| 185 | + @GenerateUncached |
| 186 | + public abstract static class GetCodeCallTargetNode extends PNodeWithContext { |
188 | 187 |
|
189 |
| - private final boolean isAdoptable; |
190 |
| - @CompilationFinal private ConditionProfile hasCtProfile; |
191 |
| - @CompilationFinal private PCode cachedCode1; |
192 |
| - @CompilationFinal private PCode cachedCode2; |
193 |
| - @CompilationFinal private RootCallTarget cachedCt1; |
194 |
| - @CompilationFinal private RootCallTarget cachedCt2; |
| 188 | + GetCodeCallTargetNode() { |
| 189 | + } |
195 | 190 |
|
196 |
| - private GetCodeCallTargetNode(boolean isAdoptable) { |
197 |
| - this.isAdoptable = isAdoptable; |
| 191 | + public abstract RootCallTarget execute(PCode code); |
| 192 | + |
| 193 | + @Specialization(guards = {"cachedCode == code", "isSingleContext()"}, limit = "2") |
| 194 | + final RootCallTarget doCachedCode(@SuppressWarnings("unused") PCode code, |
| 195 | + @SuppressWarnings("unused") @Cached("code") PCode cachedCode, |
| 196 | + @Cached("code.initializeCallTarget()") RootCallTarget cachedRootCallTarget) { |
| 197 | + return cachedRootCallTarget; |
198 | 198 | }
|
199 | 199 |
|
200 |
| - public final RootCallTarget execute(PCode code) { |
201 |
| - if (isAdoptable) { |
202 |
| - if (hasCtProfile == null) { |
203 |
| - if (PythonLanguage.get(this).isSingleContext()) { |
204 |
| - if (cachedCode1 == null) { |
205 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
206 |
| - cachedCode1 = code; |
207 |
| - cachedCt1 = code.initializeCallTarget(); |
208 |
| - return cachedCt1; |
209 |
| - } |
210 |
| - if (cachedCode1 == code) { |
211 |
| - return cachedCt1; |
212 |
| - } |
213 |
| - if (cachedCode2 == null) { |
214 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
215 |
| - cachedCode2 = code; |
216 |
| - cachedCt2 = code.initializeCallTarget(); |
217 |
| - return cachedCt2; |
218 |
| - } |
219 |
| - if (cachedCode2 == code) { |
220 |
| - return cachedCt2; |
221 |
| - } |
222 |
| - } |
223 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
224 |
| - cachedCode1 = cachedCode2 = null; |
225 |
| - cachedCt1 = cachedCt2 = null; |
226 |
| - hasCtProfile = ConditionProfile.create(); |
227 |
| - } |
228 |
| - RootCallTarget ct = code.callTarget; |
229 |
| - if (hasCtProfile.profile(ct == null)) { |
230 |
| - ct = code.initializeCallTarget(); |
231 |
| - } |
232 |
| - return ct; |
233 |
| - } else { |
234 |
| - RootCallTarget ct = code.callTarget; |
235 |
| - if (ct == null) { |
236 |
| - ct = code.initializeCallTarget(); |
237 |
| - } |
238 |
| - return ct; |
| 200 | + @Specialization(replaces = "doCachedCode") |
| 201 | + final RootCallTarget doGeneric(PCode code, |
| 202 | + @Bind("this") Node inliningTarget, |
| 203 | + @Cached InlinedConditionProfile hasCtProfile) { |
| 204 | + RootCallTarget ct = code.callTarget; |
| 205 | + if (hasCtProfile.profile(inliningTarget, ct == null)) { |
| 206 | + ct = code.initializeCallTarget(); |
239 | 207 | }
|
| 208 | + return ct; |
240 | 209 | }
|
241 | 210 |
|
242 | 211 | @NeverDefault
|
243 | 212 | public static GetCodeCallTargetNode create() {
|
244 |
| - return new GetCodeCallTargetNode(true); |
| 213 | + return GetCodeCallTargetNodeGen.create(); |
245 | 214 | }
|
246 | 215 |
|
| 216 | + @NeverDefault |
247 | 217 | public static GetCodeCallTargetNode getUncached() {
|
248 |
| - return UNCACHED; |
| 218 | + return GetCodeCallTargetNodeGen.getUncached(); |
249 | 219 | }
|
250 | 220 | }
|
251 | 221 |
|
@@ -297,7 +267,7 @@ public boolean isAdoptable() {
|
297 | 267 | return isAdoptable;
|
298 | 268 | }
|
299 | 269 |
|
300 |
| - public final RootNode execute(PCode code) { |
| 270 | + public RootNode execute(PCode code) { |
301 | 271 | if (getCodeCallTargetNode == null) {
|
302 | 272 | CompilerDirectives.transferToInterpreterAndInvalidate();
|
303 | 273 | getCodeCallTargetNode = insert(GetCodeCallTargetNode.create());
|
|
0 commit comments