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
32namespace 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 macro(ClearCatchLocals, NodeMustGenerate) \
100 \
101 /* Tier-up checks from the DFG to the FTL. */\
102 macro(CheckTierUpInLoop, NodeMustGenerate) \
103 macro(CheckTierUpAndOSREnter, NodeMustGenerate) \
104 macro(CheckTierUpAtReturn, NodeMustGenerate) \
105 \
106 /* Marker for an argument being set at the prologue of a function. The argument is guaranteed to be set after this node. */\
107 macro(SetArgumentDefinitely, 0) \
108 /* A marker like the above that we use to track variable liveness and OSR exit state. However, it's not guaranteed to be set. To verify it was set, you'd need to check the actual argument length. We use this for varargs when we're unsure how many argument may actually end up on the stack. */\
109 macro(SetArgumentMaybe, 0) \
110 \
111 /* Marker of location in the IR where we may possibly perform jump replacement to */\
112 /* invalidate this code block. */\
113 macro(InvalidationPoint, NodeMustGenerate) \
114 \
115 /* Nodes for bitwise operations. */\
116 macro(ValueBitNot, NodeResultJS | NodeMustGenerate) \
117 macro(ArithBitNot, NodeResultInt32) \
118 macro(ValueBitAnd, NodeResultJS | NodeMustGenerate) \
119 macro(ArithBitAnd, NodeResultInt32) \
120 macro(ValueBitOr, NodeResultJS | NodeMustGenerate) \
121 macro(ArithBitOr, NodeResultInt32) \
122 macro(ValueBitXor, NodeResultJS | NodeMustGenerate) \
123 macro(ArithBitXor, NodeResultInt32) \
124 macro(BitLShift, NodeResultInt32) \
125 macro(BitRShift, NodeResultInt32) \
126 macro(BitURShift, NodeResultInt32) \
127 /* Bitwise operators call ToInt32 on their operands. */\
128 macro(ValueToInt32, NodeResultInt32) \
129 /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\
130 macro(UInt32ToNumber, NodeResultNumber) \
131 /* Converts booleans to numbers but passes everything else through. */\
132 macro(BooleanToNumber, NodeResultJS) \
133 \
134 /* Attempt to truncate a double to int32; this will exit if it can't do it. */\
135 macro(DoubleAsInt32, NodeResultInt32) \
136 \
137 /* Change the representation of a value. */\
138 macro(DoubleRep, NodeResultDouble) \
139 macro(Int52Rep, NodeResultInt52) \
140 macro(ValueRep, NodeResultJS) \
141 \
142 /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\
143 macro(FiatInt52, NodeResultJS) \
144 \
145 /* Nodes for arithmetic operations. Note that if they do checks other than just type checks, */\
146 /* then they are MustGenerate. This is probably stricter than it needs to be - for example */\
147 /* they won't do checks if they are speculated double. Also, we could kill these if we do it */\
148 /* before AI starts eliminating downstream operations based on proofs, for example in the */\
149 /* case of "var tmp = a + b; return (tmp | 0) == tmp;". If a, b are speculated integer then */\
150 /* this is only true if we do the overflow check - hence the need to keep it alive. More */\
151 /* generally, we need to keep alive any operation whose checks cause filtration in AI. */\
152 macro(ArithAdd, NodeResultNumber | NodeMustGenerate) \
153 macro(ArithClz32, NodeResultInt32 | NodeMustGenerate) \
154 macro(ArithSub, NodeResultNumber | NodeMustGenerate) \
155 macro(ArithNegate, NodeResultNumber | NodeMustGenerate) \
156 macro(ArithMul, NodeResultNumber | NodeMustGenerate) \
157 macro(ArithIMul, NodeResultInt32) \
158 macro(ArithDiv, NodeResultNumber | NodeMustGenerate) \
159 macro(ArithMod, NodeResultNumber | NodeMustGenerate) \
160 macro(ArithAbs, NodeResultNumber | NodeMustGenerate) \
161 macro(ArithMin, NodeResultNumber) \
162 macro(ArithMax, NodeResultNumber) \
163 macro(ArithFRound, NodeResultDouble | NodeMustGenerate) \
164 macro(ArithPow, NodeResultDouble) \
165 macro(ArithRandom, NodeResultDouble | NodeMustGenerate) \
166 macro(ArithRound, NodeResultNumber | NodeMustGenerate) \
167 macro(ArithFloor, NodeResultNumber | NodeMustGenerate) \
168 macro(ArithCeil, NodeResultNumber | NodeMustGenerate) \
169 macro(ArithTrunc, NodeResultNumber | NodeMustGenerate) \
170 macro(ArithSqrt, NodeResultDouble | NodeMustGenerate) \
171 macro(ArithUnary, NodeResultDouble | NodeMustGenerate) \
172 \
173 /* BigInt is a valid operand for negate operations */\
174 macro(ValueNegate, NodeResultJS | NodeMustGenerate) \
175 \
176 /* Add of values may either be arithmetic, or result in string concatenation. */\
177 macro(ValueAdd, NodeResultJS | NodeMustGenerate) \
178 \
179 macro(ValueSub, NodeResultJS | NodeMustGenerate) \
180 macro(ValueMul, NodeResultJS | NodeMustGenerate) \
181 macro(ValueDiv, NodeResultJS | NodeMustGenerate) \
182 macro(ValueMod, NodeResultJS | NodeMustGenerate) \
183 \
184 /* Add of values that always convers its inputs to strings. May have two or three kids. */\
185 macro(StrCat, NodeResultJS | NodeMustGenerate) \
186 \
187 /* Property access. */\
188 /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\
189 /* Since a put to 'length' may invalidate optimizations here, */\
190 /* this must be the directly subsequent property put. Note that PutByVal */\
191 /* opcodes use VarArgs beause they may have up to 4 children. */\
192 macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
193 macro(GetByValWithThis, NodeResultJS | NodeMustGenerate) \
194 macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \
195 macro(GetMyArgumentByValOutOfBounds, NodeResultJS | NodeMustGenerate) \
196 macro(LoadVarargs, NodeMustGenerate) \
197 macro(ForwardVarargs, NodeMustGenerate) \
198 macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs) \
199 macro(PutByVal, NodeMustGenerate | NodeHasVarArgs) \
200 macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs) \
201 macro(TryGetById, NodeResultJS) \
202 macro(GetById, NodeResultJS | NodeMustGenerate) \
203 macro(GetByIdFlush, NodeResultJS | NodeMustGenerate) \
204 macro(GetByIdWithThis, NodeResultJS | NodeMustGenerate) \
205 macro(GetByIdDirect, NodeResultJS | NodeMustGenerate) \
206 macro(GetByIdDirectFlush, NodeResultJS | NodeMustGenerate) \
207 macro(PutById, NodeMustGenerate) \
208 macro(PutByIdFlush, NodeMustGenerate) \
209 macro(PutByIdDirect, NodeMustGenerate) \
210 macro(PutByIdWithThis, NodeMustGenerate) \
211 macro(PutByValWithThis, NodeMustGenerate | NodeHasVarArgs) \
212 macro(PutGetterById, NodeMustGenerate) \
213 macro(PutSetterById, NodeMustGenerate) \
214 macro(PutGetterSetterById, NodeMustGenerate) \
215 macro(PutGetterByVal, NodeMustGenerate) \
216 macro(PutSetterByVal, NodeMustGenerate) \
217 macro(DefineDataProperty, NodeMustGenerate | NodeHasVarArgs) \
218 macro(DefineAccessorProperty, NodeMustGenerate | NodeHasVarArgs) \
219 macro(DeleteById, NodeResultBoolean | NodeMustGenerate) \
220 macro(DeleteByVal, NodeResultBoolean | NodeMustGenerate) \
221 macro(CheckStructure, NodeMustGenerate) \
222 macro(CheckStructureOrEmpty, NodeMustGenerate) \
223 macro(GetExecutable, NodeResultJS) \
224 macro(PutStructure, NodeMustGenerate) \
225 macro(AllocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
226 macro(ReallocatePropertyStorage, NodeMustGenerate | NodeResultStorage) \
227 macro(GetButterfly, NodeResultStorage) \
228 macro(NukeStructureAndSetButterfly, NodeMustGenerate) \
229 macro(CheckArray, NodeMustGenerate) \
230 macro(Arrayify, NodeMustGenerate) \
231 macro(ArrayifyToStructure, NodeMustGenerate) \
232 macro(GetIndexedPropertyStorage, NodeResultStorage) \
233 macro(ConstantStoragePointer, NodeResultStorage) \
234 macro(GetGetter, NodeResultJS) \
235 macro(GetSetter, NodeResultJS) \
236 macro(GetByOffset, NodeResultJS) \
237 macro(GetGetterSetterByOffset, NodeResultJS) \
238 macro(MultiGetByOffset, NodeResultJS | NodeMustGenerate) \
239 macro(PutByOffset, NodeMustGenerate) \
240 macro(MultiPutByOffset, NodeMustGenerate) \
241 macro(GetArrayLength, NodeResultInt32) \
242 macro(GetVectorLength, NodeResultInt32) \
243 macro(GetTypedArrayByteOffset, NodeResultInt32) \
244 macro(GetScope, NodeResultJS) \
245 macro(SkipScope, NodeResultJS) \
246 macro(ResolveScope, NodeResultJS | NodeMustGenerate) \
247 macro(ResolveScopeForHoistingFuncDeclInEval, NodeResultJS | NodeMustGenerate) \
248 macro(GetGlobalObject, NodeResultJS) \
249 macro(GetGlobalThis, NodeResultJS) \
250 macro(GetClosureVar, NodeResultJS) \
251 macro(PutClosureVar, NodeMustGenerate) \
252 macro(GetGlobalVar, NodeResultJS) \
253 macro(GetGlobalLexicalVariable, NodeResultJS) \
254 macro(PutGlobalVariable, NodeMustGenerate) \
255 macro(GetDynamicVar, NodeResultJS | NodeMustGenerate) \
256 macro(PutDynamicVar, NodeMustGenerate) \
257 macro(NotifyWrite, NodeMustGenerate) \
258 macro(GetRegExpObjectLastIndex, NodeResultJS) \
259 macro(SetRegExpObjectLastIndex, NodeMustGenerate) \
260 macro(RecordRegExpCachedResult, NodeMustGenerate | NodeHasVarArgs) \
261 macro(CheckCell, NodeMustGenerate) \
262 macro(CheckNotEmpty, NodeMustGenerate) \
263 macro(AssertNotEmpty, NodeMustGenerate) \
264 macro(CheckBadCell, NodeMustGenerate) \
265 macro(CheckInBounds, NodeMustGenerate | NodeResultJS) \
266 macro(CheckStringIdent, NodeMustGenerate) \
267 macro(CheckTypeInfoFlags, NodeMustGenerate) /* Takes an OpInfo with the flags you want to test are set */\
268 macro(CheckSubClass, NodeMustGenerate) \
269 macro(ParseInt, NodeMustGenerate | NodeResultJS) \
270 macro(GetPrototypeOf, NodeMustGenerate | NodeResultJS) \
271 macro(ObjectCreate, NodeMustGenerate | NodeResultJS) \
272 macro(ObjectKeys, NodeMustGenerate | NodeResultJS) \
273 \
274 /* Atomics object functions. */\
275 macro(AtomicsAdd, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
276 macro(AtomicsAnd, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
277 macro(AtomicsCompareExchange, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
278 macro(AtomicsExchange, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
279 macro(AtomicsIsLockFree, NodeResultBoolean) \
280 macro(AtomicsLoad, NodeResultJS | NodeMustGenerate) \
281 macro(AtomicsOr, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
282 macro(AtomicsStore, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
283 macro(AtomicsSub, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
284 macro(AtomicsXor, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
285 \
286 /* Optimizations for array mutation. */\
287 macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
288 macro(ArrayPop, NodeResultJS | NodeMustGenerate) \
289 macro(ArraySlice, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
290 macro(ArrayIndexOf, NodeResultInt32 | NodeHasVarArgs) \
291 \
292 /* Optimizations for regular expression matching. */\
293 macro(RegExpExec, NodeResultJS | NodeMustGenerate) \
294 macro(RegExpExecNonGlobalOrSticky, NodeResultJS) \
295 macro(RegExpTest, NodeResultJS | NodeMustGenerate) \
296 macro(RegExpMatchFast, NodeResultJS | NodeMustGenerate) \
297 macro(RegExpMatchFastGlobal, NodeResultJS) \
298 macro(StringReplace, NodeResultJS | NodeMustGenerate) \
299 macro(StringReplaceRegExp, NodeResultJS | NodeMustGenerate) \
300 \
301 /* Optimizations for string access */ \
302 macro(StringCharCodeAt, NodeResultInt32) \
303 macro(StringCharAt, NodeResultJS) \
304 macro(StringFromCharCode, NodeResultJS | NodeMustGenerate) \
305 \
306 /* Nodes for comparison operations. */\
307 macro(CompareLess, NodeResultBoolean | NodeMustGenerate) \
308 macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate) \
309 macro(CompareGreater, NodeResultBoolean | NodeMustGenerate) \
310 macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate) \
311 macro(CompareBelow, NodeResultBoolean) \
312 macro(CompareBelowEq, NodeResultBoolean) \
313 macro(CompareEq, NodeResultBoolean | NodeMustGenerate) \
314 macro(CompareStrictEq, NodeResultBoolean) \
315 macro(CompareEqPtr, NodeResultBoolean) \
316 macro(SameValue, NodeResultBoolean) \
317 \
318 /* Calls. */\
319 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
320 macro(DirectCall, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
321 macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
322 macro(DirectConstruct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
323 macro(CallVarargs, NodeResultJS | NodeMustGenerate) \
324 macro(CallForwardVarargs, NodeResultJS | NodeMustGenerate) \
325 macro(ConstructVarargs, NodeResultJS | NodeMustGenerate) \
326 macro(ConstructForwardVarargs, NodeResultJS | NodeMustGenerate) \
327 macro(TailCallInlinedCaller, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
328 macro(DirectTailCallInlinedCaller, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
329 macro(TailCallVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
330 macro(TailCallForwardVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
331 macro(CallEval, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
332 \
333 /* Shadow Chicken */\
334 macro(LogShadowChickenPrologue, NodeMustGenerate) \
335 macro(LogShadowChickenTail, NodeMustGenerate) \
336 \
337 /* Allocations. */\
338 macro(NewObject, NodeResultJS) \
339 macro(NewArray, NodeResultJS | NodeHasVarArgs) \
340 macro(NewArrayWithSpread, NodeResultJS | NodeHasVarArgs) \
341 macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \
342 macro(NewArrayBuffer, NodeResultJS) \
343 macro(NewTypedArray, NodeResultJS | NodeMustGenerate) \
344 macro(NewRegexp, NodeResultJS) \
345 macro(NewSymbol, NodeResultJS) \
346 macro(NewStringObject, NodeResultJS) \
347 /* Rest Parameter */\
348 macro(GetRestLength, NodeResultInt32) \
349 macro(CreateRest, NodeResultJS | NodeMustGenerate) \
350 \
351 macro(Spread, NodeResultJS | NodeMustGenerate) \
352 /* Support for allocation sinking. */\
353 macro(PhantomNewObject, NodeResultJS | NodeMustGenerate) \
354 macro(PutHint, NodeMustGenerate) \
355 macro(CheckStructureImmediate, NodeMustGenerate) \
356 macro(MaterializeNewObject, NodeResultJS | NodeHasVarArgs) \
357 macro(PhantomNewFunction, NodeResultJS | NodeMustGenerate) \
358 macro(PhantomNewGeneratorFunction, NodeResultJS | NodeMustGenerate) \
359 macro(PhantomNewAsyncFunction, NodeResultJS | NodeMustGenerate) \
360 macro(PhantomNewAsyncGeneratorFunction, NodeResultJS | NodeMustGenerate) \
361 macro(PhantomCreateActivation, NodeResultJS | NodeMustGenerate) \
362 macro(MaterializeCreateActivation, NodeResultJS | NodeHasVarArgs) \
363 macro(PhantomNewRegexp, NodeResultJS | NodeMustGenerate) \
364 \
365 /* Nodes for misc operations. */\
366 macro(OverridesHasInstance, NodeMustGenerate | NodeResultBoolean) \
367 macro(InstanceOf, NodeMustGenerate | NodeResultBoolean) \
368 macro(InstanceOfCustom, NodeMustGenerate | NodeResultBoolean) \
369 macro(MatchStructure, NodeMustGenerate | NodeResultBoolean) \
370 \
371 macro(IsCellWithType, NodeResultBoolean) \
372 macro(IsEmpty, NodeResultBoolean) \
373 macro(IsUndefined, NodeResultBoolean) \
374 macro(IsUndefinedOrNull, NodeResultBoolean) \
375 macro(IsBoolean, NodeResultBoolean) \
376 macro(IsNumber, NodeResultBoolean) \
377 macro(NumberIsInteger, NodeResultBoolean) \
378 macro(IsObject, NodeResultBoolean) \
379 macro(IsObjectOrNull, NodeResultBoolean) \
380 macro(IsFunction, NodeResultBoolean) \
381 macro(IsTypedArrayView, NodeResultBoolean) \
382 macro(TypeOf, NodeResultJS) \
383 macro(LogicalNot, NodeResultBoolean) \
384 macro(ToPrimitive, NodeResultJS | NodeMustGenerate) \
385 macro(ToString, NodeResultJS | NodeMustGenerate) \
386 macro(ToNumber, NodeResultJS | NodeMustGenerate) \
387 macro(ToObject, NodeResultJS | NodeMustGenerate) \
388 macro(CallObjectConstructor, NodeResultJS) \
389 macro(CallStringConstructor, NodeResultJS | NodeMustGenerate) \
390 macro(NumberToStringWithRadix, NodeResultJS | NodeMustGenerate) \
391 macro(NumberToStringWithValidRadixConstant, NodeResultJS) \
392 macro(MakeRope, NodeResultJS) \
393 macro(InByVal, NodeResultBoolean | NodeMustGenerate) \
394 macro(InById, NodeResultBoolean | NodeMustGenerate) \
395 macro(ProfileType, NodeMustGenerate) \
396 macro(ProfileControlFlow, NodeMustGenerate) \
397 macro(SetFunctionName, NodeMustGenerate) \
398 macro(HasOwnProperty, NodeResultBoolean) \
399 \
400 macro(CreateActivation, NodeResultJS) \
401 macro(PushWithScope, NodeResultJS | NodeMustGenerate) \
402 \
403 macro(CreateDirectArguments, NodeResultJS) \
404 macro(PhantomDirectArguments, NodeResultJS | NodeMustGenerate) \
405 macro(PhantomCreateRest, NodeResultJS | NodeMustGenerate) \
406 macro(PhantomSpread, NodeResultJS | NodeMustGenerate) \
407 macro(PhantomNewArrayWithSpread, NodeResultJS | NodeMustGenerate | NodeHasVarArgs) \
408 macro(PhantomNewArrayBuffer, NodeResultJS | NodeMustGenerate) \
409 macro(CreateScopedArguments, NodeResultJS) \
410 macro(CreateClonedArguments, NodeResultJS) \
411 macro(PhantomClonedArguments, NodeResultJS | NodeMustGenerate) \
412 macro(GetFromArguments, NodeResultJS) \
413 macro(PutToArguments, NodeMustGenerate) \
414 macro(GetArgument, NodeResultJS) \
415 \
416 macro(NewFunction, NodeResultJS) \
417 macro(NewGeneratorFunction, NodeResultJS) \
418 macro(NewAsyncGeneratorFunction, NodeResultJS) \
419 macro(NewAsyncFunction, NodeResultJS) \
420 \
421 /* Block terminals. */\
422 macro(Jump, NodeMustGenerate) \
423 macro(Branch, NodeMustGenerate) \
424 macro(Switch, NodeMustGenerate) \
425 macro(EntrySwitch, NodeMustGenerate) \
426 macro(Return, NodeMustGenerate) \
427 macro(TailCall, NodeMustGenerate | NodeHasVarArgs) \
428 macro(DirectTailCall, NodeMustGenerate | NodeHasVarArgs) \
429 macro(TailCallVarargs, NodeMustGenerate) \
430 macro(TailCallForwardVarargs, NodeMustGenerate) \
431 macro(Unreachable, NodeMustGenerate) \
432 macro(Throw, NodeMustGenerate) \
433 macro(ThrowStaticError, NodeMustGenerate) \
434 \
435 /* Count execution. */\
436 macro(CountExecution, NodeMustGenerate) \
437 /* Super sampler. */\
438 macro(SuperSamplerBegin, NodeMustGenerate) \
439 macro(SuperSamplerEnd, NodeMustGenerate) \
440 \
441 /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\
442 /* this point, but execution does continue in the basic block - just in a */\
443 /* different compiler. */\
444 macro(ForceOSRExit, NodeMustGenerate) \
445 \
446 /* Vends a bottom JS value. It is invalid to ever execute this. Useful for cases */\
447 /* where we know that we would have exited but we'd like to still track the control */\
448 /* flow. */\
449 macro(BottomValue, NodeResultJS) \
450 \
451 /* Checks for VM traps. If there is a trap, we'll jettison or call operation operationHandleTraps. */ \
452 macro(CheckTraps, NodeMustGenerate) \
453 /* Write barriers */\
454 macro(StoreBarrier, NodeMustGenerate) \
455 macro(FencedStoreBarrier, NodeMustGenerate) \
456 \
457 /* For-in enumeration opcodes */\
458 macro(GetEnumerableLength, NodeMustGenerate | NodeResultJS) \
459 macro(HasIndexedProperty, NodeResultBoolean | NodeHasVarArgs) \
460 macro(HasStructureProperty, NodeResultBoolean) \
461 macro(HasGenericProperty, NodeResultBoolean) \
462 macro(GetDirectPname, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
463 macro(GetPropertyEnumerator, NodeMustGenerate | NodeResultJS) \
464 macro(GetEnumeratorStructurePname, NodeMustGenerate | NodeResultJS) \
465 macro(GetEnumeratorGenericPname, NodeMustGenerate | NodeResultJS) \
466 macro(ToIndexString, NodeResultJS) \
467 /* Nodes for JSMap and JSSet */ \
468 macro(MapHash, NodeResultInt32) \
469 macro(NormalizeMapKey, NodeResultJS) \
470 macro(GetMapBucket, NodeResultJS) \
471 macro(GetMapBucketHead, NodeResultJS) \
472 macro(GetMapBucketNext, NodeResultJS) \
473 macro(LoadKeyFromMapBucket, NodeResultJS) \
474 macro(LoadValueFromMapBucket, NodeResultJS) \
475 macro(SetAdd, NodeMustGenerate | NodeResultJS) \
476 macro(MapSet, NodeMustGenerate | NodeHasVarArgs | NodeResultJS) \
477 /* Nodes for JSWeakMap and JSWeakSet */ \
478 macro(WeakMapGet, NodeResultJS) \
479 macro(WeakSetAdd, NodeMustGenerate) \
480 macro(WeakMapSet, NodeMustGenerate | NodeHasVarArgs) \
481 macro(ExtractValueFromWeakMapGet, NodeResultJS) \
482 \
483 macro(StringValueOf, NodeMustGenerate | NodeResultJS) \
484 macro(StringSlice, NodeResultJS) \
485 macro(ToLowerCase, NodeResultJS) \
486 /* Nodes for DOM JIT */\
487 macro(CallDOMGetter, NodeResultJS | NodeMustGenerate) \
488 macro(CallDOM, NodeResultJS | NodeMustGenerate) \
489 /* Metadata node that initializes the state for flushed argument types at an entrypoint in the program. */ \
490 /* Currently, we only use this for the blocks an EntrySwitch branches to at the root of the program. */ \
491 /* This is only used in SSA. */ \
492 macro(InitializeEntrypointArguments, NodeMustGenerate) \
493 \
494 /* Used for $vm performance debugging */ \
495 macro(CPUIntrinsic, NodeResultJS | NodeMustGenerate) \
496 \
497 /* Used to provide feedback to the IC profiler. */ \
498 macro(FilterCallLinkStatus, NodeMustGenerate) \
499 macro(FilterGetByIdStatus, NodeMustGenerate) \
500 macro(FilterInByIdStatus, NodeMustGenerate) \
501 macro(FilterPutByIdStatus, NodeMustGenerate) \
502 /* Data view access */ \
503 macro(DataViewGetInt, NodeMustGenerate | NodeResultJS) /* The gets are must generate for now because they do bounds checks */ \
504 macro(DataViewGetFloat, NodeMustGenerate | NodeResultDouble) \
505 macro(DataViewSet, NodeMustGenerate | NodeMustGenerate | NodeHasVarArgs) \
506
507
508// This enum generates a monotonically increasing id for all Node types,
509// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask).
510enum NodeType {
511#define DFG_OP_ENUM(opcode, flags) opcode,
512 FOR_EACH_DFG_OP(DFG_OP_ENUM)
513#undef DFG_OP_ENUM
514 LastNodeType
515};
516
517// Specifies the default flags for each node.
518inline NodeFlags defaultFlags(NodeType op)
519{
520 switch (op) {
521#define DFG_OP_ENUM(opcode, flags) case opcode: return flags;
522 FOR_EACH_DFG_OP(DFG_OP_ENUM)
523#undef DFG_OP_ENUM
524 default:
525 RELEASE_ASSERT_NOT_REACHED();
526 return 0;
527 }
528}
529
530inline bool isAtomicsIntrinsic(NodeType op)
531{
532 switch (op) {
533 case AtomicsAdd:
534 case AtomicsAnd:
535 case AtomicsCompareExchange:
536 case AtomicsExchange:
537 case AtomicsLoad:
538 case AtomicsOr:
539 case AtomicsStore:
540 case AtomicsSub:
541 case AtomicsXor:
542 case AtomicsIsLockFree:
543 return true;
544 default:
545 return false;
546 }
547}
548
549static const unsigned maxNumExtraAtomicsArgs = 2;
550
551inline unsigned numExtraAtomicsArgs(NodeType op)
552{
553 switch (op) {
554 case AtomicsLoad:
555 return 0;
556 case AtomicsAdd:
557 case AtomicsAnd:
558 case AtomicsExchange:
559 case AtomicsOr:
560 case AtomicsStore:
561 case AtomicsSub:
562 case AtomicsXor:
563 return 1;
564 case AtomicsCompareExchange:
565 return 2;
566 default:
567 RELEASE_ASSERT_NOT_REACHED();
568 return 0;
569 }
570}
571
572} } // namespace JSC::DFG
573
574#endif // ENABLE(DFG_JIT)
575