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