Array.prototype.flat/flatMap have a minor bug in ArraySpeciesCreate
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGClobberize.h
1 /*
2  * Copyright (C) 2013-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 "DFGAbstractHeap.h"
31 #include "DFGEdgeUsesStructure.h"
32 #include "DFGGraph.h"
33 #include "DFGHeapLocation.h"
34 #include "DFGLazyNode.h"
35 #include "DFGPureValue.h"
36 #include "DOMJITCallDOMGetterSnippet.h"
37 #include "DOMJITSignature.h"
38 #include "InlineCallFrame.h"
39 #include "JSFixedArray.h"
40 #include "JSImmutableButterfly.h"
41
42 namespace JSC { namespace DFG {
43
44 template<typename ReadFunctor, typename WriteFunctor, typename DefFunctor>
45 void clobberize(Graph& graph, Node* node, const ReadFunctor& read, const WriteFunctor& write, const DefFunctor& def)
46 {
47     // Some notes:
48     //
49     // - The canonical way of clobbering the world is to read world and write
50     //   heap. This is because World subsumes Heap and Stack, and Stack can be
51     //   read by anyone but only written to by explicit stack writing operations.
52     //   Of course, claiming to also write World is not wrong; it'll just
53     //   pessimise some important optimizations.
54     //
55     // - We cannot hoist, or sink, anything that has effects. This means that the
56     //   easiest way of indicating that something cannot be hoisted is to claim
57     //   that it side-effects some miscellaneous thing.
58     //
59     // - We cannot hoist forward-exiting nodes without some additional effort. I
60     //   believe that what it comes down to is that forward-exiting generally have
61     //   their NodeExitsForward cleared upon hoist, except for forward-exiting
62     //   nodes that take bogus state as their input. Those are substantially
63     //   harder. We disable it for now. In the future we could enable it by having
64     //   versions of those nodes that backward-exit instead, but I'm not convinced
65     //   of the soundness.
66     //
67     // - Some nodes lie, and claim that they do not read the JSCell_structureID,
68     //   JSCell_typeInfoFlags, etc. These are nodes that use the structure in a way
69     //   that does not depend on things that change under structure transitions.
70     //
71     // - It's implicitly understood that OSR exits read the world. This is why we
72     //   generally don't move or eliminate stores. Every node can exit, so the
73     //   read set does not reflect things that would be read if we exited.
74     //   Instead, the read set reflects what the node will have to read if it
75     //   *doesn't* exit.
76     //
77     // - Broadly, we don't say that we're reading something if that something is
78     //   immutable.
79     //
80     // - This must be sound even prior to type inference. We use this as early as
81     //   bytecode parsing to determine at which points in the program it's legal to
82     //   OSR exit.
83     //
84     // - If you do read(Stack) or read(World), then make sure that readTop() in
85     //   PreciseLocalClobberize is correct.
86     
87     // While read() and write() are fairly self-explanatory - they track what sorts of things the
88     // node may read or write - the def() functor is more tricky. It tells you the heap locations
89     // (not just abstract heaps) that are defined by a node. A heap location comprises an abstract
90     // heap, some nodes, and a LocationKind. Briefly, a location defined by a node is a location
91     // whose value can be deduced from looking at the node itself. The locations returned must obey
92     // the following properties:
93     //
94     // - If someone wants to CSE a load from the heap, then a HeapLocation object should be
95     //   sufficient to find a single matching node.
96     //
97     // - The abstract heap is the only abstract heap that could be clobbered to invalidate any such
98     //   CSE attempt. I.e. if clobberize() reports that on every path between some node and a node
99     //   that defines a HeapLocation that it wanted, there were no writes to any abstract heap that
100     //   overlap the location's heap, then we have a sound match. Effectively, the semantics of
101     //   write() and def() are intertwined such that for them to be sound they must agree on what
102     //   is CSEable.
103     //
104     // read(), write(), and def() for heap locations is enough to do GCSE on effectful things. To
105     // keep things simple, this code will also def() pure things. def() must be overloaded to also
106     // accept PureValue. This way, a client of clobberize() can implement GCSE entirely using the
107     // information that clobberize() passes to write() and def(). Other clients of clobberize() can
108     // just ignore def() by using a NoOpClobberize functor.
109
110     if (edgesUseStructure(graph, node))
111         read(JSCell_structureID);
112     
113     // We allow the runtime to perform a stack scan at any time. We don't model which nodes get implemented
114     // by calls into the runtime. For debugging we might replace the implementation of any node with a call
115     // to the runtime, and that call may walk stack. Therefore, each node must read() anything that a stack
116     // scan would read. That's what this does.
117     for (InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
118         if (inlineCallFrame->isClosureCall)
119             read(AbstractHeap(Stack, inlineCallFrame->stackOffset + CallFrameSlot::callee));
120         if (inlineCallFrame->isVarargs())
121             read(AbstractHeap(Stack, inlineCallFrame->stackOffset + CallFrameSlot::argumentCount));
122     }
123
124     // We don't want to specifically account which nodes can read from the scope
125     // when the debugger is enabled. It's helpful to just claim all nodes do.
126     // Specifically, if a node allocates, this may call into the debugger's machinery.
127     // The debugger's machinery is free to take a stack trace and try to read from
128     // a scope which is expected to be flushed to the stack.
129     if (graph.hasDebuggerEnabled()) {
130         ASSERT(!node->origin.semantic.inlineCallFrame);
131         read(AbstractHeap(Stack, graph.m_codeBlock->scopeRegister()));
132     }
133     
134     switch (node->op()) {
135     case JSConstant:
136     case DoubleConstant:
137     case Int52Constant:
138         def(PureValue(node, node->constant()));
139         return;
140
141     case Identity:
142     case IdentityWithProfile:
143     case Phantom:
144     case Check:
145     case CheckVarargs:
146     case ExtractOSREntryLocal:
147     case CheckStructureImmediate:
148         return;
149
150     case ExtractCatchLocal:
151         read(AbstractHeap(CatchLocals, node->catchOSREntryIndex()));
152         return;
153
154     case ClearCatchLocals:
155         write(CatchLocals);
156         return;
157         
158     case LazyJSConstant:
159         // We should enable CSE of LazyJSConstant. It's a little annoying since LazyJSValue has
160         // more bits than we currently have in PureValue.
161         return;
162
163     case CompareEqPtr:
164         def(PureValue(node, node->cellOperand()->cell()));
165         return;
166         
167     case ArithIMul:
168     case ArithMin:
169     case ArithMax:
170     case ArithPow:
171     case GetScope:
172     case SkipScope:
173     case GetGlobalObject:
174     case StringCharCodeAt:
175     case CompareStrictEq:
176     case SameValue:
177     case IsEmpty:
178     case IsUndefined:
179     case IsUndefinedOrNull:
180     case IsBoolean:
181     case IsNumber:
182     case NumberIsInteger:
183     case IsObject:
184     case IsTypedArrayView:
185     case LogicalNot:
186     case CheckInBounds:
187     case DoubleRep:
188     case ValueRep:
189     case Int52Rep:
190     case BooleanToNumber:
191     case FiatInt52:
192     case MakeRope:
193     case StrCat:
194     case ValueToInt32:
195     case GetExecutable:
196     case BottomValue:
197     case TypeOf:
198         def(PureValue(node));
199         return;
200
201     case GetGlobalThis:
202         read(World);
203         return;
204
205     case AtomicsIsLockFree:
206         if (node->child1().useKind() == Int32Use)
207             def(PureValue(node));
208         else {
209             read(World);
210             write(Heap);
211         }
212         return;
213         
214     case ArithUnary:
215         if (node->child1().useKind() == DoubleRepUse)
216             def(PureValue(node, static_cast<std::underlying_type<Arith::UnaryType>::type>(node->arithUnaryType())));
217         else {
218             read(World);
219             write(Heap);
220         }
221         return;
222
223     case ArithFRound:
224     case ArithSqrt:
225         if (node->child1().useKind() == DoubleRepUse)
226             def(PureValue(node));
227         else {
228             read(World);
229             write(Heap);
230         }
231         return;
232
233     case ArithAbs:
234         if (node->child1().useKind() == Int32Use || node->child1().useKind() == DoubleRepUse)
235             def(PureValue(node));
236         else {
237             read(World);
238             write(Heap);
239         }
240         return;
241
242     case ArithClz32:
243         if (node->child1().useKind() == Int32Use || node->child1().useKind() == KnownInt32Use)
244             def(PureValue(node));
245         else {
246             read(World);
247             write(Heap);
248         }
249         return;
250
251     case ArithNegate:
252         if (node->child1().useKind() == Int32Use
253             || node->child1().useKind() == DoubleRepUse
254             || node->child1().useKind() == Int52RepUse)
255             def(PureValue(node));
256         else {
257             read(World);
258             write(Heap);
259         }
260         return;
261
262     case IsCellWithType:
263         def(PureValue(node, node->queriedType()));
264         return;
265
266     case ArithBitNot:
267         if (node->child1().useKind() == UntypedUse) {
268             read(World);
269             write(Heap);
270             return;
271         }
272         def(PureValue(node));
273         return;
274
275     case ArithBitAnd:
276     case ArithBitOr:
277     case ArithBitXor:
278     case BitLShift:
279     case BitRShift:
280     case BitURShift:
281         if (node->child1().useKind() == UntypedUse || node->child2().useKind() == UntypedUse) {
282             read(World);
283             write(Heap);
284             return;
285         }
286         def(PureValue(node));
287         return;
288
289     case ArithRandom:
290         read(MathDotRandomState);
291         write(MathDotRandomState);
292         return;
293
294     case GetEnumerableLength: {
295         read(Heap);
296         write(SideState);
297         return;
298     }
299
300     case ToIndexString:
301     case GetEnumeratorStructurePname:
302     case GetEnumeratorGenericPname: {
303         def(PureValue(node));
304         return;
305     }
306
307     case HasIndexedProperty: {
308         read(JSObject_butterfly);
309         ArrayMode mode = node->arrayMode();
310         switch (mode.type()) {
311         case Array::ForceExit: {
312             write(SideState);
313             return;
314         }
315         case Array::Int32: {
316             if (mode.isInBounds()) {
317                 read(Butterfly_publicLength);
318                 read(IndexedInt32Properties);
319                 def(HeapLocation(HasIndexedPropertyLoc, IndexedInt32Properties, node->child1(), node->child2()), LazyNode(node));
320                 return;
321             }
322             read(Heap);
323             return;
324         }
325             
326         case Array::Double: {
327             if (mode.isInBounds()) {
328                 read(Butterfly_publicLength);
329                 read(IndexedDoubleProperties);
330                 def(HeapLocation(HasIndexedPropertyLoc, IndexedDoubleProperties, node->child1(), node->child2()), LazyNode(node));
331                 return;
332             }
333             read(Heap);
334             return;
335         }
336             
337         case Array::Contiguous: {
338             if (mode.isInBounds()) {
339                 read(Butterfly_publicLength);
340                 read(IndexedContiguousProperties);
341                 def(HeapLocation(HasIndexedPropertyLoc, IndexedContiguousProperties, node->child1(), node->child2()), LazyNode(node));
342                 return;
343             }
344             read(Heap);
345             return;
346         }
347
348         case Array::ArrayStorage: {
349             if (mode.isInBounds()) {
350                 read(Butterfly_vectorLength);
351                 read(IndexedArrayStorageProperties);
352                 return;
353             }
354             read(Heap);
355             return;
356         }
357
358         default: {
359             read(World);
360             write(Heap);
361             return;
362         }
363         }
364         RELEASE_ASSERT_NOT_REACHED();
365         return;
366     }
367
368     case StringFromCharCode:
369         switch (node->child1().useKind()) {
370         case Int32Use:
371             def(PureValue(node));
372             return;
373         case UntypedUse:
374             read(World);
375             write(Heap);
376             return;
377         default:
378             DFG_CRASH(graph, node, "Bad use kind");
379         }
380         return;
381
382     case ArithAdd:
383     case ArithMod:
384     case DoubleAsInt32:
385     case UInt32ToNumber:
386         def(PureValue(node, node->arithMode()));
387         return;
388
389     case ArithDiv:
390     case ArithMul:
391     case ArithSub:
392         switch (node->binaryUseKind()) {
393         case Int32Use:
394         case Int52RepUse:
395         case DoubleRepUse:
396             def(PureValue(node, node->arithMode()));
397             return;
398         case UntypedUse:
399             read(World);
400             write(Heap);
401             return;
402         default:
403             DFG_CRASH(graph, node, "Bad use kind");
404         }
405
406     case ArithRound:
407     case ArithFloor:
408     case ArithCeil:
409     case ArithTrunc:
410         if (node->child1().useKind() == DoubleRepUse)
411             def(PureValue(node, static_cast<uintptr_t>(node->arithRoundingMode())));
412         else {
413             read(World);
414             write(Heap);
415         }
416         return;
417
418     case CheckCell:
419         def(PureValue(CheckCell, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->cellOperand()));
420         return;
421
422     case CheckNotEmpty:
423         def(PureValue(CheckNotEmpty, AdjacencyList(AdjacencyList::Fixed, node->child1())));
424         return;
425
426     case AssertNotEmpty:
427         write(SideState);
428         return;
429
430     case CheckStringIdent:
431         def(PureValue(CheckStringIdent, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->uidOperand()));
432         return;
433
434     case ConstantStoragePointer:
435         def(PureValue(node, node->storagePointer()));
436         return;
437
438     case KillStack:
439         write(AbstractHeap(Stack, node->unlinkedLocal()));
440         return;
441          
442     case MovHint:
443     case ZombieHint:
444     case ExitOK:
445     case Upsilon:
446     case Phi:
447     case PhantomLocal:
448     case SetArgument:
449     case Jump:
450     case Branch:
451     case Switch:
452     case EntrySwitch:
453     case ForceOSRExit:
454     case CPUIntrinsic:
455     case CheckBadCell:
456     case Return:
457     case Unreachable:
458     case CheckTierUpInLoop:
459     case CheckTierUpAtReturn:
460     case CheckTierUpAndOSREnter:
461     case LoopHint:
462     case ProfileType:
463     case ProfileControlFlow:
464     case PutHint:
465     case InitializeEntrypointArguments:
466     case FilterCallLinkStatus:
467     case FilterGetByIdStatus:
468     case FilterPutByIdStatus:
469     case FilterInByIdStatus:
470         write(SideState);
471         return;
472         
473     case StoreBarrier:
474         read(JSCell_cellState);
475         write(JSCell_cellState);
476         return;
477         
478     case FencedStoreBarrier:
479         read(Heap);
480         write(JSCell_cellState);
481         return;
482
483     case CheckTraps:
484         read(InternalState);
485         write(InternalState);
486         return;
487
488     case InvalidationPoint:
489         write(SideState);
490         def(HeapLocation(InvalidationPointLoc, Watchpoint_fire), LazyNode(node));
491         return;
492
493     case Flush:
494         read(AbstractHeap(Stack, node->local()));
495         write(SideState);
496         return;
497
498     case NotifyWrite:
499         write(Watchpoint_fire);
500         write(SideState);
501         return;
502
503     case PushWithScope: {
504         read(World);
505         write(HeapObjectCount);
506         return;
507     }
508
509     case CreateActivation: {
510         SymbolTable* table = node->castOperand<SymbolTable*>();
511         if (table->singletonScope()->isStillValid())
512             write(Watchpoint_fire);
513         read(HeapObjectCount);
514         write(HeapObjectCount);
515         return;
516     }
517
518     case CreateDirectArguments:
519     case CreateScopedArguments:
520     case CreateClonedArguments:
521         read(Stack);
522         read(HeapObjectCount);
523         write(HeapObjectCount);
524         return;
525
526     case PhantomDirectArguments:
527     case PhantomClonedArguments:
528         // DFG backend requires that the locals that this reads are flushed. FTL backend can handle those
529         // locals being promoted.
530         if (!graph.m_plan.isFTL())
531             read(Stack);
532         
533         // Even though it's phantom, it still has the property that one can't be replaced with another.
534         read(HeapObjectCount);
535         write(HeapObjectCount);
536         return;
537
538     case PhantomSpread:
539     case PhantomNewArrayWithSpread:
540     case PhantomNewArrayBuffer:
541     case PhantomCreateRest:
542         // Even though it's phantom, it still has the property that one can't be replaced with another.
543         read(HeapObjectCount);
544         write(HeapObjectCount);
545         return;
546
547     case CallObjectConstructor:
548         read(HeapObjectCount);
549         write(HeapObjectCount);
550         return;
551
552     case ToThis:
553         read(MiscFields);
554         read(HeapObjectCount);
555         write(HeapObjectCount);
556         return;
557
558     case IsObjectOrNull:
559         read(MiscFields);
560         def(HeapLocation(IsObjectOrNullLoc, MiscFields, node->child1()), LazyNode(node));
561         return;
562         
563     case IsFunction:
564         read(MiscFields);
565         def(HeapLocation(IsFunctionLoc, MiscFields, node->child1()), LazyNode(node));
566         return;
567         
568     case MatchStructure:
569         read(JSCell_structureID);
570         return;
571
572     case ArraySlice:
573         read(MiscFields);
574         read(JSCell_indexingType);
575         read(JSCell_structureID);
576         read(JSObject_butterfly);
577         read(Butterfly_publicLength);
578         read(IndexedDoubleProperties);
579         read(IndexedInt32Properties);
580         read(IndexedContiguousProperties);
581         read(HeapObjectCount);
582         write(HeapObjectCount);
583         return;
584
585     case ArrayIndexOf: {
586         // FIXME: Should support a CSE rule.
587         // https://bugs.webkit.org/show_bug.cgi?id=173173
588         read(MiscFields);
589         read(JSCell_indexingType);
590         read(JSCell_structureID);
591         read(JSObject_butterfly);
592         read(Butterfly_publicLength);
593         switch (node->arrayMode().type()) {
594         case Array::Double:
595             read(IndexedDoubleProperties);
596             return;
597         case Array::Int32:
598             read(IndexedInt32Properties);
599             return;
600         case Array::Contiguous:
601             read(IndexedContiguousProperties);
602             return;
603         default:
604             RELEASE_ASSERT_NOT_REACHED();
605             return;
606         }
607         return;
608     }
609         
610     case GetById:
611     case GetByIdFlush:
612     case GetByIdWithThis:
613     case GetByIdDirect:
614     case GetByIdDirectFlush:
615     case GetByValWithThis:
616     case PutById:
617     case PutByIdWithThis:
618     case PutByValWithThis:
619     case PutByIdFlush:
620     case PutByIdDirect:
621     case PutGetterById:
622     case PutSetterById:
623     case PutGetterSetterById:
624     case PutGetterByVal:
625     case PutSetterByVal:
626     case DefineDataProperty:
627     case DefineAccessorProperty:
628     case DeleteById:
629     case DeleteByVal:
630     case ArrayPush:
631     case ArrayPop:
632     case Call:
633     case DirectCall:
634     case TailCallInlinedCaller:
635     case DirectTailCallInlinedCaller:
636     case Construct:
637     case DirectConstruct:
638     case CallVarargs:
639     case CallForwardVarargs:
640     case TailCallVarargsInlinedCaller:
641     case TailCallForwardVarargsInlinedCaller:
642     case ConstructVarargs:
643     case ConstructForwardVarargs:
644     case ToPrimitive:
645     case InByVal:
646     case InById:
647     case HasOwnProperty:
648     case ValueNegate:
649     case SetFunctionName:
650     case GetDynamicVar:
651     case PutDynamicVar:
652     case ResolveScopeForHoistingFuncDeclInEval:
653     case ResolveScope:
654     case ToObject:
655     case HasGenericProperty:
656     case HasStructureProperty:
657     case GetPropertyEnumerator:
658     case GetDirectPname:
659     case InstanceOfCustom:
660     case ToNumber:
661     case NumberToStringWithRadix:
662     case CreateThis:
663     case InstanceOf:
664     case StringValueOf:
665     case ObjectKeys:
666         read(World);
667         write(Heap);
668         return;
669
670     case ValueBitAnd:
671     case ValueBitXor:
672     case ValueBitOr:
673     case ValueAdd:
674     case ValueSub:
675     case ValueMul:
676     case ValueDiv:
677         if (node->isBinaryUseKind(BigIntUse)) {
678             def(PureValue(node));
679             return;
680         }
681         read(World);
682         write(Heap);
683         return;
684
685     case ObjectToString:
686         switch (node->child1().useKind()) {
687         case OtherUse:
688             def(PureValue(node));
689             return;
690         case UntypedUse:
691             read(World);
692             write(Heap);
693             return;
694         default:
695             RELEASE_ASSERT_NOT_REACHED();
696             return;
697         }
698
699     case AtomicsAdd:
700     case AtomicsAnd:
701     case AtomicsCompareExchange:
702     case AtomicsExchange:
703     case AtomicsLoad:
704     case AtomicsOr:
705     case AtomicsStore:
706     case AtomicsSub:
707     case AtomicsXor: {
708         unsigned numExtraArgs = numExtraAtomicsArgs(node->op());
709         Edge storageEdge = graph.child(node, 2 + numExtraArgs);
710         if (!storageEdge) {
711             read(World);
712             write(Heap);
713             return;
714         }
715         read(TypedArrayProperties);
716         read(MiscFields);
717         write(TypedArrayProperties);
718         return;
719     }
720
721     case CallEval:
722         ASSERT(!node->origin.semantic.inlineCallFrame);
723         read(AbstractHeap(Stack, graph.m_codeBlock->scopeRegister()));
724         read(AbstractHeap(Stack, virtualRegisterForArgument(0)));
725         read(World);
726         write(Heap);
727         return;
728
729     case Throw:
730     case ThrowStaticError:
731     case TailCall:
732     case DirectTailCall:
733     case TailCallVarargs:
734     case TailCallForwardVarargs:
735         read(World);
736         write(SideState);
737         return;
738         
739     case GetGetter:
740         read(GetterSetter_getter);
741         def(HeapLocation(GetterLoc, GetterSetter_getter, node->child1()), LazyNode(node));
742         return;
743         
744     case GetSetter:
745         read(GetterSetter_setter);
746         def(HeapLocation(SetterLoc, GetterSetter_setter, node->child1()), LazyNode(node));
747         return;
748         
749     case GetCallee:
750         read(AbstractHeap(Stack, CallFrameSlot::callee));
751         def(HeapLocation(StackLoc, AbstractHeap(Stack, CallFrameSlot::callee)), LazyNode(node));
752         return;
753
754     case SetCallee:
755         write(AbstractHeap(Stack, CallFrameSlot::callee));
756         return;
757         
758     case GetArgumentCountIncludingThis: {
759         auto heap = AbstractHeap(Stack, remapOperand(node->argumentsInlineCallFrame(), VirtualRegister(CallFrameSlot::argumentCount)));
760         read(heap);
761         def(HeapLocation(StackPayloadLoc, heap), LazyNode(node));
762         return;
763     }
764
765     case SetArgumentCountIncludingThis:
766         write(AbstractHeap(Stack, CallFrameSlot::argumentCount));
767         return;
768
769     case GetRestLength:
770         read(Stack);
771         return;
772         
773     case GetLocal:
774         read(AbstractHeap(Stack, node->local()));
775         def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), LazyNode(node));
776         return;
777         
778     case SetLocal:
779         write(AbstractHeap(Stack, node->local()));
780         def(HeapLocation(StackLoc, AbstractHeap(Stack, node->local())), LazyNode(node->child1().node()));
781         return;
782         
783     case GetStack: {
784         AbstractHeap heap(Stack, node->stackAccessData()->local);
785         read(heap);
786         def(HeapLocation(StackLoc, heap), LazyNode(node));
787         return;
788     }
789         
790     case PutStack: {
791         AbstractHeap heap(Stack, node->stackAccessData()->local);
792         write(heap);
793         def(HeapLocation(StackLoc, heap), LazyNode(node->child1().node()));
794         return;
795     }
796         
797     case LoadVarargs: {
798         read(World);
799         write(Heap);
800         LoadVarargsData* data = node->loadVarargsData();
801         write(AbstractHeap(Stack, data->count.offset()));
802         for (unsigned i = data->limit; i--;)
803             write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
804         return;
805     }
806         
807     case ForwardVarargs: {
808         // We could be way more precise here.
809         read(Stack);
810         
811         LoadVarargsData* data = node->loadVarargsData();
812         write(AbstractHeap(Stack, data->count.offset()));
813         for (unsigned i = data->limit; i--;)
814             write(AbstractHeap(Stack, data->start.offset() + static_cast<int>(i)));
815         return;
816     }
817         
818     case GetByVal: {
819         ArrayMode mode = node->arrayMode();
820         LocationKind indexedPropertyLoc = indexedPropertyLocForResultType(node->result());
821         switch (mode.type()) {
822         case Array::SelectUsingPredictions:
823         case Array::Unprofiled:
824         case Array::SelectUsingArguments:
825             // Assume the worst since we don't have profiling yet.
826             read(World);
827             write(Heap);
828             return;
829             
830         case Array::ForceExit:
831             write(SideState);
832             return;
833             
834         case Array::Generic:
835             read(World);
836             write(Heap);
837             return;
838             
839         case Array::String:
840             if (mode.isOutOfBounds()) {
841                 read(World);
842                 write(Heap);
843                 return;
844             }
845             // This appears to read nothing because it's only reading immutable data.
846             def(PureValue(graph, node, mode.asWord()));
847             return;
848             
849         case Array::DirectArguments:
850             if (mode.isInBounds()) {
851                 read(DirectArgumentsProperties);
852                 def(HeapLocation(indexedPropertyLoc, DirectArgumentsProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
853                 return;
854             }
855             read(World);
856             write(Heap);
857             return;
858             
859         case Array::ScopedArguments:
860             read(ScopeProperties);
861             def(HeapLocation(indexedPropertyLoc, ScopeProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
862             return;
863             
864         case Array::Int32:
865             if (mode.isInBounds()) {
866                 read(Butterfly_publicLength);
867                 read(IndexedInt32Properties);
868                 def(HeapLocation(indexedPropertyLoc, IndexedInt32Properties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
869                 return;
870             }
871             read(World);
872             write(Heap);
873             return;
874             
875         case Array::Double:
876             if (mode.isInBounds()) {
877                 read(Butterfly_publicLength);
878                 read(IndexedDoubleProperties);
879                 LocationKind kind = mode.isSaneChain() ? IndexedPropertyDoubleSaneChainLoc : IndexedPropertyDoubleLoc;
880                 def(HeapLocation(kind, IndexedDoubleProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
881                 return;
882             }
883             read(World);
884             write(Heap);
885             return;
886             
887         case Array::Contiguous:
888             if (mode.isInBounds()) {
889                 read(Butterfly_publicLength);
890                 read(IndexedContiguousProperties);
891                 def(HeapLocation(indexedPropertyLoc, IndexedContiguousProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
892                 return;
893             }
894             read(World);
895             write(Heap);
896             return;
897
898         case Array::Undecided:
899             def(PureValue(graph, node));
900             return;
901             
902         case Array::ArrayStorage:
903         case Array::SlowPutArrayStorage:
904             if (mode.isInBounds()) {
905                 read(Butterfly_vectorLength);
906                 read(IndexedArrayStorageProperties);
907                 return;
908             }
909             read(World);
910             write(Heap);
911             return;
912             
913         case Array::Int8Array:
914         case Array::Int16Array:
915         case Array::Int32Array:
916         case Array::Uint8Array:
917         case Array::Uint8ClampedArray:
918         case Array::Uint16Array:
919         case Array::Uint32Array:
920         case Array::Float32Array:
921         case Array::Float64Array:
922             read(TypedArrayProperties);
923             read(MiscFields);
924             def(HeapLocation(indexedPropertyLoc, TypedArrayProperties, graph.varArgChild(node, 0), graph.varArgChild(node, 1)), LazyNode(node));
925             return;
926         // We should not get an AnyTypedArray in a GetByVal as AnyTypedArray is only created from intrinsics, which
927         // are only added from Inline Caching a GetById.
928         case Array::AnyTypedArray:
929             DFG_CRASH(graph, node, "impossible array mode for get");
930             return;
931         }
932         RELEASE_ASSERT_NOT_REACHED();
933         return;
934     }
935         
936     case GetMyArgumentByVal:
937     case GetMyArgumentByValOutOfBounds: {
938         read(Stack);
939         // FIXME: It would be trivial to have a def here.
940         // https://bugs.webkit.org/show_bug.cgi?id=143077
941         return;
942     }
943
944     case PutByValDirect:
945     case PutByVal:
946     case PutByValAlias: {
947         ArrayMode mode = node->arrayMode();
948         Node* base = graph.varArgChild(node, 0).node();
949         Node* index = graph.varArgChild(node, 1).node();
950         Node* value = graph.varArgChild(node, 2).node();
951         LocationKind indexedPropertyLoc = indexedPropertyLocForResultType(node->result());
952
953         switch (mode.modeForPut().type()) {
954         case Array::SelectUsingPredictions:
955         case Array::SelectUsingArguments:
956         case Array::Unprofiled:
957         case Array::Undecided:
958             // Assume the worst since we don't have profiling yet.
959             read(World);
960             write(Heap);
961             return;
962             
963         case Array::ForceExit:
964             write(SideState);
965             return;
966             
967         case Array::Generic:
968             read(World);
969             write(Heap);
970             return;
971             
972         case Array::Int32:
973             if (node->arrayMode().isOutOfBounds()) {
974                 read(World);
975                 write(Heap);
976                 return;
977             }
978             read(Butterfly_publicLength);
979             read(Butterfly_vectorLength);
980             read(IndexedInt32Properties);
981             write(IndexedInt32Properties);
982             if (node->arrayMode().mayStoreToHole())
983                 write(Butterfly_publicLength);
984             def(HeapLocation(indexedPropertyLoc, IndexedInt32Properties, base, index), LazyNode(value));
985             return;
986             
987         case Array::Double:
988             if (node->arrayMode().isOutOfBounds()) {
989                 read(World);
990                 write(Heap);
991                 return;
992             }
993             read(Butterfly_publicLength);
994             read(Butterfly_vectorLength);
995             read(IndexedDoubleProperties);
996             write(IndexedDoubleProperties);
997             if (node->arrayMode().mayStoreToHole())
998                 write(Butterfly_publicLength);
999             def(HeapLocation(IndexedPropertyDoubleLoc, IndexedDoubleProperties, base, index), LazyNode(value));
1000             def(HeapLocation(IndexedPropertyDoubleSaneChainLoc, IndexedDoubleProperties, base, index), LazyNode(value));
1001             return;
1002             
1003         case Array::Contiguous:
1004             if (node->arrayMode().isOutOfBounds()) {
1005                 read(World);
1006                 write(Heap);
1007                 return;
1008             }
1009             read(Butterfly_publicLength);
1010             read(Butterfly_vectorLength);
1011             read(IndexedContiguousProperties);
1012             write(IndexedContiguousProperties);
1013             if (node->arrayMode().mayStoreToHole())
1014                 write(Butterfly_publicLength);
1015             def(HeapLocation(indexedPropertyLoc, IndexedContiguousProperties, base, index), LazyNode(value));
1016             return;
1017             
1018         case Array::ArrayStorage:
1019             if (node->arrayMode().isOutOfBounds()) {
1020                 read(World);
1021                 write(Heap);
1022                 return;
1023             }
1024             read(Butterfly_publicLength);
1025             read(Butterfly_vectorLength);
1026             read(ArrayStorageProperties);
1027             write(ArrayStorageProperties);
1028             if (node->arrayMode().mayStoreToHole())
1029                 write(Butterfly_publicLength);
1030             return;
1031
1032         case Array::SlowPutArrayStorage:
1033             if (node->arrayMode().mayStoreToHole()) {
1034                 read(World);
1035                 write(Heap);
1036                 return;
1037             }
1038             read(Butterfly_publicLength);
1039             read(Butterfly_vectorLength);
1040             read(ArrayStorageProperties);
1041             write(ArrayStorageProperties);
1042             return;
1043
1044         case Array::Int8Array:
1045         case Array::Int16Array:
1046         case Array::Int32Array:
1047         case Array::Uint8Array:
1048         case Array::Uint8ClampedArray:
1049         case Array::Uint16Array:
1050         case Array::Uint32Array:
1051         case Array::Float32Array:
1052         case Array::Float64Array:
1053             read(MiscFields);
1054             write(TypedArrayProperties);
1055             // FIXME: We can't def() anything here because these operations truncate their inputs.
1056             // https://bugs.webkit.org/show_bug.cgi?id=134737
1057             return;
1058         case Array::AnyTypedArray:
1059         case Array::String:
1060         case Array::DirectArguments:
1061         case Array::ScopedArguments:
1062             DFG_CRASH(graph, node, "impossible array mode for put");
1063             return;
1064         }
1065         RELEASE_ASSERT_NOT_REACHED();
1066         return;
1067     }
1068         
1069     case CheckStructureOrEmpty:
1070     case CheckStructure:
1071         read(JSCell_structureID);
1072         return;
1073
1074     case CheckArray:
1075         read(JSCell_indexingType);
1076         read(JSCell_typeInfoType);
1077         read(JSCell_structureID);
1078         return;
1079
1080     case CheckTypeInfoFlags:
1081         read(JSCell_typeInfoFlags);
1082         def(HeapLocation(CheckTypeInfoFlagsLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node));
1083         return;
1084
1085     case ParseInt:
1086         // Note: We would have eliminated a ParseInt that has just a single child as an Int32Use inside fixup.
1087         if (node->child1().useKind() == StringUse && (!node->child2() || node->child2().useKind() == Int32Use)) {
1088             def(PureValue(node));
1089             return;
1090         }
1091
1092         read(World);
1093         write(Heap);
1094         return;
1095
1096     case OverridesHasInstance:
1097         read(JSCell_typeInfoFlags);
1098         def(HeapLocation(OverridesHasInstanceLoc, JSCell_typeInfoFlags, node->child1()), LazyNode(node));
1099         return;
1100
1101     case PutStructure:
1102         read(JSObject_butterfly);
1103         write(JSCell_structureID);
1104         write(JSCell_typeInfoType);
1105         write(JSCell_typeInfoFlags);
1106         write(JSCell_indexingType);
1107         return;
1108         
1109     case AllocatePropertyStorage:
1110     case ReallocatePropertyStorage:
1111         read(HeapObjectCount);
1112         write(HeapObjectCount);
1113         return;
1114         
1115     case NukeStructureAndSetButterfly:
1116         write(JSObject_butterfly);
1117         write(JSCell_structureID);
1118         def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node->child2().node()));
1119         return;
1120         
1121     case GetButterfly:
1122         read(JSObject_butterfly);
1123         def(HeapLocation(ButterflyLoc, JSObject_butterfly, node->child1()), LazyNode(node));
1124         return;
1125
1126     case CheckSubClass:
1127         def(PureValue(node, node->classInfo()));
1128         return;
1129
1130     case CallDOMGetter: {
1131         DOMJIT::CallDOMGetterSnippet* snippet = node->callDOMGetterData()->snippet;
1132         if (!snippet) {
1133             read(World);
1134             write(Heap);
1135             return;
1136         }
1137         DOMJIT::Effect effect = snippet->effect;
1138         if (effect.reads) {
1139             if (effect.reads == DOMJIT::HeapRange::top())
1140                 read(World);
1141             else
1142                 read(AbstractHeap(DOMState, effect.reads.rawRepresentation()));
1143         }
1144         if (effect.writes) {
1145             if (effect.writes == DOMJIT::HeapRange::top())
1146                 write(Heap);
1147             else
1148                 write(AbstractHeap(DOMState, effect.writes.rawRepresentation()));
1149         }
1150         if (effect.def != DOMJIT::HeapRange::top()) {
1151             DOMJIT::HeapRange range = effect.def;
1152             if (range == DOMJIT::HeapRange::none())
1153                 def(PureValue(node, bitwise_cast<uintptr_t>(node->callDOMGetterData()->customAccessorGetter)));
1154             else {
1155                 // Def with heap location. We do not include "GlobalObject" for that since this information is included in the base node.
1156                 // We only see the DOMJIT getter here. So just including "base" is ok.
1157                 def(HeapLocation(DOMStateLoc, AbstractHeap(DOMState, range.rawRepresentation()), node->child1()), LazyNode(node));
1158             }
1159         }
1160         return;
1161     }
1162
1163     case CallDOM: {
1164         const DOMJIT::Signature* signature = node->signature();
1165         DOMJIT::Effect effect = signature->effect;
1166         if (effect.reads) {
1167             if (effect.reads == DOMJIT::HeapRange::top())
1168                 read(World);
1169             else
1170                 read(AbstractHeap(DOMState, effect.reads.rawRepresentation()));
1171         }
1172         if (effect.writes) {
1173             if (effect.writes == DOMJIT::HeapRange::top())
1174                 write(Heap);
1175             else
1176                 write(AbstractHeap(DOMState, effect.writes.rawRepresentation()));
1177         }
1178         ASSERT_WITH_MESSAGE(effect.def == DOMJIT::HeapRange::top(), "Currently, we do not accept any def for CallDOM.");
1179         return;
1180     }
1181
1182     case Arrayify:
1183     case ArrayifyToStructure:
1184         read(JSCell_structureID);
1185         read(JSCell_indexingType);
1186         read(JSObject_butterfly);
1187         write(JSCell_structureID);
1188         write(JSCell_indexingType);
1189         write(JSObject_butterfly);
1190         write(Watchpoint_fire);
1191         return;
1192         
1193     case GetIndexedPropertyStorage:
1194         if (node->arrayMode().type() == Array::String) {
1195             def(PureValue(node, node->arrayMode().asWord()));
1196             return;
1197         }
1198         read(MiscFields);
1199         def(HeapLocation(IndexedPropertyStorageLoc, MiscFields, node->child1()), LazyNode(node));
1200         return;
1201         
1202     case GetTypedArrayByteOffset:
1203         read(MiscFields);
1204         def(HeapLocation(TypedArrayByteOffsetLoc, MiscFields, node->child1()), LazyNode(node));
1205         return;
1206
1207     case GetPrototypeOf: {
1208         switch (node->child1().useKind()) {
1209         case ArrayUse:
1210         case FunctionUse:
1211         case FinalObjectUse:
1212             read(JSCell_structureID);
1213             read(JSObject_butterfly);
1214             read(NamedProperties); // Poly proto could load prototype from its slot.
1215             def(HeapLocation(PrototypeLoc, NamedProperties, node->child1()), LazyNode(node));
1216             return;
1217         default:
1218             read(World);
1219             write(Heap);
1220             return;
1221         }
1222     }
1223         
1224     case GetByOffset:
1225     case GetGetterSetterByOffset: {
1226         unsigned identifierNumber = node->storageAccessData().identifierNumber;
1227         AbstractHeap heap(NamedProperties, identifierNumber);
1228         read(heap);
1229         def(HeapLocation(NamedPropertyLoc, heap, node->child2()), LazyNode(node));
1230         return;
1231     }
1232
1233     case TryGetById: {
1234         read(Heap);
1235         return;
1236     }
1237
1238     case MultiGetByOffset: {
1239         read(JSCell_structureID);
1240         read(JSObject_butterfly);
1241         AbstractHeap heap(NamedProperties, node->multiGetByOffsetData().identifierNumber);
1242         read(heap);
1243         def(HeapLocation(NamedPropertyLoc, heap, node->child1()), LazyNode(node));
1244         return;
1245     }
1246         
1247     case MultiPutByOffset: {
1248         read(JSCell_structureID);
1249         read(JSObject_butterfly);
1250         AbstractHeap heap(NamedProperties, node->multiPutByOffsetData().identifierNumber);
1251         write(heap);
1252         if (node->multiPutByOffsetData().writesStructures())
1253             write(JSCell_structureID);
1254         if (node->multiPutByOffsetData().reallocatesStorage())
1255             write(JSObject_butterfly);
1256         def(HeapLocation(NamedPropertyLoc, heap, node->child1()), LazyNode(node->child2().node()));
1257         return;
1258     }
1259         
1260     case PutByOffset: {
1261         unsigned identifierNumber = node->storageAccessData().identifierNumber;
1262         AbstractHeap heap(NamedProperties, identifierNumber);
1263         write(heap);
1264         def(HeapLocation(NamedPropertyLoc, heap, node->child2()), LazyNode(node->child3().node()));
1265         return;
1266     }
1267         
1268     case GetArrayLength: {
1269         ArrayMode mode = node->arrayMode();
1270         switch (mode.type()) {
1271         case Array::Undecided:
1272         case Array::Int32:
1273         case Array::Double:
1274         case Array::Contiguous:
1275         case Array::ArrayStorage:
1276         case Array::SlowPutArrayStorage:
1277             read(Butterfly_publicLength);
1278             def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node->child1()), LazyNode(node));
1279             return;
1280             
1281         case Array::String:
1282             def(PureValue(node, mode.asWord()));
1283             return;
1284
1285         case Array::DirectArguments:
1286         case Array::ScopedArguments:
1287             read(MiscFields);
1288             def(HeapLocation(ArrayLengthLoc, MiscFields, node->child1()), LazyNode(node));
1289             return;
1290
1291         default:
1292             ASSERT(mode.isSomeTypedArrayView());
1293             read(MiscFields);
1294             def(HeapLocation(ArrayLengthLoc, MiscFields, node->child1()), LazyNode(node));
1295             return;
1296         }
1297     }
1298
1299     case GetVectorLength: {
1300         ArrayMode mode = node->arrayMode();
1301         switch (mode.type()) {
1302         case Array::ArrayStorage:
1303         case Array::SlowPutArrayStorage:
1304             read(Butterfly_vectorLength);
1305             def(HeapLocation(VectorLengthLoc, Butterfly_vectorLength, node->child1()), LazyNode(node));
1306             return;
1307
1308         default:
1309             RELEASE_ASSERT_NOT_REACHED();
1310             return;
1311         }
1312     }
1313         
1314     case GetClosureVar:
1315         read(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
1316         def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child1()), LazyNode(node));
1317         return;
1318         
1319     case PutClosureVar:
1320         write(AbstractHeap(ScopeProperties, node->scopeOffset().offset()));
1321         def(HeapLocation(ClosureVariableLoc, AbstractHeap(ScopeProperties, node->scopeOffset().offset()), node->child1()), LazyNode(node->child2().node()));
1322         return;
1323
1324     case GetRegExpObjectLastIndex:
1325         read(RegExpObject_lastIndex);
1326         def(HeapLocation(RegExpObjectLastIndexLoc, RegExpObject_lastIndex, node->child1()), LazyNode(node));
1327         return;
1328
1329     case SetRegExpObjectLastIndex:
1330         write(RegExpObject_lastIndex);
1331         def(HeapLocation(RegExpObjectLastIndexLoc, RegExpObject_lastIndex, node->child1()), LazyNode(node->child2().node()));
1332         return;
1333
1334     case RecordRegExpCachedResult:
1335         write(RegExpState);
1336         return;
1337         
1338     case GetFromArguments: {
1339         AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
1340         read(heap);
1341         def(HeapLocation(DirectArgumentsLoc, heap, node->child1()), LazyNode(node));
1342         return;
1343     }
1344         
1345     case PutToArguments: {
1346         AbstractHeap heap(DirectArgumentsProperties, node->capturedArgumentsOffset().offset());
1347         write(heap);
1348         def(HeapLocation(DirectArgumentsLoc, heap, node->child1()), LazyNode(node->child2().node()));
1349         return;
1350     }
1351
1352     case GetArgument: {
1353         read(Stack);
1354         // FIXME: It would be trivial to have a def here.
1355         // https://bugs.webkit.org/show_bug.cgi?id=143077
1356         return;
1357     }
1358         
1359     case GetGlobalVar:
1360     case GetGlobalLexicalVariable:
1361         read(AbstractHeap(Absolute, node->variablePointer()));
1362         def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), LazyNode(node));
1363         return;
1364         
1365     case PutGlobalVariable:
1366         write(AbstractHeap(Absolute, node->variablePointer()));
1367         def(HeapLocation(GlobalVariableLoc, AbstractHeap(Absolute, node->variablePointer())), LazyNode(node->child2().node()));
1368         return;
1369
1370     case NewArrayWithSize:
1371         read(HeapObjectCount);
1372         write(HeapObjectCount);
1373         return;
1374
1375     case NewTypedArray:
1376         switch (node->child1().useKind()) {
1377         case Int32Use:
1378             read(HeapObjectCount);
1379             write(HeapObjectCount);
1380             return;
1381         case UntypedUse:
1382             read(World);
1383             write(Heap);
1384             return;
1385         default:
1386             DFG_CRASH(graph, node, "Bad use kind");
1387         }
1388         break;
1389
1390     case NewArrayWithSpread: {
1391         // This also reads from JSFixedArray's data store, but we don't have any way of describing that yet.
1392         read(HeapObjectCount);
1393         for (unsigned i = 0; i < node->numChildren(); i++) {
1394             Node* child = graph.varArgChild(node, i).node();
1395             if (child->op() == PhantomSpread) {
1396                 read(Stack);
1397                 break;
1398             }
1399         }
1400         write(HeapObjectCount);
1401         return;
1402     }
1403
1404     case Spread: {
1405         if (node->child1()->op() == PhantomNewArrayBuffer) {
1406             read(MiscFields);
1407             return;
1408         }
1409
1410         if (node->child1()->op() == PhantomCreateRest) {
1411             read(Stack);
1412             write(HeapObjectCount);
1413             return;
1414         }
1415
1416         read(World);
1417         write(Heap);
1418         return;
1419     }
1420
1421     case NewArray: {
1422         read(HeapObjectCount);
1423         write(HeapObjectCount);
1424
1425         unsigned numElements = node->numChildren();
1426
1427         def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node),
1428             LazyNode(graph.freeze(jsNumber(numElements))));
1429
1430         if (!numElements)
1431             return;
1432
1433         AbstractHeap heap;
1434         LocationKind indexedPropertyLoc;
1435         switch (node->indexingType()) {
1436         case ALL_DOUBLE_INDEXING_TYPES:
1437             heap = IndexedDoubleProperties;
1438             indexedPropertyLoc = IndexedPropertyDoubleLoc;
1439             break;
1440
1441         case ALL_INT32_INDEXING_TYPES:
1442             heap = IndexedInt32Properties;
1443             indexedPropertyLoc = IndexedPropertyJSLoc;
1444             break;
1445
1446         case ALL_CONTIGUOUS_INDEXING_TYPES:
1447             heap = IndexedContiguousProperties;
1448             indexedPropertyLoc = IndexedPropertyJSLoc;
1449             break;
1450
1451         default:
1452             return;
1453         }
1454
1455         if (numElements < graph.m_uint32ValuesInUse.size()) {
1456             for (unsigned operandIdx = 0; operandIdx < numElements; ++operandIdx) {
1457                 Edge use = graph.m_varArgChildren[node->firstChild() + operandIdx];
1458                 def(HeapLocation(indexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(operandIdx)))),
1459                     LazyNode(use.node()));
1460             }
1461         } else {
1462             for (uint32_t operandIdx : graph.m_uint32ValuesInUse) {
1463                 if (operandIdx >= numElements)
1464                     continue;
1465                 Edge use = graph.m_varArgChildren[node->firstChild() + operandIdx];
1466                 // operandIdx comes from graph.m_uint32ValuesInUse and thus is guaranteed to be already frozen
1467                 def(HeapLocation(indexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(operandIdx)))),
1468                     LazyNode(use.node()));
1469             }
1470         }
1471         return;
1472     }
1473
1474     case NewArrayBuffer: {
1475         read(HeapObjectCount);
1476         write(HeapObjectCount);
1477
1478         auto* array = node->castOperand<JSImmutableButterfly*>();
1479         unsigned numElements = array->length();
1480         def(HeapLocation(ArrayLengthLoc, Butterfly_publicLength, node),
1481             LazyNode(graph.freeze(jsNumber(numElements))));
1482
1483         AbstractHeap heap;
1484         LocationKind indexedPropertyLoc;
1485         NodeType op = JSConstant;
1486         switch (node->indexingType()) {
1487         case ALL_DOUBLE_INDEXING_TYPES:
1488             heap = IndexedDoubleProperties;
1489             indexedPropertyLoc = IndexedPropertyDoubleLoc;
1490             op = DoubleConstant;
1491             break;
1492
1493         case ALL_INT32_INDEXING_TYPES:
1494             heap = IndexedInt32Properties;
1495             indexedPropertyLoc = IndexedPropertyJSLoc;
1496             break;
1497
1498         case ALL_CONTIGUOUS_INDEXING_TYPES:
1499             heap = IndexedContiguousProperties;
1500             indexedPropertyLoc = IndexedPropertyJSLoc;
1501             break;
1502
1503         default:
1504             return;
1505         }
1506
1507         if (numElements < graph.m_uint32ValuesInUse.size()) {
1508             for (unsigned index = 0; index < numElements; ++index) {
1509                 def(HeapLocation(indexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(index)))),
1510                     LazyNode(graph.freeze(array->get(index)), op));
1511             }
1512         } else {
1513             Vector<uint32_t> possibleIndices;
1514             for (uint32_t index : graph.m_uint32ValuesInUse) {
1515                 if (index >= numElements)
1516                     continue;
1517                 possibleIndices.append(index);
1518             }
1519             for (uint32_t index : possibleIndices) {
1520                 def(HeapLocation(indexedPropertyLoc, heap, node, LazyNode(graph.freeze(jsNumber(index)))),
1521                     LazyNode(graph.freeze(array->get(index)), op));
1522             }
1523         }
1524         return;
1525     }
1526
1527     case CreateRest: {
1528         if (!graph.isWatchingHavingABadTimeWatchpoint(node)) {
1529             // This means we're already having a bad time.
1530             read(World);
1531             write(Heap);
1532             return;
1533         }
1534         read(Stack);
1535         read(HeapObjectCount);
1536         write(HeapObjectCount);
1537         return;
1538     }
1539
1540     case ObjectCreate: {
1541         switch (node->child1().useKind()) {
1542         case ObjectUse:
1543             read(HeapObjectCount);
1544             write(HeapObjectCount);
1545             return;
1546         case UntypedUse:
1547             read(World);
1548             write(Heap);
1549             return;
1550         default:
1551             RELEASE_ASSERT_NOT_REACHED();
1552             return;
1553         }
1554     }
1555
1556     case NewObject:
1557     case NewRegexp:
1558     case NewSymbol:
1559     case NewStringObject:
1560     case PhantomNewObject:
1561     case MaterializeNewObject:
1562     case PhantomNewFunction:
1563     case PhantomNewGeneratorFunction:
1564     case PhantomNewAsyncFunction:
1565     case PhantomNewAsyncGeneratorFunction:
1566     case PhantomCreateActivation:
1567     case MaterializeCreateActivation:
1568     case PhantomNewRegexp:
1569         read(HeapObjectCount);
1570         write(HeapObjectCount);
1571         return;
1572
1573     case NewFunction:
1574     case NewGeneratorFunction:
1575     case NewAsyncGeneratorFunction:
1576     case NewAsyncFunction:
1577         if (node->castOperand<FunctionExecutable*>()->singletonFunction()->isStillValid())
1578             write(Watchpoint_fire);
1579         read(HeapObjectCount);
1580         write(HeapObjectCount);
1581         return;
1582
1583     case RegExpExec:
1584     case RegExpTest:
1585         // Even if we've proven known input types as RegExpObject and String,
1586         // accessing lastIndex is effectful if it's a global regexp.
1587         read(World);
1588         write(Heap);
1589         return;
1590
1591     case RegExpMatchFast:
1592         read(RegExpState);
1593         read(RegExpObject_lastIndex);
1594         write(RegExpState);
1595         write(RegExpObject_lastIndex);
1596         return;
1597
1598     case RegExpExecNonGlobalOrSticky:
1599     case RegExpMatchFastGlobal:
1600         read(RegExpState);
1601         write(RegExpState);
1602         return;
1603
1604     case StringReplace:
1605     case StringReplaceRegExp:
1606         if (node->child1().useKind() == StringUse
1607             && node->child2().useKind() == RegExpObjectUse
1608             && node->child3().useKind() == StringUse) {
1609             read(RegExpState);
1610             read(RegExpObject_lastIndex);
1611             write(RegExpState);
1612             write(RegExpObject_lastIndex);
1613             return;
1614         }
1615         read(World);
1616         write(Heap);
1617         return;
1618
1619     case StringCharAt:
1620         if (node->arrayMode().isOutOfBounds()) {
1621             read(World);
1622             write(Heap);
1623             return;
1624         }
1625         def(PureValue(node));
1626         return;
1627
1628     case CompareBelow:
1629     case CompareBelowEq:
1630         def(PureValue(node));
1631         return;
1632         
1633     case CompareEq:
1634     case CompareLess:
1635     case CompareLessEq:
1636     case CompareGreater:
1637     case CompareGreaterEq:
1638         if (node->isBinaryUseKind(StringUse)) {
1639             read(HeapObjectCount);
1640             write(HeapObjectCount);
1641             return;
1642         }
1643
1644         if (node->isBinaryUseKind(UntypedUse)) {
1645             read(World);
1646             write(Heap);
1647             return;
1648         }
1649
1650         def(PureValue(node));
1651         return;
1652
1653     case ToString:
1654     case CallStringConstructor:
1655         switch (node->child1().useKind()) {
1656         case StringObjectUse:
1657         case StringOrStringObjectUse:
1658             // These don't def a pure value, unfortunately. I'll avoid load-eliminating these for
1659             // now.
1660             return;
1661             
1662         case CellUse:
1663         case UntypedUse:
1664             read(World);
1665             write(Heap);
1666             return;
1667
1668         case Int32Use:
1669         case Int52RepUse:
1670         case DoubleRepUse:
1671         case NotCellUse:
1672             def(PureValue(node));
1673             return;
1674             
1675         default:
1676             RELEASE_ASSERT_NOT_REACHED();
1677             return;
1678         }
1679         
1680     case CountExecution:
1681     case SuperSamplerBegin:
1682     case SuperSamplerEnd:
1683         read(InternalState);
1684         write(InternalState);
1685         return;
1686         
1687     case LogShadowChickenPrologue:
1688     case LogShadowChickenTail:
1689         write(SideState);
1690         return;
1691
1692     case MapHash:
1693         def(PureValue(node));
1694         return;
1695
1696     case NormalizeMapKey:
1697         def(PureValue(node));
1698         return;
1699
1700     case GetMapBucket: {
1701         Edge& mapEdge = node->child1();
1702         Edge& keyEdge = node->child2();
1703         AbstractHeapKind heap = (mapEdge.useKind() == MapObjectUse) ? JSMapFields : JSSetFields;
1704         read(heap);
1705         def(HeapLocation(MapBucketLoc, heap, mapEdge, keyEdge), LazyNode(node));
1706         return;
1707     }
1708
1709     case GetMapBucketHead: {
1710         Edge& mapEdge = node->child1();
1711         AbstractHeapKind heap = (mapEdge.useKind() == MapObjectUse) ? JSMapFields : JSSetFields;
1712         read(heap);
1713         def(HeapLocation(MapBucketHeadLoc, heap, mapEdge), LazyNode(node));
1714         return;
1715     }
1716
1717     case GetMapBucketNext: {
1718         AbstractHeapKind heap = (node->bucketOwnerType() == BucketOwnerType::Map) ? JSMapFields : JSSetFields;
1719         read(heap);
1720         Edge& bucketEdge = node->child1();
1721         def(HeapLocation(MapBucketNextLoc, heap, bucketEdge), LazyNode(node));
1722         return;
1723     }
1724
1725     case LoadKeyFromMapBucket: {
1726         AbstractHeapKind heap = (node->bucketOwnerType() == BucketOwnerType::Map) ? JSMapFields : JSSetFields;
1727         read(heap);
1728         Edge& bucketEdge = node->child1();
1729         def(HeapLocation(MapBucketKeyLoc, heap, bucketEdge), LazyNode(node));
1730         return;
1731     }
1732
1733     case LoadValueFromMapBucket: {
1734         AbstractHeapKind heap = (node->bucketOwnerType() == BucketOwnerType::Map) ? JSMapFields : JSSetFields;
1735         read(heap);
1736         Edge& bucketEdge = node->child1();
1737         def(HeapLocation(MapBucketValueLoc, heap, bucketEdge), LazyNode(node));
1738         return;
1739     }
1740
1741     case WeakMapGet: {
1742         Edge& mapEdge = node->child1();
1743         Edge& keyEdge = node->child2();
1744         AbstractHeapKind heap = (mapEdge.useKind() == WeakMapObjectUse) ? JSWeakMapFields : JSWeakSetFields;
1745         read(heap);
1746         def(HeapLocation(WeakMapGetLoc, heap, mapEdge, keyEdge), LazyNode(node));
1747         return;
1748     }
1749
1750     case SetAdd: {
1751         Edge& mapEdge = node->child1();
1752         Edge& keyEdge = node->child2();
1753         write(JSSetFields);
1754         def(HeapLocation(MapBucketLoc, JSSetFields, mapEdge, keyEdge), LazyNode(node));
1755         return;
1756     }
1757
1758     case MapSet: {
1759         Edge& mapEdge = graph.varArgChild(node, 0);
1760         Edge& keyEdge = graph.varArgChild(node, 1);
1761         write(JSMapFields);
1762         def(HeapLocation(MapBucketLoc, JSMapFields, mapEdge, keyEdge), LazyNode(node));
1763         return;
1764     }
1765
1766     case WeakSetAdd: {
1767         Edge& mapEdge = node->child1();
1768         Edge& keyEdge = node->child2();
1769         write(JSWeakSetFields);
1770         def(HeapLocation(WeakMapGetLoc, JSWeakSetFields, mapEdge, keyEdge), LazyNode(keyEdge.node()));
1771         return;
1772     }
1773
1774     case WeakMapSet: {
1775         Edge& mapEdge = graph.varArgChild(node, 0);
1776         Edge& keyEdge = graph.varArgChild(node, 1);
1777         Edge& valueEdge = graph.varArgChild(node, 2);
1778         write(JSWeakMapFields);
1779         def(HeapLocation(WeakMapGetLoc, JSWeakMapFields, mapEdge, keyEdge), LazyNode(valueEdge.node()));
1780         return;
1781     }
1782
1783     case ExtractValueFromWeakMapGet:
1784         def(PureValue(node));
1785         return;
1786
1787     case StringSlice:
1788         def(PureValue(node));
1789         return;
1790
1791     case ToLowerCase:
1792         def(PureValue(node));
1793         return;
1794
1795     case NumberToStringWithValidRadixConstant:
1796         def(PureValue(node, node->validRadixConstant()));
1797         return;
1798
1799     case DataViewGetFloat:
1800     case DataViewGetInt: {
1801         read(MiscFields);
1802         read(TypedArrayProperties);
1803         LocationKind indexedPropertyLoc = indexedPropertyLocForResultType(node->result());
1804         def(HeapLocation(indexedPropertyLoc, AbstractHeap(TypedArrayProperties, node->dataViewData().asQuadWord),
1805             node->child1(), node->child2(), node->child3()), LazyNode(node));
1806         return;
1807     }
1808
1809     case DataViewSet: {
1810         read(MiscFields);
1811         read(TypedArrayProperties);
1812         write(TypedArrayProperties);
1813         return;
1814     }
1815
1816     case LastNodeType:
1817         RELEASE_ASSERT_NOT_REACHED();
1818         return;
1819     }
1820     
1821     DFG_CRASH(graph, node, toCString("Unrecognized node type: ", Graph::opName(node->op())).data());
1822 }
1823
1824 class NoOpClobberize {
1825 public:
1826     NoOpClobberize() { }
1827     template<typename... T>
1828     void operator()(T...) const { }
1829 };
1830
1831 class CheckClobberize {
1832 public:
1833     CheckClobberize()
1834         : m_result(false)
1835     {
1836     }
1837     
1838     template<typename... T>
1839     void operator()(T...) const { m_result = true; }
1840     
1841     bool result() const { return m_result; }
1842     
1843 private:
1844     mutable bool m_result;
1845 };
1846
1847 bool doesWrites(Graph&, Node*);
1848
1849 class AbstractHeapOverlaps {
1850 public:
1851     AbstractHeapOverlaps(AbstractHeap heap)
1852         : m_heap(heap)
1853         , m_result(false)
1854     {
1855     }
1856     
1857     void operator()(AbstractHeap otherHeap) const
1858     {
1859         if (m_result)
1860             return;
1861         m_result = m_heap.overlaps(otherHeap);
1862     }
1863     
1864     bool result() const { return m_result; }
1865
1866 private:
1867     AbstractHeap m_heap;
1868     mutable bool m_result;
1869 };
1870
1871 bool accessesOverlap(Graph&, Node*, AbstractHeap);
1872 bool writesOverlap(Graph&, Node*, AbstractHeap);
1873
1874 bool clobbersHeap(Graph&, Node*);
1875
1876 // We would have used bind() for these, but because of the overlaoding that we are doing,
1877 // it's quite a bit of clearer to just write this out the traditional way.
1878
1879 template<typename T>
1880 class ReadMethodClobberize {
1881 public:
1882     ReadMethodClobberize(T& value)
1883         : m_value(value)
1884     {
1885     }
1886     
1887     void operator()(AbstractHeap heap) const
1888     {
1889         m_value.read(heap);
1890     }
1891 private:
1892     T& m_value;
1893 };
1894
1895 template<typename T>
1896 class WriteMethodClobberize {
1897 public:
1898     WriteMethodClobberize(T& value)
1899         : m_value(value)
1900     {
1901     }
1902     
1903     void operator()(AbstractHeap heap) const
1904     {
1905         m_value.write(heap);
1906     }
1907 private:
1908     T& m_value;
1909 };
1910
1911 template<typename T>
1912 class DefMethodClobberize {
1913 public:
1914     DefMethodClobberize(T& value)
1915         : m_value(value)
1916     {
1917     }
1918     
1919     void operator()(PureValue value) const
1920     {
1921         m_value.def(value);
1922     }
1923     
1924     void operator()(HeapLocation location, LazyNode node) const
1925     {
1926         m_value.def(location, node);
1927     }
1928
1929 private:
1930     T& m_value;
1931 };
1932
1933 template<typename Adaptor>
1934 void clobberize(Graph& graph, Node* node, Adaptor& adaptor)
1935 {
1936     ReadMethodClobberize<Adaptor> read(adaptor);
1937     WriteMethodClobberize<Adaptor> write(adaptor);
1938     DefMethodClobberize<Adaptor> def(adaptor);
1939     clobberize(graph, node, read, write, def);
1940 }
1941
1942 } } // namespace JSC::DFG
1943
1944 #endif // ENABLE(DFG_JIT)