Mercurial > hg > truffle
annotate graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLDispatchNode.java @ 21493:99e3f4c5c853
SL: handle undefined functions gracefully.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 26 May 2015 20:04:07 +0200 |
parents | 2170de9acab0 |
children |
rev | line source |
---|---|
20956
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
1 /* |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
4 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
5 * This code is free software; you can redistribute it and/or modify it |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
6 * under the terms of the GNU General Public License version 2 only, as |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
7 * published by the Free Software Foundation. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
8 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
13 * accompanied this code). |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
14 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
15 * You should have received a copy of the GNU General Public License version |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
18 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
21 * questions. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
22 */ |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
23 package com.oracle.truffle.sl.nodes.call; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
24 |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
25 import com.oracle.truffle.api.*; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
26 import com.oracle.truffle.api.dsl.*; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
27 import com.oracle.truffle.api.frame.*; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
28 import com.oracle.truffle.api.nodes.*; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
29 import com.oracle.truffle.sl.runtime.*; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
30 |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
31 public abstract class SLDispatchNode extends Node { |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
32 |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
33 protected static final int INLINE_CACHE_SIZE = 2; |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
34 |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
35 public abstract Object executeDispatch(VirtualFrame frame, SLFunction function, Object[] arguments); |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
36 |
21493
99e3f4c5c853
SL: handle undefined functions gracefully.
Christian Humer <christian.humer@gmail.com>
parents:
20956
diff
changeset
|
37 @Specialization(guards = "function.getCallTarget() == null") |
99e3f4c5c853
SL: handle undefined functions gracefully.
Christian Humer <christian.humer@gmail.com>
parents:
20956
diff
changeset
|
38 protected Object doUndefinedFunction(SLFunction function, @SuppressWarnings("unused") Object[] arguments) { |
99e3f4c5c853
SL: handle undefined functions gracefully.
Christian Humer <christian.humer@gmail.com>
parents:
20956
diff
changeset
|
39 throw new SLUndefinedFunctionException(function.getName()); |
99e3f4c5c853
SL: handle undefined functions gracefully.
Christian Humer <christian.humer@gmail.com>
parents:
20956
diff
changeset
|
40 } |
99e3f4c5c853
SL: handle undefined functions gracefully.
Christian Humer <christian.humer@gmail.com>
parents:
20956
diff
changeset
|
41 |
20956
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
42 /** |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
43 * Inline cached specialization of the dispatch. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
44 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
45 * <p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
46 * Since SL is a quite simple language, the benefit of the inline cache is quite small: after |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
47 * checking that the actual function to be executed is the same as the cachedFuntion, we can |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
48 * safely execute the cached call target. You can reasonably argue that caching the call target |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
49 * is overkill, since we could just retrieve it via {@code function.getCallTarget()}. However, |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
50 * in a more complex language the lookup of the call target is usually much more complicated |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
51 * than in SL. In addition, caching the call target allows method inlining. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
52 * </p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
53 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
54 * <p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
55 * {@code limit = "INLINE_CACHE_SIZE"} Specifies the limit number of inline cache specialization |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
56 * instantiations. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
57 * </p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
58 * <p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
59 * {@code guards = "function == cachedFunction"} The inline cache check. Note that |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
60 * cachedFunction is a final field so that the compiler can optimize the check. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
61 * </p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
62 * <p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
63 * {@code assumptions = "cachedFunction.getCallTargetStable()"} Support for function |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
64 * redefinition: When a function is redefined, the call target maintained by the SLFunction |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
65 * object is change. To avoid a check for that, we use an Assumption that is invalidated by the |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
66 * SLFunction when the change is performed. Since checking an assumption is a no-op in compiled |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
67 * code, the assumption check performed by the DSL does not add any overhead during optimized |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
68 * execution. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
69 * </p> |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
70 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
71 * @see Cached |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
72 * @see Specialization |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
73 * |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
74 * @param function the dynamically provided function |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
75 * @param cachedFunction the cached function of the specialization instance |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
76 * @param callNode the {@link DirectCallNode} specifically created for the {@link CallTarget} in |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
77 * cachedFunction. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
78 */ |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
79 @Specialization(limit = "INLINE_CACHE_SIZE", guards = "function == cachedFunction", assumptions = "cachedFunction.getCallTargetStable()") |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
80 protected static Object doDirect(VirtualFrame frame, SLFunction function, Object[] arguments, // |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
81 @Cached("function") SLFunction cachedFunction, // |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
82 @Cached("create(cachedFunction.getCallTarget())") DirectCallNode callNode) { |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
83 /* Inline cache hit, we are safe to execute the cached call target. */ |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
84 return callNode.call(frame, arguments); |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
85 } |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
86 |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
87 /** |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
88 * Slow-path code for a call, used when the polymorphic inline cache exceeded its maximum size |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
89 * specified in <code>INLINE_CACHE_SIZE</code>. Such calls are not optimized any further, e.g., |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
90 * no method inlining is performed. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
91 */ |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
92 @Specialization(contains = "doDirect") |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
93 protected static Object doIndirect(VirtualFrame frame, SLFunction function, Object[] arguments, // |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
94 @Cached("create()") IndirectCallNode callNode) { |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
95 /* |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
96 * SL has a quite simple call lookup: just ask the function for the current call target, and |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
97 * call it. |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
98 */ |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
99 return callNode.call(frame, function.getCallTarget(), arguments); |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
100 } |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
101 |
2170de9acab0
SL: use DSL for call dispatches.
Christian Humer <christian.humer@gmail.com>
parents:
diff
changeset
|
102 } |