Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/Specialization.java @ 19288:3a37116ef37f
Truffle-DSL: added @Cached annotation, added limit property and updated @Specialization javadoc.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 29 Dec 2014 18:32:03 +0100 |
parents | ea9903f9684f |
children | 67ab244ab689 |
comparison
equal
deleted
inserted
replaced
19287:19c6359c6191 | 19288:3a37116ef37f |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this | 7 * published by the Free Software Foundation. Oracle designates this |
24 */ | 24 */ |
25 package com.oracle.truffle.api.dsl; | 25 package com.oracle.truffle.api.dsl; |
26 | 26 |
27 import java.lang.annotation.*; | 27 import java.lang.annotation.*; |
28 | 28 |
29 import com.oracle.truffle.api.*; | |
30 import com.oracle.truffle.api.frame.*; | |
31 import com.oracle.truffle.api.nodes.*; | |
32 | |
33 /** | |
34 * <p> | |
35 * Defines a method of a node subclass to represent one specialization of an operation. Multiple | |
36 * specializations can be defined in a node representing an operation. A specialization defines | |
37 * which kind of input is expected using the method signature and the annotation attributes. The | |
38 * specialized semantics of the operation are defined using the body of the annotated Java method. A | |
39 * specialization method must be declared in a class that is derived from {@link Node} that | |
40 * references a {@link TypeSystem}. At least one specialization must be defined per operation. If no | |
41 * specialization is valid for the given set of input values then an | |
42 * {@link UnsupportedSpecializationException} is thrown instead of invoking any specialization | |
43 * method. | |
44 * </p> | |
45 * <p> | |
46 * A specialization must have at least as many parameters as there are {@link NodeChild} annotations | |
47 * declared for the enclosing operation node. These parameters are declared in the same order as the | |
48 * {@link NodeChild} annotations (linear execution order). We call such parameters dynamic input | |
49 * parameters. Every specialization that is declared within an operation must have an equal number | |
50 * of dynamic input parameters. | |
51 * </p> | |
52 * <p> | |
53 * The supported kind of input values for a specialization are declared using guards. A | |
54 * specialization may provide declarative specifications for four kinds of guards: | |
55 * <ul> | |
56 * <li><b>Type guards</b> optimistically assume the type of an input value. A value that matches the | |
57 * type is cast to its expected type automatically. Type guards are modeled using the parameter type | |
58 * of the specialization method. Types used for type guards must be defined in the | |
59 * {@link TypeSystem}. If the type of the parameter is {@link Object} then no type guard is used for | |
60 * the dynamic input parameter.</li> | |
61 * | |
62 * <li><b>Expression guards</b> optimistically assume the return value of a user-defined expression | |
63 * to be <code>true</code>. Expression guards are modeled using Java expressions that return a | |
64 * <code>boolean</code> value. If the guard expression returns <code>false</code>, the | |
65 * specialization is no longer applicable and the operation is re-specialized. Guard expressions are | |
66 * declared using the {@link #guards()} attribute.</li> | |
67 * | |
68 * <li><b>Event guards</b> trigger re-specialization in case an exception is thrown in the | |
69 * specialization body. The {@link #rewriteOn()} attribute can be used to declare a list of such | |
70 * exceptions. Guards of this kind are useful to avoid calculating a value twice when it is used in | |
71 * the guard and its specialization.</li> | |
72 * | |
73 * <li><b>Assumption guards</b> optimistically assume that the state of an {@link Assumption} | |
74 * remains <code>true</code>. Assumptions can be assigned to specializations using the | |
75 * {@link #assumptions()} attribute.</li> | |
76 * </ul> | |
77 * </p> | |
78 * <p> | |
79 * The enclosing {@link Node} of a specialization method must have at least one <code>public</code> | |
80 * and non-<code>final</code> execute method. An execute method is a method that starts with | |
81 * 'execute'. If all execute methods declare the first parameter type as {@link Frame}, | |
82 * {@link VirtualFrame} or {@link MaterializedFrame} then the same frame type can be used as | |
83 * optional first parameter of the specialization. This parameter does not count to the number of | |
84 * dynamic parameters. | |
85 * </p> | |
86 * <p> | |
87 * A specialization method may declare multiple parameters annotated with {@link Cached}. Cached | |
88 * parameters are initialized and stored once per specialization instantiation. For consistency | |
89 * between specialization declarations cached parameters must be declared last in a specialization | |
90 * method. | |
91 * </p> | |
92 * <p> | |
93 * If the operation is re-specialized or if it is executed for the first time then all declared | |
94 * specializations of the operation are tried in declaration order until the guards of the first | |
95 * specialization accepts the current input values. The new specialization is then added to the | |
96 * chain of current specialization instances which might consist of one (monomorph) or multiple | |
97 * instances (polymorph). If an assumption of an instantiated specialization is violated then | |
98 * re-specialization is triggered again. | |
99 * </p> | |
100 * <p> | |
101 * With guards in combination with cached parameters it is possible that multiple instances of the | |
102 * same specialization are created. The {@link #limit()} attribute can be used to limit the number | |
103 * of instantiations per specialization. | |
104 * </p> | |
105 * | |
106 * @see NodeChild | |
107 * @see ShortCircuit | |
108 * @see Fallback | |
109 * @see Cached | |
110 * @see TypeSystem | |
111 * @see TypeSystemReference | |
112 * @see UnsupportedSpecializationException | |
113 */ | |
29 @Retention(RetentionPolicy.RUNTIME) | 114 @Retention(RetentionPolicy.RUNTIME) |
30 @Target({ElementType.METHOD}) | 115 @Target({ElementType.METHOD}) |
31 public @interface Specialization { | 116 public @interface Specialization { |
32 | 117 |
33 /** | 118 /** |
34 * @deprecated do not use anymore. Will get removed in the next release. | 119 * @deprecated do not use anymore. Will get removed in the next release. |
35 */ | 120 */ |
36 @Deprecated int DEFAULT_ORDER = -1; | 121 @Deprecated int DEFAULT_ORDER = -1; |
37 | 122 |
38 /** | 123 /** |
39 * The order has no effect anymore. The declaration order specialization methods is used | |
40 * instead. | |
41 * | |
42 * @deprecated use declaration order instead. Will get removed in the next release. | 124 * @deprecated use declaration order instead. Will get removed in the next release. |
43 */ | 125 */ |
44 @Deprecated | 126 @Deprecated |
45 int order() default DEFAULT_ORDER; | 127 int order() default DEFAULT_ORDER; |
46 | 128 |
47 /** | 129 /** |
48 * Inserts this and all specializations that are declared after this specialization before a | 130 * References a specialization of a super class by its method name where this specialization is |
49 * specialization in the superclass. By default all specializations of the subclass are appended | 131 * inserted before. The declaration order of a specialization is not usable for nodes where |
50 * to the specializations of the superclass. | 132 * specializations are partly declared in the super class and partly declared in a derived |
133 * class. By default all specializations declared in the derived class are appended to those in | |
134 * the super class. This attribute can be used to override the default behavior. | |
51 */ | 135 */ |
52 String insertBefore() default ""; | 136 String insertBefore() default ""; |
53 | 137 |
138 /** | |
139 * <p> | |
140 * Declares an event guards that trigger re-specialization in case an exception is thrown in the | |
141 * specialization body. This attribute can be used to declare a list of such exceptions. Guards | |
142 * of this kind are useful to avoid calculating a value twice when it is used in the guard and | |
143 * its specialization. | |
144 * </p> | |
145 * | |
146 * <p> | |
147 * If an event guard exception is triggered then all instantiations of this specialization are | |
148 * removed. If one of theses exceptions is thrown once then no further instantiations of this | |
149 * specialization are going to be created for this node. A specialization that rewrites on an | |
150 * exception must ensure that no non-repeatable side-effect is caused until the rewrite is | |
151 * triggered. | |
152 * </p> | |
153 * | |
154 * <b>Example usage:</b> | |
155 * | |
156 * <pre> | |
157 * @Specialization(rewriteOn = ArithmeticException.class) | |
158 * int doAddNoOverflow(int a, int b) { | |
159 * return ExactMath.addExact(a, b); | |
160 * } | |
161 * | |
162 * @Specialization | |
163 * long doAddWithOverflow(int a, int b) { | |
164 * return a + b; | |
165 * } | |
166 * ... | |
167 * | |
168 * Example executions: | |
169 * execute(Integer.MAX_VALUE - 1, 1) => doAddNoOverflow(Integer.MAX_VALUE - 1, 1) | |
170 * execute(Integer.MAX_VALUE, 1) => doAddNoOverflow(Integer.MAX_VALUE, 1) | |
171 * => throws ArithmeticException | |
172 * => doAddWithOverflow(Integer.MAX_VALUE, 1) | |
173 * execute(Integer.MAX_VALUE - 1, 1) => doAddWithOverflow(Integer.MAX_VALUE - 1, 1) | |
174 * </pre> | |
175 * | |
176 * </p> | |
177 * | |
178 * @see ExactMath#addExact(int, int) | |
179 */ | |
54 Class<? extends Throwable>[] rewriteOn() default {}; | 180 Class<? extends Throwable>[] rewriteOn() default {}; |
55 | 181 |
56 /** | 182 /** |
57 * The contains attribute declares all specializations that are contained by this | 183 * <p> |
58 * specialization. A containing specialization must be strictly generic as the contained | 184 * Declares other specializations of the same node to be contained by this specialization. Other |
59 * specialization. | 185 * specializations are references using their unique method name. If this specialization is |
186 * instantiated then all contained specialization instances are removed and never instantiated | |
187 * again for this node instance. Therefore this specialization should handle strictly more | |
188 * inputs than which were handled by the contained specialization, otherwise the removal of the | |
189 * contained specialization will lead to unspecialized types of input values. The contains | |
190 * declaration is transitive for multiple involved specializations. | |
191 * </p> | |
192 * <b>Example usage:</b> | |
193 * | |
194 * <pre> | |
195 * @Specialization(guards = "b == 2") | |
196 * void doDivPowerTwo(int a, int b) { | |
197 * return a >> 1; | |
198 * } | |
199 * | |
200 * @Specialization(contains ="doDivPowerTwo", guards = "b > 0") | |
201 * void doDivPositive(int a, int b) { | |
202 * return a / b; | |
203 * } | |
204 * ... | |
205 * | |
206 * Example executions with contains="doDivPowerTwo": | |
207 * execute(4, 2) => doDivPowerTwo(4, 2) | |
208 * execute(9, 3) => doDivPositive(9, 3) // doDivPowerTwo instances get removed | |
209 * execute(4, 2) => doDivPositive(4, 2) | |
210 * | |
211 * Same executions without contains="doDivPowerTwo" | |
212 * execute(4, 2) => doDivPowerTwo(4, 2) | |
213 * execute(9, 3) => doDivPositive(9, 3) | |
214 * execute(4, 2) => doDivPowerTwo(4, 2) | |
215 * </pre> | |
216 * | |
217 * </p> | |
218 * | |
219 * @see #guards() | |
60 */ | 220 */ |
61 String[] contains() default {}; | 221 String[] contains() default {}; |
62 | 222 |
223 /** | |
224 * <p> | |
225 * Declares <code>boolean</code> expressions that define whether or not input values are | |
226 * applicable to this specialization instance. Guard expressions must always return the same | |
227 * result for each combination of the enclosing node instance and the bound input values. | |
228 * </p> | |
229 * <p> | |
230 * If a guard expression does not bind any dynamic input parameters then the DSL assumes that | |
231 * the result will not change for this node after specialization instantiation. The DSL asserts | |
232 * this assumption if assertions are enabled (-ea). | |
233 * </p> | |
234 * <p> | |
235 * Guard expressions are defined using a subset of Java. This subset includes field/parameter | |
236 * accesses, function calls, type exact infix comparisons (==, !=, <, <=, >, >=), logical | |
237 * negation (!), logical disjunction (||) and integer literals. The return type of guard | |
238 * expressions must be <code>boolean</code>. Bound elements without receivers are resolved using | |
239 * the following order: | |
240 * <ol> | |
241 * <li>Dynamic and cached parameters of the enclosing specialization.</li> | |
242 * <li>Fields defined using {@link NodeField} for the enclosing node.</li> | |
243 * <li>Non-private, static or virtual methods or fields of enclosing node.</li> | |
244 * <li>Non-private, static or virtual methods or fields of super types of the enclosing node.</li> | |
245 * <li>Public and static methods or fields imported using {@link ImportStatic}.</li> | |
246 * </ol> | |
247 * </p> | |
248 * <p> | |
249 * <b>Example usage:</b> | |
250 * | |
251 * <pre> | |
252 * static boolean acceptOperand(int operand) { | |
253 * assert operand <= 42; | |
254 * return operand & 1 == 1; | |
255 * } | |
256 * | |
257 * @Specialization(guards = {"operand <= 42", "acceptOperand(operand)"}) | |
258 * void doSpecialization(int operand) {...} | |
259 * </pre> | |
260 * | |
261 * </p> | |
262 * | |
263 * @see Cached | |
264 * @see ImportStatic | |
265 */ | |
63 String[] guards() default {}; | 266 String[] guards() default {}; |
64 | 267 |
65 /** | 268 /** |
66 * Defines the assumptions to check for this specialization. When the specialization method is | 269 * <p> |
67 * invoked it is guaranteed that these assumptions still hold. It is not guaranteed that they | 270 * Declares assumption guards that optimistically assume that the state of an {@link Assumption} |
68 * are checked before the {@link #guards()} methods. They may be checked before after or in | 271 * remains valid. Assumption expressions are cached once per specialization instantiation. If |
69 * between {@link #guards()}. To declare assumptions use the {@link NodeAssumptions} annotation | 272 * one of the returned assumptions gets invalidated then the specialization instance is removed. |
70 * at class level. | 273 * An assumption expression may return different assumptions per specialization instance. The |
274 * returned assumption instance must not be <code>null</code>. | |
275 * </p> | |
276 * <p> | |
277 * Assumption expressions are defined using a subset of Java. This subset includes | |
278 * field/parameter accesses, function calls, type exact infix comparisons (==, !=, <, <=, >, | |
279 * >=), logical negation (!), logical disjunction (||) and integer literals. The return type of | |
280 * the expression must be {@link Assumption}. Assumption expressions are not allowed to bind to | |
281 * dynamic parameter values of the specialization. Bound elements without receivers are resolved | |
282 * using the following order: | |
283 * <ol> | |
284 * <li>Cached parameters of the enclosing specialization.</li> | |
285 * <li>Fields defined using {@link NodeField} for the enclosing node.</li> | |
286 * <li>Non-private, static or virtual methods or fields of enclosing node.</li> | |
287 * <li>Non-private, static or virtual methods or fields of super types of the enclosing node.</li> | |
288 * <li>Public and static methods or fields imported using {@link ImportStatic}.</li> | |
289 * </ol> | |
290 * </p> | |
291 * | |
292 * <p> | |
293 * <b>Example usage:</b> | |
294 * | |
295 * <pre> | |
296 * static abstract class DynamicObject() { | |
297 * abstract Shape getShape(); | |
298 * ... | |
299 * } | |
300 * static abstract class Shape() { | |
301 * abstract Assumption getUnmodifiedAssuption(); | |
302 * ... | |
303 * } | |
304 * | |
305 * @Specialization(guards = "operand.getShape() == cachedShape", assumptions = "cachedShape.getUnmodifiedAssumption()") | |
306 * void doAssumeUnmodifiedShape(DynamicObject operand, @Cached("operand.getShape()") Shape cachedShape) {...} | |
307 * </pre> | |
308 * | |
309 * </p> | |
310 * | |
311 * @see Cached | |
312 * @see ImportStatic | |
71 */ | 313 */ |
72 String[] assumptions() default {}; | 314 String[] assumptions() default {}; |
73 | 315 |
316 /** | |
317 * <p> | |
318 * Declares the expression that limits the number of specialization instantiations. The default | |
319 * limit for specialization instantiations is defined as <code>"3"</code>. If the limit is | |
320 * exceeded no more instantiations of the enclosing specialization method are created. Please | |
321 * note that the existing specialization instantiations are <b>not</b> removed from the | |
322 * specialization chain. You can use {@link #contains()} to remove unnecessary specializations | |
323 * instances. | |
324 * </p> | |
325 * <p> | |
326 * The limit expression is defined using a subset of Java. This subset includes field/parameter | |
327 * accesses, function calls, type exact infix comparisons (==, !=, <, <=, >, >=), logical | |
328 * negation (!), logical disjunction (||) and integer literals. The return type of the limit | |
329 * expression must be <code>int</code>. Limit expressions are not allowed to bind to dynamic | |
330 * parameter values of the specialization. Bound elements without receivers are resolved using | |
331 * the following order: | |
332 * <ol> | |
333 * <li>Cached parameters of the enclosing specialization.</li> | |
334 * <li>Fields defined using {@link NodeField} for the enclosing node.</li> | |
335 * <li>Non-private, static or virtual methods or fields of enclosing node.</li> | |
336 * <li>Non-private, static or virtual methods or fields of super types of the enclosing node.</li> | |
337 * <li>Public and static methods or fields imported using {@link ImportStatic}.</li> | |
338 * </ol> | |
339 * </p> | |
340 * | |
341 * <p> | |
342 * <b>Example usage:</b> | |
343 * | |
344 * <pre> | |
345 * static int getCacheLimit() { | |
346 * return Integer.parseInt(System.getProperty("language.cacheLimit")); | |
347 * } | |
348 * | |
349 * @Specialization(guards = "operand == cachedOperand", limit = "getCacheLimit()") | |
350 * void doCached(Object operand, @Cached("operand") Object cachedOperand) {...} | |
351 * </pre> | |
352 * | |
353 * </p> | |
354 * | |
355 * @see #guards() | |
356 * @see #contains() | |
357 * @see Cached | |
358 * @see ImportStatic | |
359 */ | |
360 String limit() default ""; | |
361 | |
74 } | 362 } |