09b6284c6a897e94cee8ed82659316f74d173cab
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNodeType.h
1 /*
2  * Copyright (C) 2012, 2013, 2014 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 #if ENABLE(DFG_JIT)
30
31 #include "DFGNodeFlags.h"
32
33 namespace JSC { namespace DFG {
34
35 // This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
36 #define FOR_EACH_DFG_OP(macro) \
37     /* A constant in the CodeBlock's constant pool. */\
38     macro(JSConstant, NodeResultJS) \
39     \
40     /* Constants with specific representations. */\
41     macro(DoubleConstant, NodeResultDouble) \
42     macro(Int52Constant, NodeResultInt52) \
43     \
44     /* Marker to indicate that an operation was optimized entirely and all that is left */\
45     /* is to make one node alias another. CSE will later usually eliminate this node, */\
46     /* though it may choose not to if it would corrupt predictions (very rare). */\
47     macro(Identity, NodeResultJS) \
48     \
49     /* Nodes for handling functions (both as call and as construct). */\
50     macro(ToThis, NodeResultJS) \
51     macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
52     macro(GetCallee, NodeResultJS) \
53     \
54     /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
55     /* Any two nodes that are part of the same Phi graph will share the same */\
56     /* VariableAccessData, and thus will share predictions. FIXME: We should come up with */\
57     /* better names for a lot of these. https://bugs.webkit.org/show_bug.cgi?id=137307 */\
58     macro(GetLocal, NodeResultJS) \
59     macro(SetLocal, 0) \
60     macro(PutLocal, NodeMustGenerate) \
61     macro(KillLocal, NodeMustGenerate) \
62     macro(MovHint, 0) \
63     macro(ZombieHint, 0) \
64     macro(GetArgument, NodeResultJS | NodeMustGenerate) \
65     macro(Phantom, NodeMustGenerate) \
66     macro(HardPhantom, NodeMustGenerate) /* Like Phantom, but we never remove any of its children. */ \
67     macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
68     macro(Upsilon, NodeRelevantToOSR) \
69     macro(Phi, NodeRelevantToOSR) \
70     macro(Flush, NodeMustGenerate) \
71     macro(PhantomLocal, NodeMustGenerate) \
72     \
73     /* Hint that this is where bytecode thinks is a good place to OSR. Note that this */\
74     /* will exist even in inlined loops. This has no execution semantics but it must */\
75     /* survive all DCE. We treat this as being a can-exit because tier-up to FTL may */\
76     /* want all state. */\
77     macro(LoopHint, NodeMustGenerate) \
78     \
79     /* Special node for OSR entry into the FTL. Indicates that we're loading a local */\
80     /* variable from the scratch buffer. */\
81     macro(ExtractOSREntryLocal, NodeResultJS) \
82     \
83     /* Tier-up checks from the DFG to the FTL. */\
84     macro(CheckTierUpInLoop, NodeMustGenerate) \
85     macro(CheckTierUpAndOSREnter, NodeMustGenerate) \
86     macro(CheckTierUpAtReturn, NodeMustGenerate) \
87     \
88     /* Get the value of a local variable, without linking into the VariableAccessData */\
89     /* network. This is only valid for variable accesses whose predictions originated */\
90     /* as something other than a local access, and thus had their own profiling. */\
91     macro(GetLocalUnlinked, NodeResultJS) \
92     \
93     /* Marker for an argument being set at the prologue of a function. */\
94     macro(SetArgument, 0) \
95     \
96     /* Marker of location in the IR where we may possibly perform jump replacement to */\
97     /* invalidate this code block. */\
98     macro(InvalidationPoint, NodeMustGenerate) \
99     \
100     /* Nodes for bitwise operations. */\
101     macro(BitAnd, NodeResultInt32) \
102     macro(BitOr, NodeResultInt32) \
103     macro(BitXor, NodeResultInt32) \
104     macro(BitLShift, NodeResultInt32) \
105     macro(BitRShift, NodeResultInt32) \
106     macro(BitURShift, NodeResultInt32) \
107     /* Bitwise operators call ToInt32 on their operands. */\
108     macro(ValueToInt32, NodeResultInt32) \
109     /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
110     macro(UInt32ToNumber, NodeResultNumber) \
111     /* Converts booleans to numbers but passes everything else through. */\
112     macro(BooleanToNumber, NodeResultJS) \
113     \
114     /* Attempt to truncate a double to int32; this will exit if it can't do it. */\
115     macro(DoubleAsInt32, NodeResultInt32) \
116     \
117     /* Change the representation of a value. */\
118     macro(DoubleRep, NodeResultDouble) \
119     macro(Int52Rep, NodeResultInt52) \
120     macro(ValueRep, NodeResultJS) \
121     \
122     /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
123     macro(FiatInt52, NodeResultJS) \
124     \
125     /* Nodes for arithmetic operations. */\
126     macro(ArithAdd, NodeResultNumber) \
127     macro(ArithSub, NodeResultNumber) \
128     macro(ArithNegate, NodeResultNumber) \
129     macro(ArithMul, NodeResultNumber) \
130     macro(ArithIMul, NodeResultInt32) \
131     macro(ArithDiv, NodeResultNumber) \
132     macro(ArithMod, NodeResultNumber) \
133     macro(ArithAbs, NodeResultNumber) \
134     macro(ArithMin, NodeResultNumber) \
135     macro(ArithMax, NodeResultNumber) \
136     macro(ArithFRound, NodeResultNumber) \
137     macro(ArithSqrt, NodeResultNumber) \
138     macro(ArithSin, NodeResultNumber) \
139     macro(ArithCos, NodeResultNumber) \
140     \
141     /* Add of values may either be arithmetic, or result in string concatenation. */\
142     macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
143     \
144     /* Property access. */\
145     /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
146     /* Since a put to 'length' may invalidate optimizations here, */\
147     /* this must be the directly subsequent property put. Note that PutByVal */\
148     /* opcodes use VarArgs beause they may have up to 4 children. */\
149     macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
150     macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
151     macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
152     macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \
153     macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
154     macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
155     macro(PutById, NodeMustGenerate | NodeClobbersWorld) \
156     macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate | NodeClobbersWorld) \
157     macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \
158     macro(CheckStructure, NodeMustGenerate) \
159     macro(GetExecutable, NodeResultJS) \
160     macro(PutStructure, NodeMustGenerate) \
161     macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
162     macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
163     macro(GetButterfly, NodeResultStorage) \
164     macro(CheckArray, NodeMustGenerate) \
165     macro(Arrayify, NodeMustGenerate) \
166     macro(ArrayifyToStructure, NodeMustGenerate) \
167     macro(GetIndexedPropertyStorage, NodeResultStorage) \
168     macro(ConstantStoragePointer, NodeResultStorage) \
169     macro(TypedArrayWatchpoint, NodeMustGenerate) \
170     macro(GetGetter, NodeResultJS) \
171     macro(GetSetter, NodeResultJS) \
172     macro(GetByOffset, NodeResultJS) \
173     macro(GetGetterSetterByOffset, NodeResultJS) \
174     macro(MultiGetByOffset, NodeResultJS | NodeMustGenerate) \
175     macro(PutByOffset, NodeMustGenerate) \
176     macro(MultiPutByOffset, NodeMustGenerate) \
177     macro(GetArrayLength, NodeResultInt32) \
178     macro(GetTypedArrayByteOffset, NodeResultInt32) \
179     macro(GetScope, NodeResultJS) \
180     macro(SkipScope, NodeResultJS) \
181     macro(GetClosureRegisters, NodeResultStorage) \
182     macro(GetClosureVar, NodeResultJS) \
183     macro(PutClosureVar, NodeMustGenerate) \
184     macro(GetGlobalVar, NodeResultJS) \
185     macro(PutGlobalVar, NodeMustGenerate) \
186     macro(NotifyWrite, NodeMustGenerate) \
187     macro(VariableWatchpoint, NodeMustGenerate) \
188     macro(VarInjectionWatchpoint, NodeMustGenerate) \
189     macro(FunctionReentryWatchpoint, NodeMustGenerate) \
190     macro(CheckCell, NodeMustGenerate) \
191     macro(CheckBadCell, NodeMustGenerate) \
192     macro(AllocationProfileWatchpoint, NodeMustGenerate) \
193     macro(CheckInBounds, NodeMustGenerate) \
194     \
195     /* Optimizations for array mutation. */\
196     macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
197     macro(ArrayPop, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
198     \
199     /* Optimizations for regular expression matching. */\
200     macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
201     macro(RegExpTest, NodeResultJS | NodeMustGenerate) \
202     \
203     /* Optimizations for string access */ \
204     macro(StringCharCodeAt, NodeResultInt32) \
205     macro(StringCharAt, NodeResultJS) \
206     macro(StringFromCharCode, NodeResultJS) \
207     \
208     /* Nodes for comparison operations. */\
209     macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
210     macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
211     macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
212     macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
213     macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
214     macro(CompareEqConstant, NodeResultBoolean) \
215     macro(CompareStrictEq, NodeResultBoolean) \
216     \
217     /* Calls. */\
218     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
219     macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
220     macro(NativeCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
221     macro(NativeConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \
222     \
223     /* Allocations. */\
224     macro(NewObject, NodeResultJS) \
225     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
226     macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
227     macro(NewArrayBuffer, NodeResultJS) \
228     macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \
229     macro(NewRegexp, NodeResultJS) \
230     \
231     /* Support for allocation sinking. */\
232     macro(PhantomNewObject, NodeResultJS) \
233     macro(PutByOffsetHint, NodeMustGenerate) \
234     macro(CheckStructureImmediate, NodeMustGenerate) \
235     macro(PutStructureHint, NodeMustGenerate) \
236     macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
237     \
238     /* Nodes for misc operations. */\
239     macro(Breakpoint, NodeMustGenerate) \
240     macro(ProfileWillCall, NodeMustGenerate) \
241     macro(ProfileDidCall, NodeMustGenerate) \
242     macro(CheckHasInstance, NodeMustGenerate) \
243     macro(InstanceOf, NodeResultBoolean) \
244     macro(IsUndefined, NodeResultBoolean) \
245     macro(IsBoolean, NodeResultBoolean) \
246     macro(IsNumber, NodeResultBoolean) \
247     macro(IsString, NodeResultBoolean) \
248     macro(IsObject, NodeResultBoolean) \
249     macro(IsFunction, NodeResultBoolean) \
250     macro(TypeOf, NodeResultJS) \
251     macro(LogicalNot, NodeResultBoolean) \
252     macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
253     macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \
254     macro(NewStringObject, NodeResultJS) \
255     macro(MakeRope, NodeResultJS) \
256     macro(In, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \
257     macro(ProfileType, NodeMustGenerate) \
258     macro(ProfileControlFlow, NodeMustGenerate) \
259     \
260     /* Nodes used for activations. Activation support works by having it anchored at */\
261     /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\
262     /* being threaded with each other. */\
263     macro(CreateActivation, NodeResultJS) \
264     \
265     /* Nodes used for arguments. Similar to lexical environment support, only it makes even less */\
266     /* sense. */\
267     macro(CreateArguments, NodeResultJS) \
268     macro(PhantomArguments, NodeResultJS) \
269     macro(TearOffArguments, NodeMustGenerate) \
270     macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \
271     macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
272     macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
273     macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \
274     macro(CheckArgumentsNotCreated, NodeMustGenerate) \
275     \
276     /* Nodes for creating functions. */\
277     macro(NewFunctionNoCheck, NodeResultJS) \
278     macro(NewFunction, NodeResultJS) \
279     macro(NewFunctionExpression, NodeResultJS) \
280     \
281     /* These aren't terminals but always exit */ \
282     macro(Throw, NodeMustGenerate) \
283     macro(ThrowReferenceError, NodeMustGenerate) \
284     \
285     /* Block terminals. */\
286     macro(Jump, NodeMustGenerate) \
287     macro(Branch, NodeMustGenerate) \
288     macro(Switch, NodeMustGenerate) \
289     macro(Return, NodeMustGenerate) \
290     macro(Unreachable, NodeMustGenerate) \
291     \
292     /* Count execution. */\
293     macro(CountExecution, NodeMustGenerate) \
294     \
295     /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
296     /* this point, but execution does continue in the basic block - just in a */\
297     /* different compiler. */\
298     macro(ForceOSRExit, NodeMustGenerate) \
299     \
300     /* Vends a bottom JS value. It is invalid to ever execute this. Useful for cases */\
301     /* where we know that we would have exited but we'd like to still track the control */\
302     /* flow. */\
303     macro(BottomValue, NodeResultJS) \
304     \
305     /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \
306     /* baseline JIT to redo the watchdog timer check, and service the timer. */ \
307     macro(CheckWatchdogTimer, NodeMustGenerate) \
308     /* Write barriers ! */\
309     macro(StoreBarrier, NodeMustGenerate) \
310     macro(StoreBarrierWithNullCheck, NodeMustGenerate) \
311     \
312     /* For-in enumeration opcodes */\
313     macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
314     macro(HasIndexedProperty, NodeResultBoolean) \
315     macro(HasStructureProperty, NodeResultBoolean) \
316     macro(HasGenericProperty, NodeResultBoolean) \
317     macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
318     macro(GetStructurePropertyEnumerator, NodeMustGenerate | NodeResultJS) \
319     macro(GetGenericPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
320     macro(GetEnumeratorPname, NodeMustGenerate | NodeResultJS) \
321     macro(ToIndexString, NodeResultJS)
322
323 // This enum generates a monotonically increasing id for all Node types,
324 // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
325 enum NodeType {
326 #define DFG_OP_ENUM(opcode, flags) opcode,
327     FOR_EACH_DFG_OP(DFG_OP_ENUM)
328 #undef DFG_OP_ENUM
329     LastNodeType
330 };
331
332 // Specifies the default flags for each node.
333 inline NodeFlags defaultFlags(NodeType op)
334 {
335     switch (op) {
336 #define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
337     FOR_EACH_DFG_OP(DFG_OP_ENUM)
338 #undef DFG_OP_ENUM
339     default:
340         RELEASE_ASSERT_NOT_REACHED();
341         return 0;
342     }
343 }
344
345 } } // namespace JSC::DFG
346
347 #endif // ENABLE(DFG_JIT)
348
349 #endif // DFGNodeType_h
350