DFG should inline InstanceOf ICs
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGNodeType.h
1 /*
2  * Copyright (C) 2012-2018 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 #pragma once
27
28 #if ENABLE(DFG_JIT)
29
30 #include "DFGNodeFlags.h"
31
32 namespace JSC { namespace DFG {
33
34 // This macro defines a set of information about all known node types, used to populate NodeId, NodeType below.
35 #define FOR_EACH_DFG_OP(macro) \
36     /* A constant in the CodeBlock's constant pool. */\
37     macro(JSConstant, NodeResultJS) \
38     \
39     /* Constants with specific representations. */\
40     macro(DoubleConstant, NodeResultDouble) \
41     macro(Int52Constant, NodeResultInt52) \
42     \
43     /* Lazy JSValue constant. We don't know the JSValue bits of it yet. */\
44     macro(LazyJSConstant, NodeResultJS) \
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     /* Used for debugging to force a profile to appear as anything we want. */ \
51     macro(IdentityWithProfile, NodeResultJS | NodeMustGenerate) \
52     \
53     /* Nodes for handling functions (both as call and as construct). */\
54     macro(ToThis, NodeResultJS) \
55     macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \
56     macro(GetCallee, NodeResultJS) \
57     macro(SetCallee, NodeMustGenerate) \
58     macro(GetArgumentCountIncludingThis, NodeResultInt32) \
59     macro(SetArgumentCountIncludingThis, NodeMustGenerate) \
60     \
61     /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
62     /* Any two nodes that are part of the same Phi graph will share the same */\
63     /* VariableAccessData, and thus will share predictions. FIXME: We should come up with */\
64     /* better names for a lot of these. https://bugs.webkit.org/show_bug.cgi?id=137307. */\
65     /* Note that GetLocal is MustGenerate because it's our only way of knowing that some other */\
66     /* basic block might have read a local variable in bytecode. We only remove GetLocals if it */\
67     /* is redundant because of an earlier GetLocal or SetLocal in the same block. We could make */\
68     /* these not MustGenerate and use a more sophisticated analysis to insert PhantomLocals in */\
69     /* the same way that we insert Phantoms. That's hard and probably not profitable. See */\
70     /* https://bugs.webkit.org/show_bug.cgi?id=144086 */\
71     macro(GetLocal, NodeResultJS | NodeMustGenerate) \
72     macro(SetLocal, 0) \
73     \
74     macro(PutStack, NodeMustGenerate) \
75     macro(KillStack, NodeMustGenerate) \
76     macro(GetStack, NodeResultJS) \
77     \
78     macro(MovHint, NodeMustGenerate) \
79     macro(ZombieHint, NodeMustGenerate) \
80     macro(ExitOK, NodeMustGenerate) /* Indicates that exit state is intact. */ \
81     macro(Phantom, NodeMustGenerate) \
82     macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
83     macro(CheckVarargs, NodeMustGenerate | NodeHasVarArgs) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
84     macro(Upsilon, 0) \
85     macro(Phi, 0) \
86     macro(Flush, NodeMustGenerate) \
87     macro(PhantomLocal, NodeMustGenerate) \
88     \
89     /* Hint that this is where bytecode thinks is a good place to OSR. Note that this */\
90     /* will exist even in inlined loops. This has no execution semantics but it must */\
91     /* survive all DCE. We treat this as being a can-exit because tier-up to FTL may */\
92     /* want all state. */\
93     macro(LoopHint, NodeMustGenerate) \
94     \
95     /* Special node for OSR entry into the FTL. Indicates that we're loading a local */\
96     /* variable from the scratch buffer. */\
97     macro(ExtractOSREntryLocal, NodeResultJS) \
98     macro(ExtractCatchLocal, NodeResultJS) \
99     \
100     /* Tier-up checks from the DFG to the FTL. */\
101     macro(CheckTierUpInLoop, NodeMustGenerate) \
102     macro(CheckTierUpAndOSREnter, NodeMustGenerate) \
103     macro(CheckTierUpAtReturn, NodeMustGenerate) \
104     \
105     /* Marker for an argument being set at the prologue of a function. */\
106     macro(SetArgument, 0) \
107     \
108     /* Marker of location in the IR where we may possibly perform jump replacement to */\
109     /* invalidate this code block. */\
110     macro(InvalidationPoint, NodeMustGenerate) \
111     \
112     /* Nodes for bitwise operations. */\
113     macro(BitAnd, NodeResultInt32) \
114     macro(BitOr, NodeResultInt32) \
115     macro(BitXor, NodeResultInt32) \
116     macro(BitLShift, NodeResultInt32) \
117     macro(BitRShift, NodeResultInt32) \
118     macro(BitURShift, NodeResultInt32) \
119     /* Bitwise operators call ToInt32 on their operands. */\
120     macro(ValueToInt32, NodeResultInt32) \
121     /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
122     macro(UInt32ToNumber, NodeResultNumber) \
123     /* Converts booleans to numbers but passes everything else through. */\
124     macro(BooleanToNumber, NodeResultJS) \
125     \
126     /* Attempt to truncate a double to int32; this will exit if it can't do it. */\
127     macro(DoubleAsInt32, NodeResultInt32) \
128     \
129     /* Change the representation of a value. */\
130     macro(DoubleRep, NodeResultDouble) \
131     macro(Int52Rep, NodeResultInt52) \
132     macro(ValueRep, NodeResultJS) \
133     \
134     /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
135     macro(FiatInt52, NodeResultJS) \
136     \
137     /* Nodes for arithmetic operations. Note that if they do checks other than just type checks, */\
138     /* then they are MustGenerate. This is probably stricter than it needs to be - for example */\
139     /* they won't do checks if they are speculated double. Also, we could kill these if we do it */\
140     /* before AI starts eliminating downstream operations based on proofs, for example in the */\
141     /* case of "var tmp = a + b; return (tmp | 0) == tmp;". If a, b are speculated integer then */\
142     /* this is only true if we do the overflow check - hence the need to keep it alive. More */\
143     /* generally, we need to keep alive any operation whose checks cause filtration in AI. */\
144     macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
145     macro(ArithClz32, NodeResultInt32 | NodeMustGenerate) \
146     macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
147     macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
148     macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
149     macro(ArithIMul, NodeResultInt32) \
150     macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
151     macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
152     macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
153     macro(ArithMin, NodeResultNumber) \
154     macro(ArithMax, NodeResultNumber) \
155     macro(ArithFRound, NodeResultDouble | NodeMustGenerate) \
156     macro(ArithPow, NodeResultDouble) \
157     macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \
158     macro(ArithRound, NodeResultNumber | NodeMustGenerate) \
159     macro(ArithFloor, NodeResultNumber | NodeMustGenerate) \
160     macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
161     macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
162     macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
163     macro(ArithUnary, NodeResultDouble | NodeMustGenerate) \
164     \
165     /* Add of values may either be arithmetic, or result in string concatenation. */\
166     macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
167     \
168     /* Add of values that always convers its inputs to strings. May have two or three kids. */\
169     macro(StrCat, NodeResultJS | NodeMustGenerate) \
170     \
171     /* Property access. */\
172     /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
173     /* Since a put to 'length' may invalidate optimizations here, */\
174     /* this must be the directly subsequent property put. Note that PutByVal */\
175     /* opcodes use VarArgs beause they may have up to 4 children. */\
176     macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
177     macro(GetByValWithThis, NodeResultJS | NodeMustGenerate) \
178     macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
179     macro(GetMyArgumentByValOutOfBounds, NodeResultJS | NodeMustGenerate) \
180     macro(LoadVarargs, NodeMustGenerate) \
181     macro(ForwardVarargs, NodeMustGenerate) \
182     macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \
183     macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \
184     macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs) \
185     macro(TryGetById, NodeResultJS) \
186     macro(GetById, NodeResultJS | NodeMustGenerate) \
187     macro(GetByIdFlush, NodeResultJS | NodeMustGenerate) \
188     macro(GetByIdWithThis, NodeResultJS | NodeMustGenerate) \
189     macro(GetByIdDirect, NodeResultJS | NodeMustGenerate) \
190     macro(GetByIdDirectFlush, NodeResultJS | NodeMustGenerate) \
191     macro(PutById, NodeMustGenerate) \
192     macro(PutByIdFlush, NodeMustGenerate) \
193     macro(PutByIdDirect, NodeMustGenerate) \
194     macro(PutByIdWithThis, NodeMustGenerate) \
195     macro(PutByValWithThis, NodeMustGenerate | NodeHasVarArgs) \
196     macro(PutGetterById, NodeMustGenerate) \
197     macro(PutSetterById, NodeMustGenerate) \
198     macro(PutGetterSetterById, NodeMustGenerate) \
199     macro(PutGetterByVal, NodeMustGenerate) \
200     macro(PutSetterByVal, NodeMustGenerate) \
201     macro(DefineDataProperty, NodeMustGenerate | NodeHasVarArgs) \
202     macro(DefineAccessorProperty, NodeMustGenerate | NodeHasVarArgs) \
203     macro(DeleteById, NodeResultBoolean | NodeMustGenerate) \
204     macro(DeleteByVal, NodeResultBoolean | NodeMustGenerate) \
205     macro(CheckStructure, NodeMustGenerate) \
206     macro(CheckStructureOrEmpty, NodeMustGenerate) \
207     macro(GetExecutable, NodeResultJS) \
208     macro(PutStructure, NodeMustGenerate) \
209     macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
210     macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
211     macro(GetButterfly, NodeResultStorage) \
212     macro(NukeStructureAndSetButterfly, NodeMustGenerate) \
213     macro(CheckArray, NodeMustGenerate) \
214     macro(Arrayify, NodeMustGenerate) \
215     macro(ArrayifyToStructure, NodeMustGenerate) \
216     macro(GetIndexedPropertyStorage, NodeResultStorage) \
217     macro(ConstantStoragePointer, NodeResultStorage) \
218     macro(GetGetter, NodeResultJS) \
219     macro(GetSetter, NodeResultJS) \
220     macro(GetByOffset, NodeResultJS) \
221     macro(GetGetterSetterByOffset, NodeResultJS) \
222     macro(MultiGetByOffset, NodeResultJS | NodeMustGenerate) \
223     macro(PutByOffset, NodeMustGenerate) \
224     macro(MultiPutByOffset, NodeMustGenerate) \
225     macro(GetArrayLength, NodeResultInt32) \
226     macro(GetVectorLength, NodeResultInt32) \
227     macro(GetTypedArrayByteOffset, NodeResultInt32) \
228     macro(GetScope, NodeResultJS) \
229     macro(SkipScope, NodeResultJS) \
230     macro(ResolveScope, NodeResultJS | NodeMustGenerate) \
231     macro(ResolveScopeForHoistingFuncDeclInEval, NodeResultJS | NodeMustGenerate) \
232     macro(GetGlobalObject, NodeResultJS) \
233     macro(GetGlobalThis, NodeResultJS) \
234     macro(GetClosureVar, NodeResultJS) \
235     macro(PutClosureVar, NodeMustGenerate) \
236     macro(GetGlobalVar, NodeResultJS) \
237     macro(GetGlobalLexicalVariable, NodeResultJS) \
238     macro(PutGlobalVariable, NodeMustGenerate) \
239     macro(GetDynamicVar, NodeResultJS | NodeMustGenerate) \
240     macro(PutDynamicVar, NodeMustGenerate) \
241     macro(NotifyWrite, NodeMustGenerate) \
242     macro(GetRegExpObjectLastIndex, NodeResultJS) \
243     macro(SetRegExpObjectLastIndex, NodeMustGenerate) \
244     macro(RecordRegExpCachedResult, NodeMustGenerate | NodeHasVarArgs) \
245     macro(CheckCell, NodeMustGenerate) \
246     macro(CheckNotEmpty, NodeMustGenerate) \
247     macro(AssertNotEmpty, NodeMustGenerate) \
248     macro(CheckBadCell, NodeMustGenerate) \
249     macro(CheckInBounds, NodeMustGenerate) \
250     macro(CheckStringIdent, NodeMustGenerate) \
251     macro(CheckTypeInfoFlags, NodeMustGenerate) /* Takes an OpInfo with the flags you want to test are set */\
252     macro(CheckSubClass, NodeMustGenerate) \
253     macro(ParseInt, NodeMustGenerate | NodeResultJS) \
254     macro(GetPrototypeOf, NodeMustGenerate | NodeResultJS) \
255     \
256     /* Atomics object functions. */\
257     macro(AtomicsAdd, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
258     macro(AtomicsAnd, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
259     macro(AtomicsCompareExchange, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
260     macro(AtomicsExchange, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
261     macro(AtomicsIsLockFree, NodeResultBoolean) \
262     macro(AtomicsLoad, NodeResultJS | NodeMustGenerate) \
263     macro(AtomicsOr, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
264     macro(AtomicsStore, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
265     macro(AtomicsSub, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
266     macro(AtomicsXor, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
267     \
268     /* Optimizations for array mutation. */\
269     macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
270     macro(ArrayPop, NodeResultJS | NodeMustGenerate) \
271     macro(ArraySlice, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
272     macro(ArrayIndexOf, NodeResultInt32 | NodeHasVarArgs) \
273     \
274     /* Optimizations for regular expression matching. */\
275     macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
276     macro(RegExpExecNonGlobalOrSticky, NodeResultJS) \
277     macro(RegExpTest, NodeResultJS | NodeMustGenerate) \
278     macro(RegExpMatchFast, NodeResultJS | NodeMustGenerate) \
279     macro(RegExpMatchFastGlobal, NodeResultJS) \
280     macro(StringReplace, NodeResultJS | NodeMustGenerate) \
281     macro(StringReplaceRegExp, NodeResultJS | NodeMustGenerate) \
282     \
283     /* Optimizations for string access */ \
284     macro(StringCharCodeAt, NodeResultInt32) \
285     macro(StringCharAt, NodeResultJS) \
286     macro(StringFromCharCode, NodeResultJS | NodeMustGenerate) \
287     \
288     /* Nodes for comparison operations. */\
289     macro(CompareLess, NodeResultBoolean | NodeMustGenerate) \
290     macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate) \
291     macro(CompareGreater, NodeResultBoolean | NodeMustGenerate) \
292     macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate) \
293     macro(CompareBelow, NodeResultBoolean) \
294     macro(CompareBelowEq, NodeResultBoolean) \
295     macro(CompareEq, NodeResultBoolean | NodeMustGenerate) \
296     macro(CompareStrictEq, NodeResultBoolean) \
297     macro(CompareEqPtr, NodeResultBoolean) \
298     macro(SameValue, NodeResultBoolean) \
299     \
300     /* Calls. */\
301     macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
302     macro(DirectCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
303     macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
304     macro(DirectConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
305     macro(CallVarargs, NodeResultJS | NodeMustGenerate) \
306     macro(CallForwardVarargs, NodeResultJS | NodeMustGenerate) \
307     macro(ConstructVarargs, NodeResultJS | NodeMustGenerate) \
308     macro(ConstructForwardVarargs, NodeResultJS | NodeMustGenerate) \
309     macro(TailCallInlinedCaller, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
310     macro(DirectTailCallInlinedCaller, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
311     macro(TailCallVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
312     macro(TailCallForwardVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
313     macro(CallEval, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
314     \
315     /* Shadow Chicken */\
316     macro(LogShadowChickenPrologue, NodeMustGenerate) \
317     macro(LogShadowChickenTail, NodeMustGenerate) \
318     \
319     /* Allocations. */\
320     macro(NewObject, NodeResultJS) \
321     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
322     macro(NewArrayWithSpread, NodeResultJS | NodeHasVarArgs) \
323     macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
324     macro(NewArrayBuffer, NodeResultJS) \
325     macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
326     macro(NewRegexp, NodeResultJS) \
327     /* Rest Parameter */\
328     macro(GetRestLength, NodeResultInt32) \
329     macro(CreateRest, NodeResultJS | NodeMustGenerate) \
330     \
331     macro(Spread, NodeResultJS | NodeMustGenerate) \
332     /* Support for allocation sinking. */\
333     macro(PhantomNewObject, NodeResultJS | NodeMustGenerate) \
334     macro(PutHint, NodeMustGenerate) \
335     macro(CheckStructureImmediate, NodeMustGenerate) \
336     macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
337     macro(PhantomNewFunction, NodeResultJS | NodeMustGenerate) \
338     macro(PhantomNewGeneratorFunction, NodeResultJS | NodeMustGenerate) \
339     macro(PhantomNewAsyncFunction, NodeResultJS | NodeMustGenerate) \
340     macro(PhantomNewAsyncGeneratorFunction, NodeResultJS | NodeMustGenerate) \
341     macro(PhantomCreateActivation, NodeResultJS | NodeMustGenerate) \
342     macro(MaterializeCreateActivation, NodeResultJS | NodeHasVarArgs) \
343     macro(PhantomNewRegexp, NodeResultJS | NodeMustGenerate) \
344     \
345     /* Nodes for misc operations. */\
346     macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
347     macro(InstanceOf, NodeMustGenerate | NodeResultBoolean) \
348     macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
349     macro(MatchStructure, NodeMustGenerate | NodeResultBoolean) \
350     \
351     macro(IsCellWithType, NodeResultBoolean) \
352     macro(IsEmpty, NodeResultBoolean) \
353     macro(IsUndefined, NodeResultBoolean) \
354     macro(IsBoolean, NodeResultBoolean) \
355     macro(IsNumber, NodeResultBoolean) \
356     macro(NumberIsInteger, NodeResultBoolean) \
357     macro(IsObject, NodeResultBoolean) \
358     macro(IsObjectOrNull, NodeResultBoolean) \
359     macro(IsFunction, NodeResultBoolean) \
360     macro(IsTypedArrayView, NodeResultBoolean) \
361     macro(TypeOf, NodeResultJS) \
362     macro(LogicalNot, NodeResultBoolean) \
363     macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
364     macro(ToString, NodeResultJS | NodeMustGenerate) \
365     macro(ToNumber, NodeResultJS | NodeMustGenerate) \
366     macro(ToObject, NodeResultJS | NodeMustGenerate) \
367     macro(CallObjectConstructor, NodeResultJS) \
368     macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
369     macro(NumberToStringWithRadix, NodeResultJS | NodeMustGenerate) \
370     macro(NumberToStringWithValidRadixConstant, NodeResultJS) \
371     macro(NewStringObject, NodeResultJS) \
372     macro(MakeRope, NodeResultJS) \
373     macro(InByVal, NodeResultBoolean | NodeMustGenerate) \
374     macro(InById, NodeResultBoolean | NodeMustGenerate) \
375     macro(ProfileType, NodeMustGenerate) \
376     macro(ProfileControlFlow, NodeMustGenerate) \
377     macro(SetFunctionName, NodeMustGenerate) \
378     macro(HasOwnProperty, NodeResultBoolean) \
379     \
380     macro(CreateActivation, NodeResultJS) \
381     macro(PushWithScope, NodeResultJS | NodeMustGenerate) \
382     \
383     macro(CreateDirectArguments, NodeResultJS) \
384     macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
385     macro(PhantomCreateRest, NodeResultJS | NodeMustGenerate) \
386     macro(PhantomSpread, NodeResultJS | NodeMustGenerate) \
387     macro(PhantomNewArrayWithSpread, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
388     macro(PhantomNewArrayBuffer, NodeResultJS | NodeMustGenerate) \
389     macro(CreateScopedArguments, NodeResultJS) \
390     macro(CreateClonedArguments, NodeResultJS) \
391     macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
392     macro(GetFromArguments, NodeResultJS) \
393     macro(PutToArguments, NodeMustGenerate) \
394     macro(GetArgument, NodeResultJS) \
395     \
396     macro(NewFunction, NodeResultJS) \
397     \
398     macro(NewGeneratorFunction, NodeResultJS) \
399     \
400     macro(NewAsyncGeneratorFunction, NodeResultJS) \
401     \
402     macro(NewAsyncFunction, NodeResultJS) \
403     \
404     /* Block terminals. */\
405     macro(Jump, NodeMustGenerate) \
406     macro(Branch, NodeMustGenerate) \
407     macro(Switch, NodeMustGenerate) \
408     macro(EntrySwitch, NodeMustGenerate) \
409     macro(Return, NodeMustGenerate) \
410     macro(TailCall, NodeMustGenerate | NodeHasVarArgs) \
411     macro(DirectTailCall, NodeMustGenerate | NodeHasVarArgs) \
412     macro(TailCallVarargs, NodeMustGenerate) \
413     macro(TailCallForwardVarargs, NodeMustGenerate) \
414     macro(Unreachable, NodeMustGenerate) \
415     macro(Throw, NodeMustGenerate) \
416     macro(ThrowStaticError, NodeMustGenerate) \
417     \
418     /* Count execution. */\
419     macro(CountExecution, NodeMustGenerate) \
420     /* Super sampler. */\
421     macro(SuperSamplerBegin, NodeMustGenerate) \
422     macro(SuperSamplerEnd, NodeMustGenerate) \
423     \
424     /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
425     /* this point, but execution does continue in the basic block - just in a */\
426     /* different compiler. */\
427     macro(ForceOSRExit, NodeMustGenerate) \
428     \
429     /* Vends a bottom JS value. It is invalid to ever execute this. Useful for cases */\
430     /* where we know that we would have exited but we'd like to still track the control */\
431     /* flow. */\
432     macro(BottomValue, NodeResultJS) \
433     \
434     /* Checks for VM traps. If there is a trap, we'll jettison or call operation operationHandleTraps. */ \
435     macro(CheckTraps, NodeMustGenerate) \
436     /* Write barriers */\
437     macro(StoreBarrier, NodeMustGenerate) \
438     macro(FencedStoreBarrier, NodeMustGenerate) \
439     \
440     /* For-in enumeration opcodes */\
441     macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
442     macro(HasIndexedProperty, NodeResultBoolean) \
443     macro(HasStructureProperty, NodeResultBoolean) \
444     macro(HasGenericProperty, NodeResultBoolean) \
445     macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
446     macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
447     macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
448     macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
449     macro(ToIndexString, NodeResultJS) \
450     /* Nodes for JSMap and JSSet */ \
451     macro(MapHash, NodeResultInt32) \
452     macro(NormalizeMapKey, NodeResultJS) \
453     macro(GetMapBucket, NodeResultJS) \
454     macro(GetMapBucketHead, NodeResultJS) \
455     macro(GetMapBucketNext, NodeResultJS) \
456     macro(LoadKeyFromMapBucket, NodeResultJS) \
457     macro(LoadValueFromMapBucket, NodeResultJS) \
458     macro(SetAdd, NodeMustGenerate | NodeResultJS) \
459     macro(MapSet, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
460     /* Nodes for JSWeakMap and JSWeakSet */ \
461     macro(WeakMapGet, NodeResultJS) \
462     macro(WeakSetAdd, NodeMustGenerate) \
463     macro(WeakMapSet, NodeMustGenerate | NodeHasVarArgs) \
464     macro(ExtractValueFromWeakMapGet, NodeResultJS) \
465     \
466     macro(StringSlice, NodeResultJS) \
467     macro(ToLowerCase, NodeResultJS) \
468     /* Nodes for DOM JIT */\
469     macro(CallDOMGetter, NodeResultJS | NodeMustGenerate) \
470     macro(CallDOM, NodeResultJS | NodeMustGenerate) \
471     /* Metadata node that initializes the state for flushed argument types at an entrypoint in the program. */ \
472     /* Currently, we only use this for the blocks an EntrySwitch branches to at the root of the program. */ \
473     /* This is only used in SSA. */ \
474     macro(InitializeEntrypointArguments, NodeMustGenerate) \
475     \
476     /* Used for $vm performance debugging */ \
477     macro(CPUIntrinsic, NodeResultJS | NodeMustGenerate) \
478
479
480 // This enum generates a monotonically increasing id for all Node types,
481 // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
482 enum NodeType {
483 #define DFG_OP_ENUM(opcode, flags) opcode,
484     FOR_EACH_DFG_OP(DFG_OP_ENUM)
485 #undef DFG_OP_ENUM
486     LastNodeType
487 };
488
489 // Specifies the default flags for each node.
490 inline NodeFlags defaultFlags(NodeType op)
491 {
492     switch (op) {
493 #define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
494     FOR_EACH_DFG_OP(DFG_OP_ENUM)
495 #undef DFG_OP_ENUM
496     default:
497         RELEASE_ASSERT_NOT_REACHED();
498         return 0;
499     }
500 }
501
502 inline bool isAtomicsIntrinsic(NodeType op)
503 {
504     switch (op) {
505     case AtomicsAdd:
506     case AtomicsAnd:
507     case AtomicsCompareExchange:
508     case AtomicsExchange:
509     case AtomicsLoad:
510     case AtomicsOr:
511     case AtomicsStore:
512     case AtomicsSub:
513     case AtomicsXor:
514     case AtomicsIsLockFree:
515         return true;
516     default:
517         return false;
518     }
519 }
520
521 static const unsigned maxNumExtraAtomicsArgs = 2;
522
523 inline unsigned numExtraAtomicsArgs(NodeType op)
524 {
525     switch (op) {
526     case AtomicsLoad:
527         return 0;
528     case AtomicsAdd:
529     case AtomicsAnd:
530     case AtomicsExchange:
531     case AtomicsOr:
532     case AtomicsStore:
533     case AtomicsSub:
534     case AtomicsXor:
535         return 1;
536     case AtomicsCompareExchange:
537         return 2;
538     default:
539         RELEASE_ASSERT_NOT_REACHED();
540         return 0;
541     }
542 }
543
544 } } // namespace JSC::DFG
545
546 #endif // ENABLE(DFG_JIT)