fourthTier: Landing the initial FTL logic in a single commit to avoid spurious
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNodeType.h
1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef DFGNodeType_h
27 #define DFGNodeType_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(DFG_JIT)
32
33 #include "DFGNodeFlags.h"
34
35 namespace JSC { namespace DFG {
36
37 // This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
38 #define FOR_EACH_DFG_OP(macro) \
39     /* A constant in the CodeBlock's constant pool. */\
40     macro(JSConstant, NodeResultJS | NodeDoesNotExit) \
41     \
42     /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\
43     /* code block. */\
44     macro(WeakJSConstant, NodeResultJS | NodeDoesNotExit) \
45     \
46     /* Marker to indicate that an operation was optimized entirely and all that is left */\
47     /* is to make one node alias another. CSE will later usually eliminate this node, */\
48     /* though it may choose not to if it would corrupt predictions (very rare). */\
49     macro(Identity, NodeResultJS) \
50     \
51     /* Nodes for handling functions (both as call and as construct). */\
52     macro(ConvertThis, NodeResultJS) \
53     macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
54     macro(GetCallee, NodeResultJS) \
55     macro(SetCallee, NodeMustGenerate) \
56     \
57     /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
58     /* Any two nodes that are part of the same Phi graph will share the same */\
59     /* VariableAccessData, and thus will share predictions. */\
60     macro(GetLocal, NodeResultJS) \
61     macro(SetLocal, NodeExitsForward) \
62     macro(MovHintAndCheck, NodeMustGenerate | NodeExitsForward) \
63     macro(MovHint, NodeDoesNotExit) \
64     macro(ZombieHint, NodeDoesNotExit) \
65     macro(Phantom, NodeMustGenerate) \
66     macro(Nop, NodeDoesNotExit) \
67     macro(Phi, NodeDoesNotExit | NodeRelevantToOSR) \
68     macro(Flush, NodeMustGenerate | NodeDoesNotExit) \
69     macro(PhantomLocal, NodeMustGenerate | NodeDoesNotExit) \
70     \
71     /* Get the value of a local variable, without linking into the VariableAccessData */\
72     /* network. This is only valid for variable accesses whose predictions originated */\
73     /* as something other than a local access, and thus had their own profiling. */\
74     macro(GetLocalUnlinked, NodeResultJS) \
75     \
76     /* Marker for an argument being set at the prologue of a function. */\
77     macro(SetArgument, 0 | NodeDoesNotExit) \
78     \
79     /* Hint that inlining begins here. No code is generated for this node. It's only */\
80     /* used for copying OSR data into inline frame data, to support reification of */\
81     /* call frames of inlined functions. */\
82     macro(InlineStart, NodeMustGenerate | NodeDoesNotExit) \
83     \
84     /* Nodes for bitwise operations. */\
85     macro(BitAnd, NodeResultInt32 | NodeMustGenerate) \
86     macro(BitOr, NodeResultInt32 | NodeMustGenerate) \
87     macro(BitXor, NodeResultInt32 | NodeMustGenerate) \
88     macro(BitLShift, NodeResultInt32 | NodeMustGenerate) \
89     macro(BitRShift, NodeResultInt32 | NodeMustGenerate) \
90     macro(BitURShift, NodeResultInt32 | NodeMustGenerate) \
91     /* Bitwise operators call ToInt32 on their operands. */\
92     macro(ValueToInt32, NodeResultInt32) \
93     /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
94     macro(UInt32ToNumber, NodeResultNumber | NodeExitsForward) \
95     \
96     /* Used to cast known integers to doubles, so as to separate the double form */\
97     /* of the value from the integer form. */\
98     macro(Int32ToDouble, NodeResultNumber) \
99     macro(ForwardInt32ToDouble, NodeResultNumber | NodeExitsForward) \
100     /* Used to speculate that a double value is actually an integer. */\
101     macro(DoubleAsInt32, NodeResultInt32 | NodeExitsForward) \
102     \
103     /* Nodes for arithmetic operations. */\
104     macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
105     macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
106     macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
107     macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
108     macro(ArithIMul, NodeResultInt32 | NodeMustGenerate) \
109     macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
110     macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
111     macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
112     macro(ArithMin, NodeResultNumber | NodeMustGenerate) \
113     macro(ArithMax, NodeResultNumber | NodeMustGenerate) \
114     macro(ArithSqrt, NodeResultNumber | NodeMustGenerate) \
115     \
116     /* Add of values may either be arithmetic, or result in string concatenation. */\
117     macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
118     \
119     /* Property access. */\
120     /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
121     /* Since a put to 'length' may invalidate optimizations here, */\
122     /* this must be the directly subsequent property put. Note that PutByVal */\
123     /* opcodes use VarArgs beause they may have up to 4 children. */\
124     macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
125     macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
126     macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
127     macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
128     macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
129     macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
130     macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
131     macro(CheckStructure, NodeMustGenerate) \
132     macro(CheckExecutable, NodeMustGenerate) \
133     macro(ForwardCheckStructure, NodeMustGenerate | NodeExitsForward) \
134     /* Transition watchpoints are a contract between the party setting the watchpoint */\
135     /* and the runtime system, where the party promises that the child object once had */\
136     /* the structure being watched, and the runtime system in turn promises that the */\
137     /* watchpoint will be turned into an OSR exit if any object with that structure */\
138     /* ever transitions to a different structure. Hence, the child object must have */\
139     /* previously had a CheckStructure executed on it or we're dealing with an object */\
140     /* constant (WeakJSConstant) and the object was known to have that structure at */\
141     /* compile-time. In the latter case this means that no structure checks have to be */\
142     /* performed for this object by JITted code. In the former case this means that*/\
143     /* the object's structure does not need to be rechecked due to side-effecting */\
144     /* (clobbering) operations. */\
145     macro(StructureTransitionWatchpoint, NodeMustGenerate) \
146     macro(ForwardStructureTransitionWatchpoint, NodeMustGenerate | NodeExitsForward) \
147     macro(PutStructure, NodeMustGenerate) \
148     macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \
149     macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
150     macro(ReallocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \
151     macro(GetButterfly, NodeResultStorage) \
152     macro(CheckArray, NodeMustGenerate) \
153     macro(Arrayify, NodeMustGenerate) \
154     macro(ArrayifyToStructure, NodeMustGenerate) \
155     macro(GetIndexedPropertyStorage, NodeResultStorage) \
156     macro(GetByOffset, NodeResultJS) \
157     macro(PutByOffset, NodeMustGenerate) \
158     macro(GetArrayLength, NodeResultInt32) \
159     macro(GetScope, NodeResultJS) \
160     macro(GetMyScope, NodeResultJS) \
161     macro(SetMyScope, NodeMustGenerate) \
162     macro(SkipTopScope, NodeResultJS) \
163     macro(SkipScope, NodeResultJS) \
164     macro(GetScopeRegisters, NodeResultStorage) \
165     macro(GetScopedVar, NodeResultJS) \
166     macro(PutScopedVar, NodeMustGenerate) \
167     macro(GetGlobalVar, NodeResultJS) \
168     macro(PutGlobalVar, NodeMustGenerate) \
169     macro(GlobalVarWatchpoint, NodeMustGenerate) \
170     macro(PutGlobalVarCheck, NodeMustGenerate) \
171     macro(CheckFunction, NodeMustGenerate) \
172     macro(AllocationProfileWatchpoint, NodeMustGenerate) \
173     \
174     /* Optimizations for array mutation. */\
175     macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
176     macro(ArrayPop, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
177     \
178     /* Optimizations for regular expression matching. */\
179     macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
180     macro(RegExpTest, NodeResultJS | NodeMustGenerate) \
181     \
182     /* Optimizations for string access */ \
183     macro(StringCharCodeAt, NodeResultInt32) \
184     macro(StringCharAt, NodeResultJS) \
185     macro(StringFromCharCode, NodeResultJS) \
186     \
187     /* Nodes for comparison operations. */\
188     macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
189     macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
190     macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
191     macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
192     macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeMightClobber) \
193     macro(CompareEqConstant, NodeResultBoolean | NodeMustGenerate) \
194     macro(CompareStrictEq, NodeResultBoolean) \
195     macro(CompareStrictEqConstant, NodeResultBoolean) \
196     \
197     /* Calls. */\
198     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
199     macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
200     \
201     /* Allocations. */\
202     macro(NewObject, NodeResultJS) \
203     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
204     macro(NewArrayWithSize, NodeResultJS) \
205     macro(NewArrayBuffer, NodeResultJS) \
206     macro(NewRegexp, NodeResultJS) \
207     \
208     /* Resolve nodes. */\
209     macro(Resolve, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
210     macro(ResolveBase, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
211     macro(ResolveBaseStrictPut, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
212     macro(ResolveGlobal, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
213     \
214     /* Nodes for misc operations. */\
215     macro(Breakpoint, NodeMustGenerate | NodeClobbersWorld) \
216     macro(CheckHasInstance, NodeMustGenerate) \
217     macro(InstanceOf, NodeResultBoolean) \
218     macro(IsUndefined, NodeResultBoolean) \
219     macro(IsBoolean, NodeResultBoolean) \
220     macro(IsNumber, NodeResultBoolean) \
221     macro(IsString, NodeResultBoolean) \
222     macro(IsObject, NodeResultBoolean) \
223     macro(IsFunction, NodeResultBoolean) \
224     macro(TypeOf, NodeResultJS) \
225     macro(LogicalNot, NodeResultBoolean) \
226     macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
227     macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
228     macro(NewStringObject, NodeResultJS) \
229     macro(MakeRope, NodeResultJS) \
230     \
231     /* Nodes used for activations. Activation support works by having it anchored at */\
232     /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
233     /* being threaded with each other. */\
234     macro(CreateActivation, NodeResultJS) \
235     macro(TearOffActivation, NodeMustGenerate) \
236     \
237     /* Nodes used for arguments. Similar to activation support, only it makes even less */\
238     /* sense. */\
239     macro(CreateArguments, NodeResultJS) \
240     macro(PhantomArguments, NodeResultJS | NodeDoesNotExit) \
241     macro(TearOffArguments, NodeMustGenerate) \
242     macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
243     macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
244     macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
245     macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
246     macro(CheckArgumentsNotCreated, NodeMustGenerate) \
247     \
248     /* Nodes for creating functions. */\
249     macro(NewFunctionNoCheck, NodeResultJS) \
250     macro(NewFunction, NodeResultJS) \
251     macro(NewFunctionExpression, NodeResultJS) \
252     \
253     /* Block terminals. */\
254     macro(Jump, NodeMustGenerate) \
255     macro(Branch, NodeMustGenerate) \
256     macro(Return, NodeMustGenerate) \
257     macro(Throw, NodeMustGenerate) \
258     macro(ThrowReferenceError, NodeMustGenerate) \
259     \
260     macro(GarbageValue, NodeResultJS | NodeClobbersWorld) \
261     \
262     /* Count execution. */\
263     macro(CountExecution, NodeMustGenerate) \
264     \
265     /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
266     /* this point, but execution does continue in the basic block - just in a */\
267     /* different compiler. */\
268     macro(ForceOSRExit, NodeMustGenerate) \
269     \
270     /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \
271     /* baseline JIT to redo the watchdog timer check, and service the timer. */ \
272     macro(CheckWatchdogTimer, NodeMustGenerate) \
273
274 // This enum generates a monotonically increasing id for all Node types,
275 // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
276 enum NodeType {
277 #define DFG_OP_ENUM(opcode, flags) opcode,
278     FOR_EACH_DFG_OP(DFG_OP_ENUM)
279 #undef DFG_OP_ENUM
280     LastNodeType
281 };
282
283 // Specifies the default flags for each node.
284 inline NodeFlags defaultFlags(NodeType op)
285 {
286     switch (op) {
287 #define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
288     FOR_EACH_DFG_OP(DFG_OP_ENUM)
289 #undef DFG_OP_ENUM
290     default:
291         RELEASE_ASSERT_NOT_REACHED();
292         return 0;
293     }
294 }
295
296 inline bool needsOSRBackwardRewiring(NodeType op)
297 {
298     return op == UInt32ToNumber;
299 }
300
301 inline bool needsOSRForwardRewiring(NodeType op)
302 {
303     switch (op) {
304     case Int32ToDouble:
305     case ForwardInt32ToDouble:
306     case ValueToInt32:
307     case UInt32ToNumber:
308     case DoubleAsInt32:
309         return true;
310     default:
311         return false;
312     }
313 }
314
315 } } // namespace JSC::DFG
316
317 #endif // ENABLE(DFG_JIT)
318
319 #endif // DFGNodeType_h
320