2 * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
30 #include "DFGNodeFlags.h"
32 namespace JSC { namespace DFG {
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) \
39 /* Constants with specific representations. */\
40 macro(DoubleConstant, NodeResultDouble) \
41 macro(Int52Constant, NodeResultInt52) \
43 /* Lazy JSValue constant. We don't know the JSValue bits of it yet. */\
44 macro(LazyJSConstant, NodeResultJS) \
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) \
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(GetArgumentCountIncludingThis, NodeResultInt32) \
59 /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\
60 /* Any two nodes that are part of the same Phi graph will share the same */\
61 /* VariableAccessData, and thus will share predictions. FIXME: We should come up with */\
62 /* better names for a lot of these. https://bugs.webkit.org/show_bug.cgi?id=137307. */\
63 /* Note that GetLocal is MustGenerate because it's our only way of knowing that some other */\
64 /* basic block might have read a local variable in bytecode. We only remove GetLocals if it */\
65 /* is redundant because of an earlier GetLocal or SetLocal in the same block. We could make */\
66 /* these not MustGenerate and use a more sophisticated analysis to insert PhantomLocals in */\
67 /* the same way that we insert Phantoms. That's hard and probably not profitable. See */\
68 /* https://bugs.webkit.org/show_bug.cgi?id=144086 */\
69 macro(GetLocal, NodeResultJS | NodeMustGenerate) \
72 macro(PutStack, NodeMustGenerate) \
73 macro(KillStack, NodeMustGenerate) \
74 macro(GetStack, NodeResultJS) \
76 macro(MovHint, NodeMustGenerate) \
77 macro(ZombieHint, NodeMustGenerate) \
78 macro(ExitOK, NodeMustGenerate) /* Indicates that exit state is intact. */ \
79 macro(Phantom, NodeMustGenerate) \
80 macro(Check, NodeMustGenerate) /* Used if we want just a type check but not liveness. Non-checking uses will be removed. */\
83 macro(Flush, NodeMustGenerate) \
84 macro(PhantomLocal, NodeMustGenerate) \
86 /* Hint that this is where bytecode thinks is a good place to OSR. Note that this */\
87 /* will exist even in inlined loops. This has no execution semantics but it must */\
88 /* survive all DCE. We treat this as being a can-exit because tier-up to FTL may */\
89 /* want all state. */\
90 macro(LoopHint, NodeMustGenerate) \
92 /* Special node for OSR entry into the FTL. Indicates that we're loading a local */\
93 /* variable from the scratch buffer. */\
94 macro(ExtractOSREntryLocal, NodeResultJS) \
95 macro(ExtractCatchLocal, NodeResultJS) \
97 /* Tier-up checks from the DFG to the FTL. */\
98 macro(CheckTierUpInLoop, NodeMustGenerate) \
99 macro(CheckTierUpAndOSREnter, NodeMustGenerate) \
100 macro(CheckTierUpAtReturn, NodeMustGenerate) \
102 /* Get the value of a local variable, without linking into the VariableAccessData */\
103 /* network. This is only valid for variable accesses whose predictions originated */\
104 /* as something other than a local access, and thus had their own profiling. */\
105 macro(GetLocalUnlinked, NodeResultJS) \
107 /* Marker for an argument being set at the prologue of a function. */\
108 macro(SetArgument, 0) \
110 /* Marker of location in the IR where we may possibly perform jump replacement to */\
111 /* invalidate this code block. */\
112 macro(InvalidationPoint, NodeMustGenerate) \
114 /* Nodes for bitwise operations. */\
115 macro(BitAnd, NodeResultInt32) \
116 macro(BitOr, NodeResultInt32) \
117 macro(BitXor, NodeResultInt32) \
118 macro(BitLShift, NodeResultInt32) \
119 macro(BitRShift, NodeResultInt32) \
120 macro(BitURShift, NodeResultInt32) \
121 /* Bitwise operators call ToInt32 on their operands. */\
122 macro(ValueToInt32, NodeResultInt32) \
123 /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
124 macro(UInt32ToNumber, NodeResultNumber) \
125 /* Converts booleans to numbers but passes everything else through. */\
126 macro(BooleanToNumber, NodeResultJS) \
128 /* Attempt to truncate a double to int32; this will exit if it can't do it. */\
129 macro(DoubleAsInt32, NodeResultInt32) \
131 /* Change the representation of a value. */\
132 macro(DoubleRep, NodeResultDouble) \
133 macro(Int52Rep, NodeResultInt52) \
134 macro(ValueRep, NodeResultJS) \
136 /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
137 macro(FiatInt52, NodeResultJS) \
139 /* Nodes for arithmetic operations. Note that if they do checks other than just type checks, */\
140 /* then they are MustGenerate. This is probably stricter than it needs to be - for example */\
141 /* they won't do checks if they are speculated double. Also, we could kill these if we do it */\
142 /* before AI starts eliminating downstream operations based on proofs, for example in the */\
143 /* case of "var tmp = a + b; return (tmp | 0) == tmp;". If a, b are speculated integer then */\
144 /* this is only true if we do the overflow check - hence the need to keep it alive. More */\
145 /* generally, we need to keep alive any operation whose checks cause filtration in AI. */\
146 macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
147 macro(ArithClz32, NodeResultInt32 | NodeMustGenerate) \
148 macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
149 macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
150 macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
151 macro(ArithIMul, NodeResultInt32) \
152 macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
153 macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
154 macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
155 macro(ArithMin, NodeResultNumber) \
156 macro(ArithMax, NodeResultNumber) \
157 macro(ArithFRound, NodeResultDouble | NodeMustGenerate) \
158 macro(ArithPow, NodeResultDouble) \
159 macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \
160 macro(ArithRound, NodeResultNumber | NodeMustGenerate) \
161 macro(ArithFloor, NodeResultNumber | NodeMustGenerate) \
162 macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
163 macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
164 macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
165 macro(ArithUnary, NodeResultDouble | NodeMustGenerate) \
167 /* Add of values may either be arithmetic, or result in string concatenation. */\
168 macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
170 /* Add of values that always convers its inputs to strings. May have two or three kids. */\
171 macro(StrCat, NodeResultJS | NodeMustGenerate) \
173 /* Property access. */\
174 /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
175 /* Since a put to 'length' may invalidate optimizations here, */\
176 /* this must be the directly subsequent property put. Note that PutByVal */\
177 /* opcodes use VarArgs beause they may have up to 4 children. */\
178 macro(GetByVal, NodeResultJS | NodeMustGenerate) \
179 macro(GetByValWithThis, NodeResultJS | NodeMustGenerate) \
180 macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
181 macro(GetMyArgumentByValOutOfBounds, NodeResultJS | NodeMustGenerate) \
182 macro(LoadVarargs, NodeMustGenerate) \
183 macro(ForwardVarargs, NodeMustGenerate) \
184 macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \
185 macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \
186 macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs) \
187 macro(TryGetById, NodeResultJS) \
188 macro(GetById, NodeResultJS | NodeMustGenerate) \
189 macro(GetByIdFlush, NodeResultJS | NodeMustGenerate) \
190 macro(GetByIdWithThis, 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(GetButterflyWithoutCaging, NodeResultStorage) \
213 macro(NukeStructureAndSetButterfly, NodeMustGenerate) \
214 macro(CheckArray, NodeMustGenerate) \
215 macro(Arrayify, NodeMustGenerate) \
216 macro(ArrayifyToStructure, NodeMustGenerate) \
217 macro(GetIndexedPropertyStorage, NodeResultStorage) \
218 macro(ConstantStoragePointer, NodeResultStorage) \
219 macro(GetGetter, NodeResultJS) \
220 macro(GetSetter, NodeResultJS) \
221 macro(GetByOffset, NodeResultJS) \
222 macro(GetGetterSetterByOffset, NodeResultJS) \
223 macro(MultiGetByOffset, NodeResultJS | NodeMustGenerate) \
224 macro(PutByOffset, NodeMustGenerate) \
225 macro(MultiPutByOffset, NodeMustGenerate) \
226 macro(GetArrayLength, NodeResultInt32) \
227 macro(GetVectorLength, NodeResultInt32) \
228 macro(GetTypedArrayByteOffset, NodeResultInt32) \
229 macro(GetScope, NodeResultJS) \
230 macro(SkipScope, NodeResultJS) \
231 macro(ResolveScope, NodeResultJS | NodeMustGenerate) \
232 macro(ResolveScopeForHoistingFuncDeclInEval, NodeResultJS | NodeMustGenerate) \
233 macro(GetGlobalObject, NodeResultJS) \
234 macro(GetGlobalThis, NodeResultJS) \
235 macro(GetClosureVar, NodeResultJS) \
236 macro(PutClosureVar, NodeMustGenerate) \
237 macro(GetGlobalVar, NodeResultJS) \
238 macro(GetGlobalLexicalVariable, NodeResultJS) \
239 macro(PutGlobalVariable, NodeMustGenerate) \
240 macro(GetDynamicVar, NodeResultJS | NodeMustGenerate) \
241 macro(PutDynamicVar, NodeMustGenerate) \
242 macro(NotifyWrite, NodeMustGenerate) \
243 macro(GetRegExpObjectLastIndex, NodeResultJS) \
244 macro(SetRegExpObjectLastIndex, NodeMustGenerate) \
245 macro(RecordRegExpCachedResult, NodeMustGenerate | NodeHasVarArgs) \
246 macro(CheckCell, NodeMustGenerate) \
247 macro(CheckNotEmpty, 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) \
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) \
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) \
274 /* Optimizations for regular expression matching. */\
275 macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
276 macro(RegExpTest, NodeResultJS | NodeMustGenerate) \
277 macro(StringReplace, NodeResultJS | NodeMustGenerate) \
278 macro(StringReplaceRegExp, NodeResultJS | NodeMustGenerate) \
280 /* Optimizations for string access */ \
281 macro(StringCharCodeAt, NodeResultInt32) \
282 macro(StringCharAt, NodeResultJS) \
283 macro(StringFromCharCode, NodeResultJS) \
285 /* Nodes for comparison operations. */\
286 macro(CompareLess, NodeResultBoolean | NodeMustGenerate) \
287 macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate) \
288 macro(CompareGreater, NodeResultBoolean | NodeMustGenerate) \
289 macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate) \
290 macro(CompareBelow, NodeResultBoolean) \
291 macro(CompareBelowEq, NodeResultBoolean) \
292 macro(CompareEq, NodeResultBoolean | NodeMustGenerate) \
293 macro(CompareStrictEq, NodeResultBoolean) \
294 macro(CompareEqPtr, NodeResultBoolean) \
297 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
298 macro(DirectCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
299 macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
300 macro(DirectConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
301 macro(CallVarargs, NodeResultJS | NodeMustGenerate) \
302 macro(CallForwardVarargs, NodeResultJS | NodeMustGenerate) \
303 macro(ConstructVarargs, NodeResultJS | NodeMustGenerate) \
304 macro(ConstructForwardVarargs, NodeResultJS | NodeMustGenerate) \
305 macro(TailCallInlinedCaller, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
306 macro(DirectTailCallInlinedCaller, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
307 macro(TailCallVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
308 macro(TailCallForwardVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
309 macro(CallEval, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
311 /* Shadow Chicken */\
312 macro(LogShadowChickenPrologue, NodeMustGenerate) \
313 macro(LogShadowChickenTail, NodeMustGenerate) \
316 macro(NewObject, NodeResultJS) \
317 macro(NewArray, NodeResultJS | NodeHasVarArgs) \
318 macro(NewArrayWithSpread, NodeResultJS | NodeHasVarArgs) \
319 macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
320 macro(NewArrayBuffer, NodeResultJS) \
321 macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
322 macro(NewRegexp, NodeResultJS) \
323 /* Rest Parameter */\
324 macro(GetRestLength, NodeResultInt32) \
325 macro(CreateRest, NodeResultJS | NodeMustGenerate) \
327 macro(Spread, NodeResultJS | NodeMustGenerate) \
328 /* Support for allocation sinking. */\
329 macro(PhantomNewObject, NodeResultJS | NodeMustGenerate) \
330 macro(PutHint, NodeMustGenerate) \
331 macro(CheckStructureImmediate, NodeMustGenerate) \
332 macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
333 macro(PhantomNewFunction, NodeResultJS | NodeMustGenerate) \
334 macro(PhantomNewGeneratorFunction, NodeResultJS | NodeMustGenerate) \
335 macro(PhantomNewAsyncFunction, NodeResultJS | NodeMustGenerate) \
336 macro(PhantomNewAsyncGeneratorFunction, NodeResultJS | NodeMustGenerate) \
337 macro(PhantomCreateActivation, NodeResultJS | NodeMustGenerate) \
338 macro(MaterializeCreateActivation, NodeResultJS | NodeHasVarArgs) \
340 /* Nodes for misc operations. */\
341 macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
342 macro(InstanceOf, NodeResultBoolean) \
343 macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
345 macro(IsCellWithType, NodeResultBoolean) \
346 macro(IsEmpty, NodeResultBoolean) \
347 macro(IsUndefined, NodeResultBoolean) \
348 macro(IsBoolean, NodeResultBoolean) \
349 macro(IsNumber, NodeResultBoolean) \
350 macro(IsObject, NodeResultBoolean) \
351 macro(IsObjectOrNull, NodeResultBoolean) \
352 macro(IsFunction, NodeResultBoolean) \
353 macro(IsTypedArrayView, NodeResultBoolean) \
354 macro(TypeOf, NodeResultJS) \
355 macro(LogicalNot, NodeResultBoolean) \
356 macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
357 macro(ToString, NodeResultJS | NodeMustGenerate) \
358 macro(ToNumber, NodeResultJS | NodeMustGenerate) \
359 macro(ToObject, NodeResultJS | NodeMustGenerate) \
360 macro(CallObjectConstructor, NodeResultJS) \
361 macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
362 macro(NumberToStringWithRadix, NodeResultJS | NodeMustGenerate) \
363 macro(NumberToStringWithValidRadixConstant, NodeResultJS) \
364 macro(NewStringObject, NodeResultJS) \
365 macro(MakeRope, NodeResultJS) \
366 macro(In, NodeResultBoolean | NodeMustGenerate) \
367 macro(ProfileType, NodeMustGenerate) \
368 macro(ProfileControlFlow, NodeMustGenerate) \
369 macro(SetFunctionName, NodeMustGenerate) \
370 macro(HasOwnProperty, NodeResultBoolean) \
372 macro(CreateActivation, NodeResultJS) \
373 macro(PushWithScope, NodeResultJS | NodeMustGenerate) \
375 macro(CreateDirectArguments, NodeResultJS) \
376 macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
377 macro(PhantomCreateRest, NodeResultJS | NodeMustGenerate) \
378 macro(PhantomSpread, NodeResultJS | NodeMustGenerate) \
379 macro(PhantomNewArrayWithSpread, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
380 macro(CreateScopedArguments, NodeResultJS) \
381 macro(CreateClonedArguments, NodeResultJS) \
382 macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
383 macro(GetFromArguments, NodeResultJS) \
384 macro(PutToArguments, NodeMustGenerate) \
385 macro(GetArgument, NodeResultJS) \
387 macro(NewFunction, NodeResultJS) \
389 macro(NewGeneratorFunction, NodeResultJS) \
391 macro(NewAsyncGeneratorFunction, NodeResultJS) \
393 macro(NewAsyncFunction, NodeResultJS) \
395 /* Block terminals. */\
396 macro(Jump, NodeMustGenerate) \
397 macro(Branch, NodeMustGenerate) \
398 macro(Switch, NodeMustGenerate) \
399 macro(EntrySwitch, NodeMustGenerate) \
400 macro(Return, NodeMustGenerate) \
401 macro(TailCall, NodeMustGenerate | NodeHasVarArgs) \
402 macro(DirectTailCall, NodeMustGenerate | NodeHasVarArgs) \
403 macro(TailCallVarargs, NodeMustGenerate) \
404 macro(TailCallForwardVarargs, NodeMustGenerate) \
405 macro(Unreachable, NodeMustGenerate) \
406 macro(Throw, NodeMustGenerate) \
407 macro(ThrowStaticError, NodeMustGenerate) \
409 /* Count execution. */\
410 macro(CountExecution, NodeMustGenerate) \
411 /* Super sampler. */\
412 macro(SuperSamplerBegin, NodeMustGenerate) \
413 macro(SuperSamplerEnd, NodeMustGenerate) \
415 /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
416 /* this point, but execution does continue in the basic block - just in a */\
417 /* different compiler. */\
418 macro(ForceOSRExit, NodeMustGenerate) \
420 /* Vends a bottom JS value. It is invalid to ever execute this. Useful for cases */\
421 /* where we know that we would have exited but we'd like to still track the control */\
423 macro(BottomValue, NodeResultJS) \
425 /* Checks for VM traps. If there is a trap, we'll jettison or call operation operationHandleTraps. */ \
426 macro(CheckTraps, NodeMustGenerate) \
427 /* Write barriers */\
428 macro(StoreBarrier, NodeMustGenerate) \
429 macro(FencedStoreBarrier, NodeMustGenerate) \
431 /* For-in enumeration opcodes */\
432 macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
433 macro(HasIndexedProperty, NodeResultBoolean) \
434 macro(HasStructureProperty, NodeResultBoolean) \
435 macro(HasGenericProperty, NodeResultBoolean) \
436 macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
437 macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
438 macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
439 macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
440 macro(ToIndexString, NodeResultJS) \
441 /* Nodes for JSMap and JSSet */ \
442 macro(MapHash, NodeResultInt32) \
443 macro(GetMapBucket, NodeResultJS) \
444 macro(GetMapBucketHead, NodeResultJS) \
445 macro(GetMapBucketNext, NodeResultJS) \
446 macro(LoadKeyFromMapBucket, NodeResultJS) \
447 macro(LoadValueFromMapBucket, NodeResultJS) \
448 macro(SetAdd, NodeMustGenerate) \
449 macro(MapSet, NodeMustGenerate | NodeHasVarArgs) \
450 /* Nodes for JSWeakMap and JSWeakSet */ \
451 macro(WeakMapGet, NodeResultJS) \
453 macro(StringSlice, NodeResultJS) \
454 macro(ToLowerCase, NodeResultJS) \
455 /* Nodes for DOM JIT */\
456 macro(CallDOMGetter, NodeResultJS | NodeMustGenerate) \
457 macro(CallDOM, NodeResultJS | NodeMustGenerate) \
458 /* Metadata node that initializes the state for flushed argument types at an entrypoint in the program. */ \
459 /* Currently, we only use this for the blocks an EntrySwitch branches to at the root of the program. */ \
460 /* This is only used in SSA. */ \
461 macro(InitializeEntrypointArguments, NodeMustGenerate) \
463 /* Used for $vm performance debugging */ \
464 macro(CPUIntrinsic, NodeResultJS | NodeMustGenerate) \
467 // This enum generates a monotonically increasing id for all Node types,
468 // and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
470 #define DFG_OP_ENUM(opcode, flags) opcode,
471 FOR_EACH_DFG_OP(DFG_OP_ENUM)
476 // Specifies the default flags for each node.
477 inline NodeFlags defaultFlags(NodeType op)
480 #define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
481 FOR_EACH_DFG_OP(DFG_OP_ENUM)
484 RELEASE_ASSERT_NOT_REACHED();
489 inline bool isAtomicsIntrinsic(NodeType op)
494 case AtomicsCompareExchange:
495 case AtomicsExchange:
501 case AtomicsIsLockFree:
508 static const unsigned maxNumExtraAtomicsArgs = 2;
510 inline unsigned numExtraAtomicsArgs(NodeType op)
517 case AtomicsExchange:
523 case AtomicsCompareExchange:
526 RELEASE_ASSERT_NOT_REACHED();
531 } } // namespace JSC::DFG
533 #endif // ENABLE(DFG_JIT)