1 | /*
|
---|
2 | * Copyright (C) 2014-2021 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 | #include "config.h"
|
---|
27 | #include "DFGDoesGC.h"
|
---|
28 |
|
---|
29 | #if ENABLE(DFG_JIT)
|
---|
30 |
|
---|
31 | #include "DFGClobberize.h"
|
---|
32 | #include "DFGGraph.h"
|
---|
33 | #include "DFGNode.h"
|
---|
34 |
|
---|
35 | namespace JSC { namespace DFG {
|
---|
36 |
|
---|
37 | bool doesGC(Graph& graph, Node* node)
|
---|
38 | {
|
---|
39 | if (clobbersHeap(graph, node))
|
---|
40 | return true;
|
---|
41 |
|
---|
42 | // Now consider nodes that don't clobber the world but that still may GC. This includes all
|
---|
43 | // nodes. By default, we should assume every node can GC and return true. This includes the
|
---|
44 | // world-clobbering nodes. We should only return false if we have proven that the node cannot
|
---|
45 | // GC. Typical examples of how a node can GC is if the code emitted for the node does any of the
|
---|
46 | // following:
|
---|
47 | // 1. Allocates any objects.
|
---|
48 | // 2. Resolves a rope string, which allocates a string.
|
---|
49 | // 3. Produces a string (which allocates the string) except when we can prove that
|
---|
50 | // the string will always be one of the pre-allocated SmallStrings.
|
---|
51 | // 4. Triggers a structure transition (which can allocate a new structure)
|
---|
52 | // unless it is a known transition between previously allocated structures
|
---|
53 | // such as between Array types.
|
---|
54 | // 5. Calls to a JS function, which can execute arbitrary code including allocating objects.
|
---|
55 | // 6. Calls operations that uses DeferGC, because it may GC in its destructor.
|
---|
56 |
|
---|
57 | switch (node->op()) {
|
---|
58 | case JSConstant:
|
---|
59 | case DoubleConstant:
|
---|
60 | case Int52Constant:
|
---|
61 | case LazyJSConstant:
|
---|
62 | case Identity:
|
---|
63 | case IdentityWithProfile:
|
---|
64 | case GetCallee:
|
---|
65 | case SetCallee:
|
---|
66 | case GetArgumentCountIncludingThis:
|
---|
67 | case SetArgumentCountIncludingThis:
|
---|
68 | case GetRestLength:
|
---|
69 | case GetLocal:
|
---|
70 | case SetLocal:
|
---|
71 | case MovHint:
|
---|
72 | case InitializeEntrypointArguments:
|
---|
73 | case ExitOK:
|
---|
74 | case Phantom:
|
---|
75 | case Upsilon:
|
---|
76 | case Phi:
|
---|
77 | case Flush:
|
---|
78 | case PhantomLocal:
|
---|
79 | case SetArgumentDefinitely:
|
---|
80 | case SetArgumentMaybe:
|
---|
81 | case ArithBitNot:
|
---|
82 | case ArithBitAnd:
|
---|
83 | case ArithBitOr:
|
---|
84 | case ArithBitXor:
|
---|
85 | case ArithBitLShift:
|
---|
86 | case ArithBitRShift:
|
---|
87 | case BitURShift:
|
---|
88 | case ValueToInt32:
|
---|
89 | case UInt32ToNumber:
|
---|
90 | case DoubleAsInt32:
|
---|
91 | case ArithAdd:
|
---|
92 | case ArithClz32:
|
---|
93 | case ArithSub:
|
---|
94 | case ArithNegate:
|
---|
95 | case ArithMul:
|
---|
96 | case ArithIMul:
|
---|
97 | case ArithDiv:
|
---|
98 | case ArithMod:
|
---|
99 | case ArithAbs:
|
---|
100 | case ArithMin:
|
---|
101 | case ArithMax:
|
---|
102 | case ArithPow:
|
---|
103 | case ArithSqrt:
|
---|
104 | case ArithRandom:
|
---|
105 | case ArithRound:
|
---|
106 | case ArithFloor:
|
---|
107 | case ArithCeil:
|
---|
108 | case ArithTrunc:
|
---|
109 | case ArithFRound:
|
---|
110 | case ArithUnary:
|
---|
111 | case CheckStructure:
|
---|
112 | case CheckStructureOrEmpty:
|
---|
113 | case CheckStructureImmediate:
|
---|
114 | case GetExecutable:
|
---|
115 | case GetButterfly:
|
---|
116 | case CheckJSCast:
|
---|
117 | case CheckNotJSCast:
|
---|
118 | case CheckArray:
|
---|
119 | case CheckArrayOrEmpty:
|
---|
120 | case CheckDetached:
|
---|
121 | case GetScope:
|
---|
122 | case SkipScope:
|
---|
123 | case GetGlobalObject:
|
---|
124 | case GetGlobalThis:
|
---|
125 | case GetClosureVar:
|
---|
126 | case PutClosureVar:
|
---|
127 | case GetInternalField:
|
---|
128 | case PutInternalField:
|
---|
129 | case GetRegExpObjectLastIndex:
|
---|
130 | case SetRegExpObjectLastIndex:
|
---|
131 | case RecordRegExpCachedResult:
|
---|
132 | case GetGlobalVar:
|
---|
133 | case GetGlobalLexicalVariable:
|
---|
134 | case PutGlobalVariable:
|
---|
135 | case CheckIsConstant:
|
---|
136 | case CheckNotEmpty:
|
---|
137 | case AssertNotEmpty:
|
---|
138 | case CheckIdent:
|
---|
139 | case CompareBelow:
|
---|
140 | case CompareBelowEq:
|
---|
141 | case CompareEqPtr:
|
---|
142 | case ProfileControlFlow:
|
---|
143 | case OverridesHasInstance:
|
---|
144 | case IsEmpty:
|
---|
145 | case TypeOfIsUndefined:
|
---|
146 | case TypeOfIsObject:
|
---|
147 | case TypeOfIsFunction:
|
---|
148 | case IsUndefinedOrNull:
|
---|
149 | case IsBoolean:
|
---|
150 | case IsNumber:
|
---|
151 | case IsBigInt:
|
---|
152 | case NumberIsInteger:
|
---|
153 | case IsObject:
|
---|
154 | case IsCallable:
|
---|
155 | case IsConstructor:
|
---|
156 | case IsCellWithType:
|
---|
157 | case IsTypedArrayView:
|
---|
158 | case TypeOf:
|
---|
159 | case ToBoolean:
|
---|
160 | case LogicalNot:
|
---|
161 | case Jump:
|
---|
162 | case Branch:
|
---|
163 | case EntrySwitch:
|
---|
164 | case CountExecution:
|
---|
165 | case SuperSamplerBegin:
|
---|
166 | case SuperSamplerEnd:
|
---|
167 | case CPUIntrinsic:
|
---|
168 | case NormalizeMapKey: // HeapBigInt => BigInt32 conversion does not involve GC.
|
---|
169 | case GetMapBucketHead:
|
---|
170 | case GetMapBucketNext:
|
---|
171 | case LoadKeyFromMapBucket:
|
---|
172 | case LoadValueFromMapBucket:
|
---|
173 | case ExtractValueFromWeakMapGet:
|
---|
174 | case WeakMapGet:
|
---|
175 | case WeakSetAdd:
|
---|
176 | case WeakMapSet:
|
---|
177 | case Unreachable:
|
---|
178 | case ExtractOSREntryLocal:
|
---|
179 | case ExtractCatchLocal:
|
---|
180 | case ClearCatchLocals:
|
---|
181 | case LoopHint:
|
---|
182 | case StoreBarrier:
|
---|
183 | case FencedStoreBarrier:
|
---|
184 | case InvalidationPoint:
|
---|
185 | case NotifyWrite:
|
---|
186 | case AssertInBounds:
|
---|
187 | case CheckInBounds:
|
---|
188 | case CheckInBoundsInt52:
|
---|
189 | case ConstantStoragePointer:
|
---|
190 | case Check:
|
---|
191 | case CheckVarargs:
|
---|
192 | case CheckTypeInfoFlags:
|
---|
193 | case MultiGetByOffset:
|
---|
194 | case MultiDeleteByOffset:
|
---|
195 | case ValueRep:
|
---|
196 | case DoubleRep:
|
---|
197 | case Int52Rep:
|
---|
198 | case GetGetter:
|
---|
199 | case GetSetter:
|
---|
200 | case GetArrayLength:
|
---|
201 | case GetTypedArrayLengthAsInt52:
|
---|
202 | case GetVectorLength:
|
---|
203 | case StringCharCodeAt:
|
---|
204 | case StringCodePointAt:
|
---|
205 | case GetTypedArrayByteOffset:
|
---|
206 | case GetTypedArrayByteOffsetAsInt52:
|
---|
207 | case GetPrototypeOf:
|
---|
208 | case PutStructure:
|
---|
209 | case GetByOffset:
|
---|
210 | case GetGetterSetterByOffset:
|
---|
211 | case FiatInt52:
|
---|
212 | case BooleanToNumber:
|
---|
213 | case CheckBadValue:
|
---|
214 | case BottomValue:
|
---|
215 | case PhantomNewObject:
|
---|
216 | case PhantomNewFunction:
|
---|
217 | case PhantomNewGeneratorFunction:
|
---|
218 | case PhantomNewAsyncFunction:
|
---|
219 | case PhantomNewAsyncGeneratorFunction:
|
---|
220 | case PhantomNewInternalFieldObject:
|
---|
221 | case PhantomCreateActivation:
|
---|
222 | case PhantomDirectArguments:
|
---|
223 | case PhantomCreateRest:
|
---|
224 | case PhantomNewArrayWithSpread:
|
---|
225 | case PhantomNewArrayBuffer:
|
---|
226 | case PhantomSpread:
|
---|
227 | case PhantomClonedArguments:
|
---|
228 | case PhantomNewRegexp:
|
---|
229 | case GetMyArgumentByVal:
|
---|
230 | case GetMyArgumentByValOutOfBounds:
|
---|
231 | case ForwardVarargs:
|
---|
232 | case PutHint:
|
---|
233 | case KillStack:
|
---|
234 | case GetStack:
|
---|
235 | case GetFromArguments:
|
---|
236 | case GetArgument:
|
---|
237 | case LogShadowChickenPrologue:
|
---|
238 | case LogShadowChickenTail:
|
---|
239 | case NukeStructureAndSetButterfly:
|
---|
240 | case AtomicsAdd:
|
---|
241 | case AtomicsAnd:
|
---|
242 | case AtomicsCompareExchange:
|
---|
243 | case AtomicsExchange:
|
---|
244 | case AtomicsLoad:
|
---|
245 | case AtomicsOr:
|
---|
246 | case AtomicsStore:
|
---|
247 | case AtomicsSub:
|
---|
248 | case AtomicsXor:
|
---|
249 | case AtomicsIsLockFree:
|
---|
250 | case MatchStructure:
|
---|
251 | case FilterCallLinkStatus:
|
---|
252 | case FilterGetByStatus:
|
---|
253 | case FilterPutByStatus:
|
---|
254 | case FilterInByStatus:
|
---|
255 | case FilterDeleteByStatus:
|
---|
256 | case FilterCheckPrivateBrandStatus:
|
---|
257 | case FilterSetPrivateBrandStatus:
|
---|
258 | case DateGetInt32OrNaN:
|
---|
259 | case DateGetTime:
|
---|
260 | case DataViewGetInt:
|
---|
261 | case DataViewGetFloat:
|
---|
262 | case DataViewSet:
|
---|
263 | case PutByOffset:
|
---|
264 | return false;
|
---|
265 |
|
---|
266 | #if ASSERT_ENABLED
|
---|
267 | case ArrayPush:
|
---|
268 | case ArrayPop:
|
---|
269 | case PushWithScope:
|
---|
270 | case CreateActivation:
|
---|
271 | case CreateDirectArguments:
|
---|
272 | case CreateScopedArguments:
|
---|
273 | case CreateClonedArguments:
|
---|
274 | case CreateArgumentsButterfly:
|
---|
275 | case Call:
|
---|
276 | case CallEval:
|
---|
277 | case CallForwardVarargs:
|
---|
278 | case CallObjectConstructor:
|
---|
279 | case CallVarargs:
|
---|
280 | case CheckTierUpAndOSREnter:
|
---|
281 | case CheckTierUpAtReturn:
|
---|
282 | case CheckTierUpInLoop:
|
---|
283 | case Construct:
|
---|
284 | case ConstructForwardVarargs:
|
---|
285 | case ConstructVarargs:
|
---|
286 | case DefineDataProperty:
|
---|
287 | case DefineAccessorProperty:
|
---|
288 | case DeleteById:
|
---|
289 | case DeleteByVal:
|
---|
290 | case DirectCall:
|
---|
291 | case DirectConstruct:
|
---|
292 | case DirectTailCall:
|
---|
293 | case DirectTailCallInlinedCaller:
|
---|
294 | case ForceOSRExit:
|
---|
295 | case FunctionToString:
|
---|
296 | case GetById:
|
---|
297 | case GetByIdDirect:
|
---|
298 | case GetByIdDirectFlush:
|
---|
299 | case GetByIdFlush:
|
---|
300 | case GetByIdWithThis:
|
---|
301 | case GetByValWithThis:
|
---|
302 | case GetDynamicVar:
|
---|
303 | case GetMapBucket:
|
---|
304 | case HasIndexedProperty:
|
---|
305 | case HasOwnProperty:
|
---|
306 | case InById:
|
---|
307 | case InByVal:
|
---|
308 | case HasPrivateName:
|
---|
309 | case HasPrivateBrand:
|
---|
310 | case InstanceOf:
|
---|
311 | case InstanceOfCustom:
|
---|
312 | case VarargsLength:
|
---|
313 | case LoadVarargs:
|
---|
314 | case NumberToStringWithRadix:
|
---|
315 | case NumberToStringWithValidRadixConstant:
|
---|
316 | case ProfileType:
|
---|
317 | case PutById:
|
---|
318 | case PutByIdDirect:
|
---|
319 | case PutByIdFlush:
|
---|
320 | case PutByIdWithThis:
|
---|
321 | case PutByValWithThis:
|
---|
322 | case PutDynamicVar:
|
---|
323 | case PutGetterById:
|
---|
324 | case PutGetterByVal:
|
---|
325 | case PutGetterSetterById:
|
---|
326 | case PutSetterById:
|
---|
327 | case PutSetterByVal:
|
---|
328 | case PutPrivateName:
|
---|
329 | case PutPrivateNameById:
|
---|
330 | case GetPrivateName:
|
---|
331 | case GetPrivateNameById:
|
---|
332 | case SetPrivateBrand:
|
---|
333 | case CheckPrivateBrand:
|
---|
334 | case PutStack:
|
---|
335 | case PutToArguments:
|
---|
336 | case RegExpExec:
|
---|
337 | case RegExpExecNonGlobalOrSticky:
|
---|
338 | case RegExpMatchFast:
|
---|
339 | case RegExpMatchFastGlobal:
|
---|
340 | case RegExpTest:
|
---|
341 | case RegExpTestInline:
|
---|
342 | case ResolveScope:
|
---|
343 | case ResolveScopeForHoistingFuncDeclInEval:
|
---|
344 | case Return:
|
---|
345 | case StringCharAt:
|
---|
346 | case TailCall:
|
---|
347 | case TailCallForwardVarargs:
|
---|
348 | case TailCallForwardVarargsInlinedCaller:
|
---|
349 | case TailCallInlinedCaller:
|
---|
350 | case TailCallVarargs:
|
---|
351 | case TailCallVarargsInlinedCaller:
|
---|
352 | case Throw:
|
---|
353 | case ToNumber:
|
---|
354 | case ToNumeric:
|
---|
355 | case ToObject:
|
---|
356 | case ToPrimitive:
|
---|
357 | case ToPropertyKey:
|
---|
358 | case ToThis:
|
---|
359 | case TryGetById:
|
---|
360 | case CreateThis:
|
---|
361 | case CreatePromise:
|
---|
362 | case CreateGenerator:
|
---|
363 | case CreateAsyncGenerator:
|
---|
364 | case ObjectAssign:
|
---|
365 | case ObjectCreate:
|
---|
366 | case ObjectKeys:
|
---|
367 | case ObjectGetOwnPropertyNames:
|
---|
368 | case AllocatePropertyStorage:
|
---|
369 | case ReallocatePropertyStorage:
|
---|
370 | case Arrayify:
|
---|
371 | case ArrayifyToStructure:
|
---|
372 | case NewObject:
|
---|
373 | case NewGenerator:
|
---|
374 | case NewAsyncGenerator:
|
---|
375 | case NewArray:
|
---|
376 | case NewArrayWithSpread:
|
---|
377 | case NewInternalFieldObject:
|
---|
378 | case Spread:
|
---|
379 | case NewArrayWithSize:
|
---|
380 | case NewArrayBuffer:
|
---|
381 | case NewRegexp:
|
---|
382 | case NewStringObject:
|
---|
383 | case NewSymbol:
|
---|
384 | case MakeRope:
|
---|
385 | case NewFunction:
|
---|
386 | case NewGeneratorFunction:
|
---|
387 | case NewAsyncGeneratorFunction:
|
---|
388 | case NewAsyncFunction:
|
---|
389 | case NewTypedArray:
|
---|
390 | case ThrowStaticError:
|
---|
391 | case GetPropertyEnumerator:
|
---|
392 | case EnumeratorInByVal:
|
---|
393 | case EnumeratorHasOwnProperty:
|
---|
394 | case EnumeratorNextUpdatePropertyName:
|
---|
395 | case EnumeratorNextUpdateIndexAndMode:
|
---|
396 | case MaterializeNewObject:
|
---|
397 | case MaterializeNewInternalFieldObject:
|
---|
398 | case MaterializeCreateActivation:
|
---|
399 | case SetFunctionName:
|
---|
400 | case StrCat:
|
---|
401 | case StringReplace:
|
---|
402 | case StringReplaceRegExp:
|
---|
403 | case StringSlice:
|
---|
404 | case StringValueOf:
|
---|
405 | case CreateRest:
|
---|
406 | case ToLowerCase:
|
---|
407 | case CallDOMGetter:
|
---|
408 | case CallDOM:
|
---|
409 | case ArraySlice:
|
---|
410 | case ArrayIndexOf:
|
---|
411 | case ParseInt: // We might resolve a rope even though we don't clobber anything.
|
---|
412 | case SetAdd:
|
---|
413 | case MapSet:
|
---|
414 | case ValueBitAnd:
|
---|
415 | case ValueBitOr:
|
---|
416 | case ValueBitXor:
|
---|
417 | case ValueBitLShift:
|
---|
418 | case ValueBitRShift:
|
---|
419 | case ValueAdd:
|
---|
420 | case ValueSub:
|
---|
421 | case ValueMul:
|
---|
422 | case ValueDiv:
|
---|
423 | case ValueMod:
|
---|
424 | case ValuePow:
|
---|
425 | case ValueBitNot:
|
---|
426 | case ValueNegate:
|
---|
427 | #else // not ASSERT_ENABLED
|
---|
428 | // See comment at the top for why the default for all nodes should be to
|
---|
429 | // return true.
|
---|
430 | default:
|
---|
431 | #endif // not ASSERT_ENABLED
|
---|
432 | return true;
|
---|
433 |
|
---|
434 | case CallNumberConstructor:
|
---|
435 | switch (node->child1().useKind()) {
|
---|
436 | case BigInt32Use:
|
---|
437 | return false;
|
---|
438 | default:
|
---|
439 | break;
|
---|
440 | }
|
---|
441 | return true;
|
---|
442 |
|
---|
443 | case CallStringConstructor:
|
---|
444 | case ToString:
|
---|
445 | switch (node->child1().useKind()) {
|
---|
446 | case StringObjectUse:
|
---|
447 | case StringOrStringObjectUse:
|
---|
448 | return false;
|
---|
449 | default:
|
---|
450 | break;
|
---|
451 | }
|
---|
452 | return true;
|
---|
453 |
|
---|
454 | case CheckTraps:
|
---|
455 | // FIXME: https://bugs.webkit.org/show_bug.cgi?id=194323
|
---|
456 | ASSERT(Options::usePollingTraps() || graph.m_plan.isUnlinked());
|
---|
457 | return true;
|
---|
458 |
|
---|
459 | case CompareEq:
|
---|
460 | case CompareLess:
|
---|
461 | case CompareLessEq:
|
---|
462 | case CompareGreater:
|
---|
463 | case CompareGreaterEq:
|
---|
464 | // FIXME: Add AnyBigIntUse and HeapBigIntUse specific optimizations in DFG / FTL code generation and ensure it does not perform GC.
|
---|
465 | // https://bugs.webkit.org/show_bug.cgi?id=210923
|
---|
466 | if (node->isBinaryUseKind(Int32Use)
|
---|
467 | #if USE(JSVALUE64)
|
---|
468 | || node->isBinaryUseKind(Int52RepUse)
|
---|
469 | #endif
|
---|
470 | || node->isBinaryUseKind(DoubleRepUse)
|
---|
471 | || node->isBinaryUseKind(BigInt32Use)
|
---|
472 | || node->isBinaryUseKind(StringIdentUse)
|
---|
473 | )
|
---|
474 | return false;
|
---|
475 | if (node->op() == CompareEq) {
|
---|
476 | if (node->isBinaryUseKind(BooleanUse)
|
---|
477 | || node->isBinaryUseKind(SymbolUse)
|
---|
478 | || node->isBinaryUseKind(ObjectUse)
|
---|
479 | || node->isBinaryUseKind(ObjectUse, ObjectOrOtherUse) || node->isBinaryUseKind(ObjectOrOtherUse, ObjectUse))
|
---|
480 | return false;
|
---|
481 | }
|
---|
482 | return true;
|
---|
483 |
|
---|
484 | case CompareStrictEq:
|
---|
485 | if (node->isBinaryUseKind(BooleanUse)
|
---|
486 | || node->isBinaryUseKind(Int32Use)
|
---|
487 | #if USE(JSVALUE64)
|
---|
488 | || node->isBinaryUseKind(Int52RepUse)
|
---|
489 | #endif
|
---|
490 | || node->isBinaryUseKind(DoubleRepUse)
|
---|
491 | || node->isBinaryUseKind(SymbolUse)
|
---|
492 | || node->isBinaryUseKind(SymbolUse, UntypedUse)
|
---|
493 | || node->isBinaryUseKind(UntypedUse, SymbolUse)
|
---|
494 | || node->isBinaryUseKind(StringIdentUse)
|
---|
495 | || node->isBinaryUseKind(ObjectUse, UntypedUse) || node->isBinaryUseKind(UntypedUse, ObjectUse)
|
---|
496 | || node->isBinaryUseKind(ObjectUse)
|
---|
497 | || node->isBinaryUseKind(MiscUse, UntypedUse) || node->isBinaryUseKind(UntypedUse, MiscUse)
|
---|
498 | || node->isBinaryUseKind(StringIdentUse, NotStringVarUse) || node->isBinaryUseKind(NotStringVarUse, StringIdentUse)
|
---|
499 | || node->isBinaryUseKind(NotDoubleUse, NeitherDoubleNorHeapBigIntNorStringUse) || node->isBinaryUseKind(NeitherDoubleNorHeapBigIntNorStringUse, NotDoubleUse))
|
---|
500 | return false;
|
---|
501 | return true;
|
---|
502 |
|
---|
503 | case GetIndexedPropertyStorage:
|
---|
504 | return false;
|
---|
505 |
|
---|
506 | case GetByVal:
|
---|
507 | case EnumeratorGetByVal:
|
---|
508 | if (node->arrayMode().type() == Array::String)
|
---|
509 | return true;
|
---|
510 | return false;
|
---|
511 |
|
---|
512 | case ResolveRope:
|
---|
513 | return true;
|
---|
514 |
|
---|
515 | case EnumeratorNextExtractMode:
|
---|
516 | case EnumeratorNextExtractIndex:
|
---|
517 | return false;
|
---|
518 |
|
---|
519 | case PutByValDirect:
|
---|
520 | case PutByVal:
|
---|
521 | case PutByValAlias:
|
---|
522 | if (!graph.m_plan.isFTL()) {
|
---|
523 | switch (node->arrayMode().modeForPut().type()) {
|
---|
524 | case Array::Int8Array:
|
---|
525 | case Array::Int16Array:
|
---|
526 | case Array::Int32Array:
|
---|
527 | case Array::Uint8Array:
|
---|
528 | case Array::Uint8ClampedArray:
|
---|
529 | case Array::Uint16Array:
|
---|
530 | case Array::Uint32Array:
|
---|
531 | return true;
|
---|
532 | default:
|
---|
533 | break;
|
---|
534 | }
|
---|
535 | }
|
---|
536 | return false;
|
---|
537 |
|
---|
538 | case MapHash:
|
---|
539 | switch (node->child1().useKind()) {
|
---|
540 | case BooleanUse:
|
---|
541 | case Int32Use:
|
---|
542 | case SymbolUse:
|
---|
543 | case ObjectUse:
|
---|
544 | #if USE(BIGINT32)
|
---|
545 | case BigInt32Use:
|
---|
546 | #endif
|
---|
547 | case HeapBigIntUse:
|
---|
548 | return false;
|
---|
549 | default:
|
---|
550 | // We might resolve a rope.
|
---|
551 | return true;
|
---|
552 | }
|
---|
553 |
|
---|
554 | case MultiPutByOffset:
|
---|
555 | return node->multiPutByOffsetData().reallocatesStorage();
|
---|
556 |
|
---|
557 | case SameValue:
|
---|
558 | if (node->isBinaryUseKind(DoubleRepUse))
|
---|
559 | return false;
|
---|
560 | return true;
|
---|
561 |
|
---|
562 | case StringFromCharCode:
|
---|
563 | // FIXME: Should we constant fold this case?
|
---|
564 | // https://bugs.webkit.org/show_bug.cgi?id=194308
|
---|
565 | if (node->child1()->isInt32Constant() && (node->child1()->asUInt32() <= maxSingleCharacterString))
|
---|
566 | return false;
|
---|
567 | return true;
|
---|
568 |
|
---|
569 | case Switch:
|
---|
570 | switch (node->switchData()->kind) {
|
---|
571 | case SwitchCell:
|
---|
572 | ASSERT(graph.m_plan.isFTL());
|
---|
573 | FALLTHROUGH;
|
---|
574 | case SwitchImm:
|
---|
575 | return false;
|
---|
576 | case SwitchChar:
|
---|
577 | return true;
|
---|
578 | case SwitchString:
|
---|
579 | if (node->child1().useKind() == StringIdentUse)
|
---|
580 | return false;
|
---|
581 | ASSERT(node->child1().useKind() == StringUse || node->child1().useKind() == UntypedUse);
|
---|
582 | return true;
|
---|
583 | }
|
---|
584 | RELEASE_ASSERT_NOT_REACHED();
|
---|
585 |
|
---|
586 | case Inc:
|
---|
587 | case Dec:
|
---|
588 | switch (node->child1().useKind()) {
|
---|
589 | case Int32Use:
|
---|
590 | case Int52RepUse:
|
---|
591 | case DoubleRepUse:
|
---|
592 | return false;
|
---|
593 | default:
|
---|
594 | return true;
|
---|
595 | }
|
---|
596 |
|
---|
597 | case LastNodeType:
|
---|
598 | RELEASE_ASSERT_NOT_REACHED();
|
---|
599 | }
|
---|
600 |
|
---|
601 | RELEASE_ASSERT_NOT_REACHED();
|
---|
602 | }
|
---|
603 |
|
---|
604 | } } // namespace JSC::DFG
|
---|
605 |
|
---|
606 | #endif // ENABLE(DFG_JIT)
|
---|