|
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