Merge r169148, r169185, r169188, r169578, r169582, r169584, r169588, r169753 from...
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGAbstractInterpreterInlines.h
1 /*
2  * Copyright (C) 2013, 2014 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 #ifndef DFGAbstractInterpreterInlines_h
27 #define DFGAbstractInterpreterInlines_h
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGAbstractInterpreter.h"
32 #include "GetByIdStatus.h"
33 #include "Operations.h"
34 #include "PutByIdStatus.h"
35 #include "StringObject.h"
36
37 namespace JSC { namespace DFG {
38
39 template<typename AbstractStateType>
40 AbstractInterpreter<AbstractStateType>::AbstractInterpreter(Graph& graph, AbstractStateType& state)
41     : m_codeBlock(graph.m_codeBlock)
42     , m_graph(graph)
43     , m_state(state)
44 {
45 }
46
47 template<typename AbstractStateType>
48 AbstractInterpreter<AbstractStateType>::~AbstractInterpreter()
49 {
50 }
51
52 template<typename AbstractStateType>
53 typename AbstractInterpreter<AbstractStateType>::BooleanResult
54 AbstractInterpreter<AbstractStateType>::booleanResult(
55     Node* node, AbstractValue& value)
56 {
57     JSValue childConst = value.value();
58     if (childConst) {
59         if (childConst.toBoolean(m_codeBlock->globalObjectFor(node->origin.semantic)->globalExec()))
60             return DefinitelyTrue;
61         return DefinitelyFalse;
62     }
63
64     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
65     if (isCellSpeculation(value.m_type) && !value.m_structure.isTop()) {
66         bool allTrue = true;
67         for (unsigned i = value.m_structure.size(); i--;) {
68             Structure* structure = value.m_structure[i];
69             if (structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
70                 || structure->typeInfo().type() == StringType) {
71                 allTrue = false;
72                 break;
73             }
74         }
75         if (allTrue)
76             return DefinitelyTrue;
77     }
78     
79     return UnknownBooleanResult;
80 }
81
82 template<typename AbstractStateType>
83 bool AbstractInterpreter<AbstractStateType>::startExecuting(Node* node)
84 {
85     ASSERT(m_state.block());
86     ASSERT(m_state.isValid());
87     
88     m_state.setDidClobber(false);
89     
90     node->setCanExit(false);
91     
92     return node->shouldGenerate();
93 }
94
95 template<typename AbstractStateType>
96 bool AbstractInterpreter<AbstractStateType>::startExecuting(unsigned indexInBlock)
97 {
98     return startExecuting(m_state.block()->at(indexInBlock));
99 }
100
101 template<typename AbstractStateType>
102 void AbstractInterpreter<AbstractStateType>::executeEdges(Node* node)
103 {
104     DFG_NODE_DO_TO_CHILDREN(m_graph, node, filterEdgeByUse);
105 }
106
107 template<typename AbstractStateType>
108 void AbstractInterpreter<AbstractStateType>::executeEdges(unsigned indexInBlock)
109 {
110     executeEdges(m_state.block()->at(indexInBlock));
111 }
112
113 template<typename AbstractStateType>
114 void AbstractInterpreter<AbstractStateType>::verifyEdge(Node* node, Edge edge)
115 {
116     if (!(forNode(edge).m_type & ~typeFilterFor(edge.useKind())))
117         return;
118     
119     DFG_CRASH(m_graph, node, toCString("Edge verification error: ", node, "->", edge, " was expected to have type ", SpeculationDump(typeFilterFor(edge.useKind())), " but has type ", SpeculationDump(forNode(edge).m_type)).data());
120 }
121
122 template<typename AbstractStateType>
123 void AbstractInterpreter<AbstractStateType>::verifyEdges(Node* node)
124 {
125     DFG_NODE_DO_TO_CHILDREN(m_graph, node, verifyEdge);
126 }
127
128 template<typename AbstractStateType>
129 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned clobberLimit, Node* node)
130 {
131     if (!ASSERT_DISABLED)
132         verifyEdges(node);
133     
134     m_state.createValueForNode(node);
135     
136     switch (node->op()) {
137     case JSConstant:
138     case DoubleConstant:
139     case Int52Constant:
140     case WeakJSConstant:
141     case PhantomArguments: {
142         setBuiltInConstant(node, m_graph.valueOfJSConstant(node));
143         break;
144     }
145         
146     case Identity: {
147         forNode(node) = forNode(node->child1());
148         break;
149     }
150         
151     case GetArgument: {
152         ASSERT(m_graph.m_form == SSA);
153         VariableAccessData* variable = node->variableAccessData();
154         AbstractValue& value = m_state.variables().operand(variable->local().offset());
155         ASSERT(value.isHeapTop());
156         FiltrationResult result =
157             value.filter(typeFilterFor(useKindFor(variable->flushFormat())));
158         ASSERT_UNUSED(result, result == FiltrationOK);
159         forNode(node) = value;
160         break;
161     }
162         
163     case ExtractOSREntryLocal: {
164         if (!(node->unlinkedLocal().isArgument())
165             && m_graph.m_lazyVars.get(node->unlinkedLocal().toLocal())) {
166             // This is kind of pessimistic - we could know in some cases that the
167             // DFG code at the point of the OSR had already initialized the lazy
168             // variable. But maybe this is fine, since we're inserting OSR
169             // entrypoints very early in the pipeline - so any lazy initializations
170             // ought to be hoisted out anyway.
171             forNode(node).makeBytecodeTop();
172         } else
173             forNode(node).makeHeapTop();
174         break;
175     }
176             
177     case GetLocal: {
178         VariableAccessData* variableAccessData = node->variableAccessData();
179         AbstractValue value = m_state.variables().operand(variableAccessData->local().offset());
180         if (!variableAccessData->isCaptured()) {
181             if (value.isClear())
182                 node->setCanExit(true);
183         }
184         if (value.value())
185             m_state.setFoundConstants(true);
186         forNode(node) = value;
187         break;
188     }
189         
190     case GetLocalUnlinked: {
191         AbstractValue value = m_state.variables().operand(node->unlinkedLocal().offset());
192         if (value.value())
193             m_state.setFoundConstants(true);
194         forNode(node) = value;
195         break;
196     }
197         
198     case SetLocal: {
199         m_state.variables().operand(node->local().offset()) = forNode(node->child1());
200         break;
201     }
202         
203     case MovHint: {
204         // Don't need to do anything. A MovHint only informs us about what would have happened
205         // in bytecode, but this code is just concerned with what is actually happening during
206         // DFG execution.
207         break;
208     }
209         
210     case SetArgument:
211         // Assert that the state of arguments has been set.
212         ASSERT(!m_state.block()->valuesAtHead.operand(node->local()).isClear());
213         break;
214             
215     case BitAnd:
216     case BitOr:
217     case BitXor:
218     case BitRShift:
219     case BitLShift:
220     case BitURShift: {
221         JSValue left = forNode(node->child1()).value();
222         JSValue right = forNode(node->child2()).value();
223         if (left && right && left.isInt32() && right.isInt32()) {
224             int32_t a = left.asInt32();
225             int32_t b = right.asInt32();
226             switch (node->op()) {
227             case BitAnd:
228                 setConstant(node, JSValue(a & b));
229                 break;
230             case BitOr:
231                 setConstant(node, JSValue(a | b));
232                 break;
233             case BitXor:
234                 setConstant(node, JSValue(a ^ b));
235                 break;
236             case BitRShift:
237                 setConstant(node, JSValue(a >> static_cast<uint32_t>(b)));
238                 break;
239             case BitLShift:
240                 setConstant(node, JSValue(a << static_cast<uint32_t>(b)));
241                 break;
242             case BitURShift:
243                 setConstant(node, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
244                 break;
245             default:
246                 RELEASE_ASSERT_NOT_REACHED();
247                 break;
248             }
249             break;
250         }
251         forNode(node).setType(SpecInt32);
252         break;
253     }
254         
255     case UInt32ToNumber: {
256         JSValue child = forNode(node->child1()).value();
257         if (doesOverflow(node->arithMode())) {
258             if (child && child.isInt32()) {
259                 uint32_t value = child.asInt32();
260                 setConstant(node, jsNumber(value));
261                 break;
262             }
263             forNode(node).setType(SpecInt52AsDouble);
264             break;
265         }
266         if (child && child.isInt32()) {
267             int32_t value = child.asInt32();
268             if (value >= 0) {
269                 setConstant(node, jsNumber(value));
270                 break;
271             }
272         }
273         forNode(node).setType(SpecInt32);
274         node->setCanExit(true);
275         break;
276     }
277         
278     case BooleanToNumber: {
279         JSValue concreteValue = forNode(node->child1()).value();
280         if (concreteValue) {
281             if (concreteValue.isBoolean())
282                 setConstant(node, jsNumber(concreteValue.asBoolean()));
283             else
284                 setConstant(node, concreteValue);
285             break;
286         }
287         AbstractValue& value = forNode(node);
288         value = forNode(node->child1());
289         if (node->child1().useKind() == UntypedUse && !(value.m_type & ~SpecBoolean))
290             m_state.setFoundConstants(true);
291         if (value.m_type & SpecBoolean) {
292             value.merge(SpecInt32);
293             value.filter(~SpecBoolean);
294         }
295         break;
296     }
297             
298     case DoubleAsInt32: {
299         JSValue child = forNode(node->child1()).value();
300         if (child && child.isNumber()) {
301             double asDouble = child.asNumber();
302             int32_t asInt = JSC::toInt32(asDouble);
303             if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)) {
304                 setConstant(node, JSValue(asInt));
305                 break;
306             }
307         }
308         node->setCanExit(true);
309         forNode(node).setType(SpecInt32);
310         break;
311     }
312             
313     case ValueToInt32: {
314         JSValue child = forNode(node->child1()).value();
315         if (child) {
316             if (child.isNumber()) {
317                 if (child.isInt32())
318                     setConstant(node, child);
319                 else
320                     setConstant(node, JSValue(JSC::toInt32(child.asDouble())));
321                 break;
322             }
323             if (child.isBoolean()) {
324                 setConstant(node, jsNumber(child.asBoolean()));
325                 break;
326             }
327             if (child.isUndefinedOrNull()) {
328                 setConstant(node, jsNumber(0));
329                 break;
330             }
331         }
332         
333         forNode(node).setType(SpecInt32);
334         break;
335     }
336         
337     case DoubleRep: {
338         JSValue child = forNode(node->child1()).value();
339         if (child && child.isNumber()) {
340             setConstant(node, jsDoubleNumber(child.asNumber()));
341             break;
342         }
343         forNode(node).setType(forNode(node->child1()).m_type);
344         forNode(node).fixTypeForRepresentation(node);
345         break;
346     }
347         
348     case Int52Rep: {
349         JSValue child = forNode(node->child1()).value();
350         if (child && child.isMachineInt()) {
351             setConstant(node, child);
352             break;
353         }
354         
355         forNode(node).setType(SpecInt32);
356         break;
357     }
358         
359     case ValueRep: {
360         JSValue value = forNode(node->child1()).value();
361         if (value) {
362             setConstant(node, value);
363             break;
364         }
365         
366         forNode(node).setType(forNode(node->child1()).m_type & ~SpecDoubleImpureNaN);
367         forNode(node).fixTypeForRepresentation(node);
368         break;
369     }
370         
371     case ValueAdd: {
372         ASSERT(node->binaryUseKind() == UntypedUse);
373         clobberWorld(node->origin.semantic, clobberLimit);
374         forNode(node).setType(SpecString | SpecBytecodeNumber);
375         break;
376     }
377         
378     case ArithAdd: {
379         JSValue left = forNode(node->child1()).value();
380         JSValue right = forNode(node->child2()).value();
381         switch (node->binaryUseKind()) {
382         case Int32Use:
383             if (left && right && left.isInt32() && right.isInt32()) {
384                 if (!shouldCheckOverflow(node->arithMode())) {
385                     setConstant(node, jsNumber(left.asInt32() + right.asInt32()));
386                     break;
387                 }
388                 JSValue result = jsNumber(left.asNumber() + right.asNumber());
389                 if (result.isInt32()) {
390                     setConstant(node, result);
391                     break;
392                 }
393             }
394             forNode(node).setType(SpecInt32);
395             if (shouldCheckOverflow(node->arithMode()))
396                 node->setCanExit(true);
397             break;
398         case Int52RepUse:
399             if (left && right && left.isMachineInt() && right.isMachineInt()) {
400                 JSValue result = jsNumber(left.asMachineInt() + right.asMachineInt());
401                 if (result.isMachineInt()) {
402                     setConstant(node, result);
403                     break;
404                 }
405             }
406             forNode(node).setType(SpecMachineInt);
407             if (!forNode(node->child1()).isType(SpecInt32)
408                 || !forNode(node->child2()).isType(SpecInt32))
409                 node->setCanExit(true);
410             break;
411         case DoubleRepUse:
412             if (left && right && left.isNumber() && right.isNumber()) {
413                 setConstant(node, jsDoubleNumber(left.asNumber() + right.asNumber()));
414                 break;
415             }
416             forNode(node).setType(
417                 typeOfDoubleSum(
418                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
419             break;
420         default:
421             RELEASE_ASSERT_NOT_REACHED();
422             break;
423         }
424         break;
425     }
426         
427     case MakeRope: {
428         node->setCanExit(true);
429         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
430         break;
431     }
432             
433     case ArithSub: {
434         JSValue left = forNode(node->child1()).value();
435         JSValue right = forNode(node->child2()).value();
436         switch (node->binaryUseKind()) {
437         case Int32Use:
438             if (left && right && left.isInt32() && right.isInt32()) {
439                 if (!shouldCheckOverflow(node->arithMode())) {
440                     setConstant(node, jsNumber(left.asInt32() - right.asInt32()));
441                     break;
442                 }
443                 JSValue result = jsNumber(left.asNumber() - right.asNumber());
444                 if (result.isInt32()) {
445                     setConstant(node, result);
446                     break;
447                 }
448             }
449             forNode(node).setType(SpecInt32);
450             if (shouldCheckOverflow(node->arithMode()))
451                 node->setCanExit(true);
452             break;
453         case Int52RepUse:
454             if (left && right && left.isMachineInt() && right.isMachineInt()) {
455                 JSValue result = jsNumber(left.asMachineInt() - right.asMachineInt());
456                 if (result.isMachineInt() || !shouldCheckOverflow(node->arithMode())) {
457                     setConstant(node, result);
458                     break;
459                 }
460             }
461             forNode(node).setType(SpecMachineInt);
462             if (!forNode(node->child1()).isType(SpecInt32)
463                 || !forNode(node->child2()).isType(SpecInt32))
464                 node->setCanExit(true);
465             break;
466         case DoubleRepUse:
467             if (left && right && left.isNumber() && right.isNumber()) {
468                 setConstant(node, jsDoubleNumber(left.asNumber() - right.asNumber()));
469                 break;
470             }
471             forNode(node).setType(
472                 typeOfDoubleDifference(
473                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
474             break;
475         default:
476             RELEASE_ASSERT_NOT_REACHED();
477             break;
478         }
479         break;
480     }
481         
482     case ArithNegate: {
483         JSValue child = forNode(node->child1()).value();
484         switch (node->child1().useKind()) {
485         case Int32Use:
486             if (child && child.isInt32()) {
487                 if (!shouldCheckOverflow(node->arithMode())) {
488                     setConstant(node, jsNumber(-child.asInt32()));
489                     break;
490                 }
491                 double doubleResult;
492                 if (shouldCheckNegativeZero(node->arithMode()))
493                     doubleResult = -child.asNumber();
494                 else
495                     doubleResult = 0 - child.asNumber();
496                 JSValue valueResult = jsNumber(doubleResult);
497                 if (valueResult.isInt32()) {
498                     setConstant(node, valueResult);
499                     break;
500                 }
501             }
502             forNode(node).setType(SpecInt32);
503             if (shouldCheckOverflow(node->arithMode()))
504                 node->setCanExit(true);
505             break;
506         case Int52RepUse:
507             if (child && child.isMachineInt()) {
508                 double doubleResult;
509                 if (shouldCheckNegativeZero(node->arithMode()))
510                     doubleResult = -child.asNumber();
511                 else
512                     doubleResult = 0 - child.asNumber();
513                 JSValue valueResult = jsNumber(doubleResult);
514                 if (valueResult.isMachineInt()) {
515                     setConstant(node, valueResult);
516                     break;
517                 }
518             }
519             forNode(node).setType(SpecMachineInt);
520             if (m_state.forNode(node->child1()).couldBeType(SpecInt52))
521                 node->setCanExit(true);
522             if (shouldCheckNegativeZero(node->arithMode()))
523                 node->setCanExit(true);
524             break;
525         case DoubleRepUse:
526             if (child && child.isNumber()) {
527                 setConstant(node, jsDoubleNumber(-child.asNumber()));
528                 break;
529             }
530             forNode(node).setType(
531                 typeOfDoubleNegation(
532                     forNode(node->child1()).m_type));
533             break;
534         default:
535             RELEASE_ASSERT_NOT_REACHED();
536             break;
537         }
538         break;
539     }
540         
541     case ArithMul: {
542         JSValue left = forNode(node->child1()).value();
543         JSValue right = forNode(node->child2()).value();
544         switch (node->binaryUseKind()) {
545         case Int32Use:
546             if (left && right && left.isInt32() && right.isInt32()) {
547                 if (!shouldCheckOverflow(node->arithMode())) {
548                     setConstant(node, jsNumber(left.asInt32() * right.asInt32()));
549                     break;
550                 }
551                 double doubleResult = left.asNumber() * right.asNumber();
552                 if (!shouldCheckNegativeZero(node->arithMode()))
553                     doubleResult += 0; // Sanitizes zero.
554                 JSValue valueResult = jsNumber(doubleResult);
555                 if (valueResult.isInt32()) {
556                     setConstant(node, valueResult);
557                     break;
558                 }
559             }
560             forNode(node).setType(SpecInt32);
561             if (shouldCheckOverflow(node->arithMode()))
562                 node->setCanExit(true);
563             break;
564         case Int52RepUse:
565             if (left && right && left.isMachineInt() && right.isMachineInt()) {
566                 double doubleResult = left.asNumber() * right.asNumber();
567                 if (!shouldCheckNegativeZero(node->arithMode()))
568                     doubleResult += 0;
569                 JSValue valueResult = jsNumber(doubleResult);
570                 if (valueResult.isMachineInt()) {
571                     setConstant(node, valueResult);
572                     break;
573                 }
574             }
575             forNode(node).setType(SpecMachineInt);
576             node->setCanExit(true);
577             break;
578         case DoubleRepUse:
579             if (left && right && left.isNumber() && right.isNumber()) {
580                 setConstant(node, jsDoubleNumber(left.asNumber() * right.asNumber()));
581                 break;
582             }
583             forNode(node).setType(
584                 typeOfDoubleProduct(
585                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
586             break;
587         default:
588             RELEASE_ASSERT_NOT_REACHED();
589             break;
590         }
591         break;
592     }
593         
594     case ArithDiv: {
595         JSValue left = forNode(node->child1()).value();
596         JSValue right = forNode(node->child2()).value();
597         switch (node->binaryUseKind()) {
598         case Int32Use:
599             if (left && right && left.isInt32() && right.isInt32()) {
600                 double doubleResult = left.asNumber() / right.asNumber();
601                 if (!shouldCheckOverflow(node->arithMode()))
602                     doubleResult = toInt32(doubleResult);
603                 else if (!shouldCheckNegativeZero(node->arithMode()))
604                     doubleResult += 0; // Sanitizes zero.
605                 JSValue valueResult = jsNumber(doubleResult);
606                 if (valueResult.isInt32()) {
607                     setConstant(node, valueResult);
608                     break;
609                 }
610             }
611             forNode(node).setType(SpecInt32);
612             node->setCanExit(true);
613             break;
614         case DoubleRepUse:
615             if (left && right && left.isNumber() && right.isNumber()) {
616                 setConstant(node, jsDoubleNumber(left.asNumber() / right.asNumber()));
617                 break;
618             }
619             forNode(node).setType(
620                 typeOfDoubleQuotient(
621                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
622             break;
623         default:
624             RELEASE_ASSERT_NOT_REACHED();
625             break;
626         }
627         break;
628     }
629
630     case ArithMod: {
631         JSValue left = forNode(node->child1()).value();
632         JSValue right = forNode(node->child2()).value();
633         switch (node->binaryUseKind()) {
634         case Int32Use:
635             if (left && right && left.isInt32() && right.isInt32()) {
636                 double doubleResult = fmod(left.asNumber(), right.asNumber());
637                 if (!shouldCheckOverflow(node->arithMode()))
638                     doubleResult = toInt32(doubleResult);
639                 else if (!shouldCheckNegativeZero(node->arithMode()))
640                     doubleResult += 0; // Sanitizes zero.
641                 JSValue valueResult = jsNumber(doubleResult);
642                 if (valueResult.isInt32()) {
643                     setConstant(node, valueResult);
644                     break;
645                 }
646             }
647             forNode(node).setType(SpecInt32);
648             node->setCanExit(true);
649             break;
650         case DoubleRepUse:
651             if (left && right && left.isNumber() && right.isNumber()) {
652                 setConstant(node, jsDoubleNumber(fmod(left.asNumber(), right.asNumber())));
653                 break;
654             }
655             forNode(node).setType(
656                 typeOfDoubleBinaryOp(
657                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
658             break;
659         default:
660             RELEASE_ASSERT_NOT_REACHED();
661             break;
662         }
663         break;
664     }
665
666     case ArithMin: {
667         JSValue left = forNode(node->child1()).value();
668         JSValue right = forNode(node->child2()).value();
669         switch (node->binaryUseKind()) {
670         case Int32Use:
671             if (left && right && left.isInt32() && right.isInt32()) {
672                 setConstant(node, jsNumber(std::min(left.asInt32(), right.asInt32())));
673                 break;
674             }
675             forNode(node).setType(SpecInt32);
676             node->setCanExit(true);
677             break;
678         case DoubleRepUse:
679             if (left && right && left.isNumber() && right.isNumber()) {
680                 double a = left.asNumber();
681                 double b = right.asNumber();
682                 setConstant(node, jsDoubleNumber(a < b ? a : (b <= a ? b : a + b)));
683                 break;
684             }
685             forNode(node).setType(
686                 typeOfDoubleMinMax(
687                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
688             break;
689         default:
690             RELEASE_ASSERT_NOT_REACHED();
691             break;
692         }
693         break;
694     }
695             
696     case ArithMax: {
697         JSValue left = forNode(node->child1()).value();
698         JSValue right = forNode(node->child2()).value();
699         switch (node->binaryUseKind()) {
700         case Int32Use:
701             if (left && right && left.isInt32() && right.isInt32()) {
702                 setConstant(node, jsNumber(std::max(left.asInt32(), right.asInt32())));
703                 break;
704             }
705             forNode(node).setType(SpecInt32);
706             node->setCanExit(true);
707             break;
708         case DoubleRepUse:
709             if (left && right && left.isNumber() && right.isNumber()) {
710                 double a = left.asNumber();
711                 double b = right.asNumber();
712                 setConstant(node, jsDoubleNumber(a > b ? a : (b >= a ? b : a + b)));
713                 break;
714             }
715             forNode(node).setType(
716                 typeOfDoubleMinMax(
717                     forNode(node->child1()).m_type, forNode(node->child2()).m_type));
718             break;
719         default:
720             RELEASE_ASSERT_NOT_REACHED();
721             break;
722         }
723         break;
724     }
725             
726     case ArithAbs: {
727         JSValue child = forNode(node->child1()).value();
728         switch (node->child1().useKind()) {
729         case Int32Use:
730             if (child && child.isInt32()) {
731                 JSValue result = jsNumber(fabs(child.asNumber()));
732                 if (result.isInt32()) {
733                     setConstant(node, result);
734                     break;
735                 }
736             }
737             forNode(node).setType(SpecInt32);
738             node->setCanExit(true);
739             break;
740         case DoubleRepUse:
741             if (child && child.isNumber()) {
742                 setConstant(node, jsDoubleNumber(child.asNumber()));
743                 break;
744             }
745             forNode(node).setType(typeOfDoubleAbs(forNode(node->child1()).m_type));
746             break;
747         default:
748             RELEASE_ASSERT_NOT_REACHED();
749             break;
750         }
751         break;
752     }
753             
754     case ArithSqrt: {
755         JSValue child = forNode(node->child1()).value();
756         if (child && child.isNumber()) {
757             setConstant(node, jsDoubleNumber(sqrt(child.asNumber())));
758             break;
759         }
760         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
761         break;
762     }
763         
764     case ArithFRound: {
765         JSValue child = forNode(node->child1()).value();
766         if (child && child.isNumber()) {
767             setConstant(node, jsDoubleNumber(static_cast<float>(child.asNumber())));
768             break;
769         }
770         forNode(node).setType(typeOfDoubleFRound(forNode(node->child1()).m_type));
771         break;
772     }
773         
774     case ArithSin: {
775         JSValue child = forNode(node->child1()).value();
776         if (child && child.isNumber()) {
777             setConstant(node, jsDoubleNumber(sin(child.asNumber())));
778             break;
779         }
780         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
781         break;
782     }
783     
784     case ArithCos: {
785         JSValue child = forNode(node->child1()).value();
786         if (child && child.isNumber()) {
787             setConstant(node, jsDoubleNumber(cos(child.asNumber())));
788             break;
789         }
790         forNode(node).setType(typeOfDoubleUnaryOp(forNode(node->child1()).m_type));
791         break;
792     }
793             
794     case LogicalNot: {
795         switch (booleanResult(node, forNode(node->child1()))) {
796         case DefinitelyTrue:
797             setConstant(node, jsBoolean(false));
798             break;
799         case DefinitelyFalse:
800             setConstant(node, jsBoolean(true));
801             break;
802         default:
803             switch (node->child1().useKind()) {
804             case BooleanUse:
805             case Int32Use:
806             case DoubleRepUse:
807             case UntypedUse:
808             case StringUse:
809                 break;
810             case ObjectOrOtherUse:
811                 node->setCanExit(true);
812                 break;
813             default:
814                 RELEASE_ASSERT_NOT_REACHED();
815                 break;
816             }
817             forNode(node).setType(SpecBoolean);
818             break;
819         }
820         break;
821     }
822         
823     case IsUndefined:
824     case IsBoolean:
825     case IsNumber:
826     case IsString:
827     case IsObject:
828     case IsFunction: {
829         node->setCanExit(
830             node->op() == IsUndefined
831             && m_graph.masqueradesAsUndefinedWatchpointIsStillValid(node->origin.semantic));
832         JSValue child = forNode(node->child1()).value();
833         if (child) {
834             bool constantWasSet = true;
835             switch (node->op()) {
836             case IsUndefined:
837                 setConstant(node, jsBoolean(
838                     child.isCell()
839                     ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node->origin.semantic))
840                     : child.isUndefined()));
841                 break;
842             case IsBoolean:
843                 setConstant(node, jsBoolean(child.isBoolean()));
844                 break;
845             case IsNumber:
846                 setConstant(node, jsBoolean(child.isNumber()));
847                 break;
848             case IsString:
849                 setConstant(node, jsBoolean(isJSString(child)));
850                 break;
851             case IsObject:
852                 if (child.isNull() || !child.isObject()) {
853                     setConstant(node, jsBoolean(child.isNull()));
854                     break;
855                 }
856                 constantWasSet = false;
857                 break;
858             default:
859                 constantWasSet = false;
860                 break;
861             }
862             if (constantWasSet)
863                 break;
864         }
865
866         forNode(node).setType(SpecBoolean);
867         break;
868     }
869
870     case TypeOf: {
871         VM* vm = m_codeBlock->vm();
872         JSValue child = forNode(node->child1()).value();
873         AbstractValue& abstractChild = forNode(node->child1());
874         if (child) {
875             JSValue typeString = jsTypeStringForValue(*vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
876             setConstant(node, typeString);
877             break;
878         }
879         
880         if (isFullNumberSpeculation(abstractChild.m_type)) {
881             setConstant(node, vm->smallStrings.numberString());
882             break;
883         }
884         
885         if (isStringSpeculation(abstractChild.m_type)) {
886             setConstant(node, vm->smallStrings.stringString());
887             break;
888         }
889         
890         if (isFinalObjectSpeculation(abstractChild.m_type) || isArraySpeculation(abstractChild.m_type) || isArgumentsSpeculation(abstractChild.m_type)) {
891             setConstant(node, vm->smallStrings.objectString());
892             break;
893         }
894         
895         if (isFunctionSpeculation(abstractChild.m_type)) {
896             setConstant(node, vm->smallStrings.functionString());
897             break;
898         }
899         
900         if (isBooleanSpeculation(abstractChild.m_type)) {
901             setConstant(node, vm->smallStrings.booleanString());
902             break;
903         }
904
905         switch (node->child1().useKind()) {
906         case StringUse:
907         case CellUse:
908             node->setCanExit(true);
909             break;
910         case UntypedUse:
911             break;
912         default:
913             RELEASE_ASSERT_NOT_REACHED();
914             break;
915         }
916         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
917         break;
918     }
919             
920     case CompareLess:
921     case CompareLessEq:
922     case CompareGreater:
923     case CompareGreaterEq:
924     case CompareEq:
925     case CompareEqConstant: {
926         JSValue leftConst = forNode(node->child1()).value();
927         JSValue rightConst = forNode(node->child2()).value();
928         if (leftConst && rightConst) {
929             if (leftConst.isNumber() && rightConst.isNumber()) {
930                 double a = leftConst.asNumber();
931                 double b = rightConst.asNumber();
932                 switch (node->op()) {
933                 case CompareLess:
934                     setConstant(node, jsBoolean(a < b));
935                     break;
936                 case CompareLessEq:
937                     setConstant(node, jsBoolean(a <= b));
938                     break;
939                 case CompareGreater:
940                     setConstant(node, jsBoolean(a > b));
941                     break;
942                 case CompareGreaterEq:
943                     setConstant(node, jsBoolean(a >= b));
944                     break;
945                 case CompareEq:
946                     setConstant(node, jsBoolean(a == b));
947                     break;
948                 default:
949                     RELEASE_ASSERT_NOT_REACHED();
950                     break;
951                 }
952                 break;
953             }
954             
955             if (node->op() == CompareEq && leftConst.isString() && rightConst.isString()) {
956                 const StringImpl* a = asString(leftConst)->tryGetValueImpl();
957                 const StringImpl* b = asString(rightConst)->tryGetValueImpl();
958                 if (a && b) {
959                     setConstant(node, jsBoolean(WTF::equal(a, b)));
960                     break;
961                 }
962             }
963         }
964         
965         if (node->op() == CompareEqConstant || node->op() == CompareEq) {
966             SpeculatedType leftType = forNode(node->child1()).m_type;
967             SpeculatedType rightType = forNode(node->child2()).m_type;
968             if (!valuesCouldBeEqual(leftType, rightType)) {
969                 setConstant(node, jsBoolean(false));
970                 break;
971             }
972         }
973         
974         forNode(node).setType(SpecBoolean);
975         
976         // This is overly conservative. But the only thing this prevents is store elimination,
977         // and how likely is it, really, that you'll have redundant stores across a comparison
978         // operation? Comparison operations are typically at the end of basic blocks, so
979         // unless we have global store elimination (super unlikely given how unprofitable that
980         // optimization is to begin with), you aren't going to be wanting to store eliminate
981         // across an equality op.
982         node->setCanExit(true);
983         break;
984     }
985             
986     case CompareStrictEq: {
987         Node* leftNode = node->child1().node();
988         Node* rightNode = node->child2().node();
989         JSValue left = forNode(leftNode).value();
990         JSValue right = forNode(rightNode).value();
991         if (left && right) {
992             if (left.isString() && right.isString()) {
993                 // We need this case because JSValue::strictEqual is otherwise too racy for
994                 // string comparisons.
995                 const StringImpl* a = asString(left)->tryGetValueImpl();
996                 const StringImpl* b = asString(right)->tryGetValueImpl();
997                 if (a && b) {
998                     setConstant(node, jsBoolean(WTF::equal(a, b)));
999                     break;
1000                 }
1001             } else {
1002                 setConstant(node, jsBoolean(JSValue::strictEqual(0, left, right)));
1003                 break;
1004             }
1005         }
1006         
1007         SpeculatedType leftLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(leftNode).m_type);
1008         SpeculatedType rightLUB = leastUpperBoundOfStrictlyEquivalentSpeculations(forNode(rightNode).m_type);
1009         if (!(leftLUB & rightLUB)) {
1010             setConstant(node, jsBoolean(false));
1011             break;
1012         }
1013         
1014         forNode(node).setType(SpecBoolean);
1015         node->setCanExit(true); // This is overly conservative.
1016         break;
1017     }
1018         
1019     case StringCharCodeAt:
1020         node->setCanExit(true);
1021         forNode(node).setType(SpecInt32);
1022         break;
1023         
1024     case StringFromCharCode:
1025         forNode(node).setType(SpecString);
1026         break;
1027
1028     case StringCharAt:
1029         node->setCanExit(true);
1030         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1031         break;
1032             
1033     case GetByVal: {
1034         node->setCanExit(true);
1035         switch (node->arrayMode().type()) {
1036         case Array::SelectUsingPredictions:
1037         case Array::Unprofiled:
1038         case Array::Undecided:
1039             RELEASE_ASSERT_NOT_REACHED();
1040             break;
1041         case Array::ForceExit:
1042             m_state.setIsValid(false);
1043             break;
1044         case Array::Generic:
1045             clobberWorld(node->origin.semantic, clobberLimit);
1046             forNode(node).makeHeapTop();
1047             break;
1048         case Array::String:
1049             if (node->arrayMode().isOutOfBounds()) {
1050                 // If the watchpoint was still valid we could totally set this to be
1051                 // SpecString | SpecOther. Except that we'd have to be careful. If we
1052                 // tested the watchpoint state here then it could change by the time
1053                 // we got to the backend. So to do this right, we'd have to get the
1054                 // fixup phase to check the watchpoint state and then bake into the
1055                 // GetByVal operation the fact that we're using a watchpoint, using
1056                 // something like Array::SaneChain (except not quite, because that
1057                 // implies an in-bounds access). None of this feels like it's worth it,
1058                 // so we're going with TOP for now. The same thing applies to
1059                 // clobbering the world.
1060                 clobberWorld(node->origin.semantic, clobberLimit);
1061                 forNode(node).makeHeapTop();
1062             } else
1063                 forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1064             break;
1065         case Array::Arguments:
1066             forNode(node).makeHeapTop();
1067             break;
1068         case Array::Int32:
1069             if (node->arrayMode().isOutOfBounds()) {
1070                 clobberWorld(node->origin.semantic, clobberLimit);
1071                 forNode(node).makeHeapTop();
1072             } else
1073                 forNode(node).setType(SpecInt32);
1074             break;
1075         case Array::Double:
1076             if (node->arrayMode().isOutOfBounds()) {
1077                 clobberWorld(node->origin.semantic, clobberLimit);
1078                 forNode(node).makeHeapTop();
1079             } else if (node->arrayMode().isSaneChain())
1080                 forNode(node).setType(SpecBytecodeDouble);
1081             else
1082                 forNode(node).setType(SpecDoubleReal);
1083             break;
1084         case Array::Contiguous:
1085         case Array::ArrayStorage:
1086         case Array::SlowPutArrayStorage:
1087             if (node->arrayMode().isOutOfBounds())
1088                 clobberWorld(node->origin.semantic, clobberLimit);
1089             forNode(node).makeHeapTop();
1090             break;
1091         case Array::Int8Array:
1092             forNode(node).setType(SpecInt32);
1093             break;
1094         case Array::Int16Array:
1095             forNode(node).setType(SpecInt32);
1096             break;
1097         case Array::Int32Array:
1098             forNode(node).setType(SpecInt32);
1099             break;
1100         case Array::Uint8Array:
1101             forNode(node).setType(SpecInt32);
1102             break;
1103         case Array::Uint8ClampedArray:
1104             forNode(node).setType(SpecInt32);
1105             break;
1106         case Array::Uint16Array:
1107             forNode(node).setType(SpecInt32);
1108             break;
1109         case Array::Uint32Array:
1110             if (node->shouldSpeculateInt32())
1111                 forNode(node).setType(SpecInt32);
1112             else if (enableInt52() && node->shouldSpeculateMachineInt())
1113                 forNode(node).setType(SpecInt52);
1114             else
1115                 forNode(node).setType(SpecInt52AsDouble);
1116             break;
1117         case Array::Float32Array:
1118             forNode(node).setType(SpecFullDouble);
1119             break;
1120         case Array::Float64Array:
1121             forNode(node).setType(SpecFullDouble);
1122             break;
1123         default:
1124             RELEASE_ASSERT_NOT_REACHED();
1125             break;
1126         }
1127         break;
1128     }
1129             
1130     case PutByValDirect:
1131     case PutByVal:
1132     case PutByValAlias: {
1133         node->setCanExit(true);
1134         switch (node->arrayMode().modeForPut().type()) {
1135         case Array::ForceExit:
1136             m_state.setIsValid(false);
1137             break;
1138         case Array::Generic:
1139             clobberWorld(node->origin.semantic, clobberLimit);
1140             break;
1141         case Array::Int32:
1142             if (node->arrayMode().isOutOfBounds())
1143                 clobberWorld(node->origin.semantic, clobberLimit);
1144             break;
1145         case Array::Double:
1146             if (node->arrayMode().isOutOfBounds())
1147                 clobberWorld(node->origin.semantic, clobberLimit);
1148             break;
1149         case Array::Contiguous:
1150         case Array::ArrayStorage:
1151             if (node->arrayMode().isOutOfBounds())
1152                 clobberWorld(node->origin.semantic, clobberLimit);
1153             break;
1154         case Array::SlowPutArrayStorage:
1155             if (node->arrayMode().mayStoreToHole())
1156                 clobberWorld(node->origin.semantic, clobberLimit);
1157             break;
1158         default:
1159             break;
1160         }
1161         break;
1162     }
1163             
1164     case ArrayPush:
1165         node->setCanExit(true);
1166         clobberWorld(node->origin.semantic, clobberLimit);
1167         forNode(node).setType(SpecBytecodeNumber);
1168         break;
1169             
1170     case ArrayPop:
1171         node->setCanExit(true);
1172         clobberWorld(node->origin.semantic, clobberLimit);
1173         forNode(node).makeHeapTop();
1174         break;
1175             
1176     case RegExpExec:
1177         forNode(node).makeHeapTop();
1178         break;
1179
1180     case RegExpTest:
1181         forNode(node).setType(SpecBoolean);
1182         break;
1183             
1184     case Jump:
1185         break;
1186             
1187     case Branch: {
1188         Node* child = node->child1().node();
1189         BooleanResult result = booleanResult(node, forNode(child));
1190         if (result == DefinitelyTrue) {
1191             m_state.setBranchDirection(TakeTrue);
1192             break;
1193         }
1194         if (result == DefinitelyFalse) {
1195             m_state.setBranchDirection(TakeFalse);
1196             break;
1197         }
1198         // FIXME: The above handles the trivial cases of sparse conditional
1199         // constant propagation, but we can do better:
1200         // We can specialize the source variable's value on each direction of
1201         // the branch.
1202         node->setCanExit(true); // This is overly conservative.
1203         m_state.setBranchDirection(TakeBoth);
1204         break;
1205     }
1206         
1207     case Switch: {
1208         // Nothing to do for now.
1209         // FIXME: Do sparse conditional things.
1210         break;
1211     }
1212             
1213     case Return:
1214         m_state.setIsValid(false);
1215         break;
1216         
1217     case Throw:
1218     case ThrowReferenceError:
1219         m_state.setIsValid(false);
1220         node->setCanExit(true);
1221         break;
1222             
1223     case ToPrimitive: {
1224         JSValue childConst = forNode(node->child1()).value();
1225         if (childConst && childConst.isNumber()) {
1226             setConstant(node, childConst);
1227             break;
1228         }
1229         
1230         ASSERT(node->child1().useKind() == UntypedUse);
1231         
1232         if (!forNode(node->child1()).m_type) {
1233             m_state.setIsValid(false);
1234             break;
1235         }
1236         
1237         if (!(forNode(node->child1()).m_type & ~(SpecFullNumber | SpecBoolean | SpecString))) {
1238             m_state.setFoundConstants(true);
1239             forNode(node) = forNode(node->child1());
1240             break;
1241         }
1242         
1243         clobberWorld(node->origin.semantic, clobberLimit);
1244         
1245         forNode(node).setType((SpecHeapTop & ~SpecCell) | SpecString);
1246         break;
1247     }
1248         
1249     case ToString: {
1250         switch (node->child1().useKind()) {
1251         case StringObjectUse:
1252             // This also filters that the StringObject has the primordial StringObject
1253             // structure.
1254             filter(
1255                 node->child1(),
1256                 m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
1257             node->setCanExit(true); // We could be more precise but it's likely not worth it.
1258             break;
1259         case StringOrStringObjectUse:
1260             node->setCanExit(true); // We could be more precise but it's likely not worth it.
1261             break;
1262         case CellUse:
1263         case UntypedUse:
1264             clobberWorld(node->origin.semantic, clobberLimit);
1265             break;
1266         default:
1267             RELEASE_ASSERT_NOT_REACHED();
1268             break;
1269         }
1270         forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
1271         break;
1272     }
1273         
1274     case NewStringObject: {
1275         ASSERT(node->structure()->classInfo() == StringObject::info());
1276         forNode(node).set(m_graph, node->structure());
1277         break;
1278     }
1279             
1280     case NewArray:
1281         node->setCanExit(true);
1282         forNode(node).set(
1283             m_graph,
1284             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1285         break;
1286         
1287     case NewArrayBuffer:
1288         node->setCanExit(true);
1289         forNode(node).set(
1290             m_graph,
1291             m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
1292         break;
1293
1294     case NewArrayWithSize:
1295         node->setCanExit(true);
1296         forNode(node).setType(SpecArray);
1297         break;
1298         
1299     case NewTypedArray:
1300         switch (node->child1().useKind()) {
1301         case Int32Use:
1302             break;
1303         case UntypedUse:
1304             clobberWorld(node->origin.semantic, clobberLimit);
1305             break;
1306         default:
1307             RELEASE_ASSERT_NOT_REACHED();
1308             break;
1309         }
1310         forNode(node).set(
1311             m_graph,
1312             m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(
1313                 node->typedArrayType()));
1314         break;
1315             
1316     case NewRegexp:
1317         forNode(node).set(m_graph, m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
1318         break;
1319             
1320     case ToThis: {
1321         AbstractValue& source = forNode(node->child1());
1322         AbstractValue& destination = forNode(node);
1323             
1324         if (m_graph.executableFor(node->origin.semantic)->isStrictMode())
1325             destination.makeHeapTop();
1326         else {
1327             destination = source;
1328             destination.merge(SpecObject);
1329         }
1330         break;
1331     }
1332
1333     case CreateThis: {
1334         forNode(node).setType(SpecFinalObject);
1335         break;
1336     }
1337         
1338     case AllocationProfileWatchpoint:
1339         node->setCanExit(true);
1340         break;
1341
1342     case NewObject:
1343         ASSERT(node->structure());
1344         forNode(node).set(m_graph, node->structure());
1345         break;
1346         
1347     case CreateActivation:
1348         forNode(node).set(
1349             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->activationStructure());
1350         break;
1351         
1352     case FunctionReentryWatchpoint:
1353     case TypedArrayWatchpoint:
1354         break;
1355     
1356     case CreateArguments:
1357         forNode(node) = forNode(node->child1());
1358         forNode(node).filter(~SpecEmpty);
1359         forNode(node).merge(SpecArguments);
1360         break;
1361         
1362     case TearOffActivation:
1363     case TearOffArguments:
1364         // Does nothing that is user-visible.
1365         break;
1366
1367     case CheckArgumentsNotCreated:
1368         if (isEmptySpeculation(
1369                 m_state.variables().operand(
1370                     m_graph.argumentsRegisterFor(node->origin.semantic).offset()).m_type))
1371             m_state.setFoundConstants(true);
1372         else
1373             node->setCanExit(true);
1374         break;
1375         
1376     case GetMyArgumentsLength:
1377         // We know that this executable does not escape its arguments, so we can optimize
1378         // the arguments a bit. Note that this is not sufficient to force constant folding
1379         // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
1380         // We perform further optimizations on this later on.
1381         if (node->origin.semantic.inlineCallFrame) {
1382             setConstant(
1383                 node, jsNumber(node->origin.semantic.inlineCallFrame->arguments.size() - 1));
1384             m_state.setDidClobber(true); // Pretend that we clobbered to prevent constant folding.
1385         } else
1386             forNode(node).setType(SpecInt32);
1387         node->setCanExit(
1388             !isEmptySpeculation(
1389                 m_state.variables().operand(
1390                     m_graph.argumentsRegisterFor(node->origin.semantic)).m_type));
1391         break;
1392         
1393     case GetMyArgumentsLengthSafe:
1394         // This potentially clobbers all structures if the arguments object had a getter
1395         // installed on the length property.
1396         clobberWorld(node->origin.semantic, clobberLimit);
1397         // We currently make no guarantee about what this returns because it does not
1398         // speculate that the length property is actually a length.
1399         forNode(node).makeHeapTop();
1400         break;
1401         
1402     case GetMyArgumentByVal:
1403         node->setCanExit(true);
1404         // We know that this executable does not escape its arguments, so we can optimize
1405         // the arguments a bit. Note that this ends up being further optimized by the
1406         // ArgumentsSimplificationPhase.
1407         forNode(node).makeHeapTop();
1408         break;
1409         
1410     case GetMyArgumentByValSafe:
1411         node->setCanExit(true);
1412         // This potentially clobbers all structures if the property we're accessing has
1413         // a getter. We don't speculate against this.
1414         clobberWorld(node->origin.semantic, clobberLimit);
1415         // And the result is unknown.
1416         forNode(node).makeHeapTop();
1417         break;
1418         
1419     case NewFunction: {
1420         AbstractValue& value = forNode(node);
1421         value = forNode(node->child1());
1422         
1423         if (!(value.m_type & SpecEmpty)) {
1424             m_state.setFoundConstants(true);
1425             break;
1426         }
1427
1428         value.setType((value.m_type & ~SpecEmpty) | SpecFunction);
1429         break;
1430     }
1431
1432     case NewFunctionExpression:
1433     case NewFunctionNoCheck:
1434         forNode(node).set(
1435             m_graph, m_codeBlock->globalObjectFor(node->origin.semantic)->functionStructure());
1436         break;
1437         
1438     case GetCallee:
1439     case GetGetter:
1440     case GetSetter:
1441         forNode(node).setType(SpecFunction);
1442         break;
1443         
1444     case GetScope: // FIXME: We could get rid of these if we know that the JSFunction is a constant. https://bugs.webkit.org/show_bug.cgi?id=106202
1445     case GetMyScope:
1446     case SkipTopScope:
1447         forNode(node).setType(SpecObjectOther);
1448         break;
1449
1450     case SkipScope: {
1451         JSValue child = forNode(node->child1()).value();
1452         if (child) {
1453             setConstant(node, JSValue(jsCast<JSScope*>(child.asCell())->next()));
1454             break;
1455         }
1456         forNode(node).setType(SpecObjectOther);
1457         break;
1458     }
1459
1460     case GetClosureRegisters:
1461         forNode(node).clear(); // The result is not a JS value.
1462         break;
1463
1464     case GetClosureVar:
1465         forNode(node).makeHeapTop();
1466         break;
1467             
1468     case PutClosureVar:
1469         clobberCapturedVars(node->origin.semantic);
1470         break;
1471             
1472     case GetById:
1473     case GetByIdFlush:
1474         node->setCanExit(true);
1475         if (!node->prediction()) {
1476             m_state.setIsValid(false);
1477             break;
1478         }
1479         if (isCellSpeculation(node->child1()->prediction())) {
1480             // This use of onlyStructure() should be replaced by giving GetByIdStatus the ability
1481             // to compute things based on a StructureSet, and then to factor ByteCodeParser's
1482             // ability to generate code based on a GetByIdStatus out of ByteCodeParser so that
1483             // ConstantFoldingPhase can use it.
1484             // https://bugs.webkit.org/show_bug.cgi?id=133229
1485             if (Structure* structure = forNode(node->child1()).m_structure.onlyStructure()) {
1486                 GetByIdStatus status = GetByIdStatus::computeFor(
1487                     m_graph.m_vm, structure,
1488                     m_graph.identifiers()[node->identifierNumber()]);
1489                 if (status.isSimple() && status.numVariants() == 1) {
1490                     // Assert things that we can't handle and that the computeFor() method
1491                     // above won't be able to return.
1492                     ASSERT(status[0].structureSet().size() == 1);
1493                     ASSERT(!status[0].chain());
1494                     
1495                     if (status[0].specificValue()) {
1496                         if (status[0].specificValue().isCell()) {
1497                             Structure* structure = status[0].specificValue().asCell()->structure();
1498                             m_graph.watchpoints().consider(structure);
1499                         }
1500                         setConstant(node, status[0].specificValue());
1501                     } else
1502                         forNode(node).makeHeapTop();
1503                     filter(node->child1(), status[0].structureSet());
1504                     
1505                     m_state.setFoundConstants(true);
1506                     break;
1507                 }
1508             }
1509         }
1510         clobberWorld(node->origin.semantic, clobberLimit);
1511         forNode(node).makeHeapTop();
1512         break;
1513             
1514     case GetArrayLength:
1515         node->setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
1516         forNode(node).setType(SpecInt32);
1517         break;
1518         
1519     case CheckExecutable: {
1520         // FIXME: We could track executables in AbstractValue, which would allow us to get rid of these checks
1521         // more thoroughly. https://bugs.webkit.org/show_bug.cgi?id=106200
1522         // FIXME: We could eliminate these entirely if we know the exact value that flows into this.
1523         // https://bugs.webkit.org/show_bug.cgi?id=106201
1524         node->setCanExit(true);
1525         break;
1526     }
1527
1528     case CheckStructure: {
1529         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1530         AbstractValue& value = forNode(node->child1());
1531         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1532
1533         StructureSet& set = node->structureSet();
1534         
1535         // It's interesting that we could have proven that the object has a larger structure set
1536         // that includes the set we're testing. In that case we could make the structure check
1537         // more efficient. We currently don't.
1538         
1539         if (value.m_structure.isSubsetOf(set)) {
1540             m_state.setFoundConstants(true);
1541             break;
1542         }
1543
1544         node->setCanExit(true);
1545
1546         filter(value, set);
1547         break;
1548     }
1549         
1550     case PutStructure:
1551     case PhantomPutStructure:
1552         if (!forNode(node->child1()).m_structure.isClear()) {
1553             observeTransition(
1554                 clobberLimit, node->transition()->previous, node->transition()->next);
1555             forNode(node->child1()).set(m_graph, node->transition()->next);
1556         }
1557         break;
1558     case GetButterfly:
1559     case AllocatePropertyStorage:
1560     case ReallocatePropertyStorage:
1561         forNode(node).clear(); // The result is not a JS value.
1562         break;
1563     case CheckArray: {
1564         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1565             m_state.setFoundConstants(true);
1566             break;
1567         }
1568         node->setCanExit(true); // Lies, but this is followed by operations (like GetByVal) that always exit, so there is no point in us trying to be clever here.
1569         switch (node->arrayMode().type()) {
1570         case Array::String:
1571             filter(node->child1(), SpecString);
1572             break;
1573         case Array::Int32:
1574         case Array::Double:
1575         case Array::Contiguous:
1576         case Array::ArrayStorage:
1577         case Array::SlowPutArrayStorage:
1578             break;
1579         case Array::Arguments:
1580             filter(node->child1(), SpecArguments);
1581             break;
1582         case Array::Int8Array:
1583             filter(node->child1(), SpecInt8Array);
1584             break;
1585         case Array::Int16Array:
1586             filter(node->child1(), SpecInt16Array);
1587             break;
1588         case Array::Int32Array:
1589             filter(node->child1(), SpecInt32Array);
1590             break;
1591         case Array::Uint8Array:
1592             filter(node->child1(), SpecUint8Array);
1593             break;
1594         case Array::Uint8ClampedArray:
1595             filter(node->child1(), SpecUint8ClampedArray);
1596             break;
1597         case Array::Uint16Array:
1598             filter(node->child1(), SpecUint16Array);
1599             break;
1600         case Array::Uint32Array:
1601             filter(node->child1(), SpecUint32Array);
1602             break;
1603         case Array::Float32Array:
1604             filter(node->child1(), SpecFloat32Array);
1605             break;
1606         case Array::Float64Array:
1607             filter(node->child1(), SpecFloat64Array);
1608             break;
1609         default:
1610             RELEASE_ASSERT_NOT_REACHED();
1611             break;
1612         }
1613         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
1614         break;
1615     }
1616     case Arrayify: {
1617         if (node->arrayMode().alreadyChecked(m_graph, node, forNode(node->child1()))) {
1618             m_state.setFoundConstants(true);
1619             break;
1620         }
1621         ASSERT(node->arrayMode().conversion() == Array::Convert
1622             || node->arrayMode().conversion() == Array::RageConvert);
1623         node->setCanExit(true);
1624         clobberStructures(clobberLimit);
1625         filterArrayModes(node->child1(), node->arrayMode().arrayModesThatPassFiltering());
1626         break;
1627     }
1628     case ArrayifyToStructure: {
1629         AbstractValue& value = forNode(node->child1());
1630         if (value.m_structure.isSubsetOf(StructureSet(node->structure())))
1631             m_state.setFoundConstants(true);
1632         node->setCanExit(true);
1633         clobberStructures(clobberLimit);
1634         
1635         // We have a bunch of options of how to express the abstract set at this point. Let set S
1636         // be the set of structures that the value had before clobbering and assume that all of
1637         // them are watchable. The new value should be the least expressible upper bound of the
1638         // intersection of "values that currently have structure = node->structure()" and "values
1639         // that have structure in S plus any structure transition-reachable from S". Assume that
1640         // node->structure() is not in S but it is transition-reachable from S. Then we would
1641         // like to say that the result is "values that have structure = node->structure() until
1642         // we invalidate", but there is no way to express this using the AbstractValue syntax. So
1643         // we must choose between:
1644         //
1645         // 1) "values that currently have structure = node->structure()". This is a valid
1646         //    superset of the value that we really want, and it's specific enough to satisfy the
1647         //    preconditions of the array access that this is guarding. It's also specific enough
1648         //    to allow relevant optimizations in the case that we didn't have a contradiction
1649         //    like in this example. Notice that in the abscence of any contradiction, this result
1650         //    is precise rather than being a conservative LUB.
1651         //
1652         // 2) "values that currently hava structure in S plus any structure transition-reachable
1653         //    from S". This is also a valid superset of the value that we really want, but it's
1654         //    not specific enough to satisfy the preconditions of the array access that this is
1655         //    guarding - so playing such shenanigans would preclude us from having assertions on
1656         //    the typing preconditions of any array accesses. This would also not be a desirable
1657         //    answer in the absence of a contradiction.
1658         //
1659         // Note that it's tempting to simply say that the resulting value is BOTTOM because of
1660         // the contradiction. That would be wrong, since we haven't hit an invalidation point,
1661         // yet.
1662         value.set(m_graph, node->structure());
1663         break;
1664     }
1665     case GetIndexedPropertyStorage:
1666     case ConstantStoragePointer: {
1667         forNode(node).clear();
1668         break; 
1669     }
1670         
1671     case GetTypedArrayByteOffset: {
1672         forNode(node).setType(SpecInt32);
1673         break;
1674     }
1675         
1676     case GetByOffset: {
1677         forNode(node).makeHeapTop();
1678         break;
1679     }
1680         
1681     case GetGetterSetterByOffset: {
1682         forNode(node).set(m_graph, m_graph.m_vm.getterSetterStructure.get());
1683         break;
1684     }
1685         
1686     case MultiGetByOffset: {
1687         AbstractValue& value = forNode(node->child1());
1688         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1689
1690         // This should just filter down the cases in MultiGetByOffset. If that results in all
1691         // cases having the same offset then we should strength reduce it to a CheckStructure +
1692         // GetByOffset.
1693         // https://bugs.webkit.org/show_bug.cgi?id=133229
1694         if (Structure* structure = value.m_structure.onlyStructure()) {
1695             bool done = false;
1696             for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
1697                 const GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
1698                 if (!variant.structureSet().contains(structure))
1699                     continue;
1700                 
1701                 if (variant.chain())
1702                     break;
1703                 
1704                 filter(value, structure);
1705                 forNode(node).makeHeapTop();
1706                 m_state.setFoundConstants(true);
1707                 done = true;
1708                 break;
1709             }
1710             if (done)
1711                 break;
1712         }
1713         
1714         StructureSet set;
1715         for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;)
1716             set.merge(node->multiGetByOffsetData().variants[i].structureSet());
1717         
1718         filter(node->child1(), set);
1719         forNode(node).makeHeapTop();
1720         break;
1721     }
1722             
1723     case PutByOffset: {
1724         break;
1725     }
1726         
1727     case MultiPutByOffset: {
1728         AbstractValue& value = forNode(node->child1());
1729         ASSERT(!(value.m_type & ~SpecCell)); // Edge filtering should have already ensured this.
1730
1731         // This should just filter down the cases in MultiPutByOffset. If that results in either
1732         // one case, or nothing but replace cases and they have the same offset, then we should
1733         // just strength reduce it to the appropriate combination of CheckStructure,
1734         // [Re]AllocatePropertyStorage, PutStructure, and PutByOffset.
1735         // https://bugs.webkit.org/show_bug.cgi?id=133229
1736         if (Structure* structure = value.m_structure.onlyStructure()) {
1737             bool done = false;
1738             for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
1739                 const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
1740                 if (variant.oldStructure() != structure)
1741                     continue;
1742                 
1743                 if (variant.kind() == PutByIdVariant::Replace) {
1744                     filter(node->child1(), structure);
1745                     m_state.setFoundConstants(true);
1746                     done = true;
1747                     break;
1748                 }
1749                 
1750                 ASSERT(variant.kind() == PutByIdVariant::Transition);
1751                 clobberStructures(clobberLimit);
1752                 forNode(node->child1()).set(m_graph, variant.newStructure());
1753                 m_state.setFoundConstants(true);
1754                 done = true;
1755                 break;
1756             }
1757             if (done)
1758                 break;
1759         }
1760         
1761         StructureSet oldSet;
1762         StructureSet newSet;
1763         TransitionVector transitions;
1764         for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
1765             const PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
1766             oldSet.add(variant.oldStructure());
1767             if (variant.kind() == PutByIdVariant::Transition) {
1768                 transitions.append(Transition(variant.oldStructure(), variant.newStructure()));
1769                 newSet.add(variant.newStructure());
1770             } else {
1771                 ASSERT(variant.kind() == PutByIdVariant::Replace);
1772                 newSet.add(variant.oldStructure());
1773             }
1774         }
1775         
1776         filter(node->child1(), oldSet);
1777         observeTransitions(clobberLimit, transitions);
1778         forNode(node->child1()).set(m_graph, newSet);
1779         break;
1780     }
1781     
1782     case CheckFunction: {
1783         JSValue value = forNode(node->child1()).value();
1784         if (value == node->function()) {
1785             m_state.setFoundConstants(true);
1786             ASSERT(value);
1787             break;
1788         }
1789         
1790         node->setCanExit(true); // Lies! We can do better.
1791         filterByValue(node->child1(), node->function());
1792         break;
1793     }
1794         
1795     case CheckInBounds: {
1796         JSValue left = forNode(node->child1()).value();
1797         JSValue right = forNode(node->child2()).value();
1798         if (left && right && left.isInt32() && right.isInt32()
1799             && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
1800             m_state.setFoundConstants(true);
1801             break;
1802         }
1803         
1804         node->setCanExit(true);
1805         break;
1806     }
1807         
1808     case PutById:
1809     case PutByIdFlush:
1810     case PutByIdDirect:
1811         node->setCanExit(true);
1812         // This use of onlyStructure() should be replaced by giving PutByIdStatus the ability
1813         // to compute things based on a StructureSet, and then to factor ByteCodeParser's
1814         // ability to generate code based on a PutByIdStatus out of ByteCodeParser so that
1815         // ConstantFoldingPhase can use it.
1816         // https://bugs.webkit.org/show_bug.cgi?id=133229
1817         if (Structure* structure = forNode(node->child1()).m_structure.onlyStructure()) {
1818             PutByIdStatus status = PutByIdStatus::computeFor(
1819                 m_graph.m_vm,
1820                 m_graph.globalObjectFor(node->origin.semantic),
1821                 structure,
1822                 m_graph.identifiers()[node->identifierNumber()],
1823                 node->op() == PutByIdDirect);
1824             if (status.isSimple() && status.numVariants() == 1) {
1825                 if (status[0].kind() == PutByIdVariant::Replace) {
1826                     filter(node->child1(), structure);
1827                     m_state.setFoundConstants(true);
1828                     break;
1829                 }
1830                 if (status[0].kind() == PutByIdVariant::Transition
1831                     && structure->transitionWatchpointSetHasBeenInvalidated()) {
1832                     m_graph.watchpoints().consider(status[0].newStructure());
1833                     clobberStructures(clobberLimit);
1834                     forNode(node->child1()).set(m_graph, status[0].newStructure());
1835                     m_state.setFoundConstants(true);
1836                     break;
1837                 }
1838             }
1839         }
1840         clobberWorld(node->origin.semantic, clobberLimit);
1841         break;
1842         
1843     case In:
1844         // FIXME: We can determine when the property definitely exists based on abstract
1845         // value information.
1846         clobberWorld(node->origin.semantic, clobberLimit);
1847         forNode(node).setType(SpecBoolean);
1848         break;
1849             
1850     case GetGlobalVar:
1851         forNode(node).makeHeapTop();
1852         break;
1853         
1854     case VariableWatchpoint:
1855     case VarInjectionWatchpoint:
1856         node->setCanExit(true);
1857         break;
1858             
1859     case PutGlobalVar:
1860     case NotifyWrite:
1861         break;
1862             
1863     case CheckHasInstance:
1864         node->setCanExit(true);
1865         // Sadly, we don't propagate the fact that we've done CheckHasInstance
1866         break;
1867             
1868     case InstanceOf:
1869         node->setCanExit(true);
1870         // Again, sadly, we don't propagate the fact that we've done InstanceOf
1871         forNode(node).setType(SpecBoolean);
1872         break;
1873             
1874     case Phi:
1875         RELEASE_ASSERT(m_graph.m_form == SSA);
1876         // The state of this node would have already been decided.
1877         break;
1878         
1879     case Upsilon: {
1880         m_state.createValueForNode(node->phi());
1881         AbstractValue value = forNode(node->child1());
1882         forNode(node) = value;
1883         forNode(node->phi()) = value;
1884         break;
1885     }
1886         
1887     case Flush:
1888     case PhantomLocal:
1889         break;
1890             
1891     case Call:
1892     case Construct:
1893         node->setCanExit(true);
1894         clobberWorld(node->origin.semantic, clobberLimit);
1895         forNode(node).makeHeapTop();
1896         break;
1897
1898     case ForceOSRExit:
1899         node->setCanExit(true);
1900         m_state.setIsValid(false);
1901         break;
1902         
1903     case InvalidationPoint:
1904         node->setCanExit(true);
1905         forAllValues(clobberLimit, AbstractValue::observeInvalidationPointFor);
1906         m_state.setStructureClobberState(StructuresAreWatched);
1907         break;
1908
1909     case CheckWatchdogTimer:
1910         node->setCanExit(true);
1911         break;
1912
1913     case Breakpoint:
1914     case ProfileWillCall:
1915     case ProfileDidCall:
1916     case Phantom:
1917     case HardPhantom:
1918     case Check:
1919     case CountExecution:
1920     case CheckTierUpInLoop:
1921     case CheckTierUpAtReturn:
1922         break;
1923
1924     case StoreBarrier: {
1925         filter(node->child1(), SpecCell);
1926         break;
1927     }
1928
1929     case StoreBarrierWithNullCheck: {
1930         break;
1931     }
1932
1933     case CheckTierUpAndOSREnter:
1934     case LoopHint:
1935         // We pretend that it can exit because it may want to get all state.
1936         node->setCanExit(true);
1937         break;
1938
1939     case ZombieHint:
1940     case Unreachable:
1941     case LastNodeType:
1942     case ArithIMul:
1943     case FiatInt52:
1944         RELEASE_ASSERT_NOT_REACHED();
1945         break;
1946     }
1947     
1948     return m_state.isValid();
1949 }
1950
1951 template<typename AbstractStateType>
1952 bool AbstractInterpreter<AbstractStateType>::executeEffects(unsigned indexInBlock)
1953 {
1954     return executeEffects(indexInBlock, m_state.block()->at(indexInBlock));
1955 }
1956
1957 template<typename AbstractStateType>
1958 bool AbstractInterpreter<AbstractStateType>::execute(unsigned indexInBlock)
1959 {
1960     Node* node = m_state.block()->at(indexInBlock);
1961     if (!startExecuting(node))
1962         return true;
1963     
1964     executeEdges(node);
1965     return executeEffects(indexInBlock, node);
1966 }
1967
1968 template<typename AbstractStateType>
1969 bool AbstractInterpreter<AbstractStateType>::execute(Node* node)
1970 {
1971     if (!startExecuting(node))
1972         return true;
1973     
1974     executeEdges(node);
1975     return executeEffects(UINT_MAX, node);
1976 }
1977
1978 template<typename AbstractStateType>
1979 void AbstractInterpreter<AbstractStateType>::clobberWorld(
1980     const CodeOrigin& codeOrigin, unsigned clobberLimit)
1981 {
1982     clobberCapturedVars(codeOrigin);
1983     clobberStructures(clobberLimit);
1984 }
1985
1986 template<typename AbstractStateType>
1987 void AbstractInterpreter<AbstractStateType>::clobberCapturedVars(const CodeOrigin& codeOrigin)
1988 {
1989     SamplingRegion samplingRegion("DFG AI Clobber Captured Vars");
1990     if (codeOrigin.inlineCallFrame) {
1991         const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
1992         for (size_t i = capturedVars.size(); i--;) {
1993             if (!capturedVars.quickGet(i))
1994                 continue;
1995             m_state.variables().local(i).makeHeapTop();
1996         }
1997     } else {
1998         for (size_t i = m_codeBlock->m_numVars; i--;) {
1999             if (m_codeBlock->isCaptured(virtualRegisterForLocal(i)))
2000                 m_state.variables().local(i).makeHeapTop();
2001         }
2002     }
2003
2004     for (size_t i = m_state.variables().numberOfArguments(); i--;) {
2005         if (m_codeBlock->isCaptured(virtualRegisterForArgument(i)))
2006             m_state.variables().argument(i).makeHeapTop();
2007     }
2008 }
2009
2010 template<typename AbstractStateType>
2011 template<typename Functor>
2012 void AbstractInterpreter<AbstractStateType>::forAllValues(
2013     unsigned clobberLimit, Functor& functor)
2014 {
2015     SamplingRegion samplingRegion("DFG AI For All Values");
2016     if (clobberLimit >= m_state.block()->size())
2017         clobberLimit = m_state.block()->size();
2018     else
2019         clobberLimit++;
2020     ASSERT(clobberLimit <= m_state.block()->size());
2021     for (size_t i = clobberLimit; i--;)
2022         functor(forNode(m_state.block()->at(i)));
2023     if (m_graph.m_form == SSA) {
2024         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2025         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
2026         for (; iter != end; ++iter)
2027             functor(forNode(*iter));
2028     }
2029     for (size_t i = m_state.variables().numberOfArguments(); i--;)
2030         functor(m_state.variables().argument(i));
2031     for (size_t i = m_state.variables().numberOfLocals(); i--;)
2032         functor(m_state.variables().local(i));
2033 }
2034
2035 template<typename AbstractStateType>
2036 void AbstractInterpreter<AbstractStateType>::clobberStructures(unsigned clobberLimit)
2037 {
2038     SamplingRegion samplingRegion("DFG AI Clobber Structures");
2039     forAllValues(clobberLimit, AbstractValue::clobberStructuresFor);
2040     setDidClobber();
2041 }
2042
2043 template<typename AbstractStateType>
2044 void AbstractInterpreter<AbstractStateType>::observeTransition(
2045     unsigned clobberLimit, Structure* from, Structure* to)
2046 {
2047     AbstractValue::TransitionObserver transitionObserver(from, to);
2048     forAllValues(clobberLimit, transitionObserver);
2049     setDidClobber();
2050 }
2051
2052 template<typename AbstractStateType>
2053 void AbstractInterpreter<AbstractStateType>::observeTransitions(
2054     unsigned clobberLimit, const TransitionVector& vector)
2055 {
2056     AbstractValue::TransitionsObserver transitionsObserver(vector);
2057     forAllValues(clobberLimit, transitionsObserver);
2058     setDidClobber();
2059 }
2060
2061 template<typename AbstractStateType>
2062 void AbstractInterpreter<AbstractStateType>::setDidClobber()
2063 {
2064     m_state.setDidClobber(true);
2065     m_state.setStructureClobberState(StructuresAreClobbered);
2066 }
2067
2068 template<typename AbstractStateType>
2069 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out) const
2070 {
2071     const_cast<AbstractInterpreter<AbstractStateType>*>(this)->dump(out);
2072 }
2073
2074 template<typename AbstractStateType>
2075 void AbstractInterpreter<AbstractStateType>::dump(PrintStream& out)
2076 {
2077     CommaPrinter comma(" ");
2078     HashSet<Node*> seen;
2079     if (m_graph.m_form == SSA) {
2080         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtHead.begin();
2081         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtHead.end();
2082         for (; iter != end; ++iter) {
2083             Node* node = *iter;
2084             seen.add(node);
2085             AbstractValue& value = forNode(node);
2086             if (value.isClear())
2087                 continue;
2088             out.print(comma, node, ":", value);
2089         }
2090     }
2091     for (size_t i = 0; i < m_state.block()->size(); ++i) {
2092         Node* node = m_state.block()->at(i);
2093         seen.add(node);
2094         AbstractValue& value = forNode(node);
2095         if (value.isClear())
2096             continue;
2097         out.print(comma, node, ":", value);
2098     }
2099     if (m_graph.m_form == SSA) {
2100         HashSet<Node*>::iterator iter = m_state.block()->ssa->liveAtTail.begin();
2101         HashSet<Node*>::iterator end = m_state.block()->ssa->liveAtTail.end();
2102         for (; iter != end; ++iter) {
2103             Node* node = *iter;
2104             if (seen.contains(node))
2105                 continue;
2106             AbstractValue& value = forNode(node);
2107             if (value.isClear())
2108                 continue;
2109             out.print(comma, node, ":", value);
2110         }
2111     }
2112 }
2113
2114 template<typename AbstractStateType>
2115 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2116     AbstractValue& value, const StructureSet& set)
2117 {
2118     if (value.filter(m_graph, set) == FiltrationOK)
2119         return FiltrationOK;
2120     m_state.setIsValid(false);
2121     return Contradiction;
2122 }
2123
2124 template<typename AbstractStateType>
2125 FiltrationResult AbstractInterpreter<AbstractStateType>::filterArrayModes(
2126     AbstractValue& value, ArrayModes arrayModes)
2127 {
2128     if (value.filterArrayModes(arrayModes) == FiltrationOK)
2129         return FiltrationOK;
2130     m_state.setIsValid(false);
2131     return Contradiction;
2132 }
2133
2134 template<typename AbstractStateType>
2135 FiltrationResult AbstractInterpreter<AbstractStateType>::filter(
2136     AbstractValue& value, SpeculatedType type)
2137 {
2138     if (value.filter(type) == FiltrationOK)
2139         return FiltrationOK;
2140     m_state.setIsValid(false);
2141     return Contradiction;
2142 }
2143
2144 template<typename AbstractStateType>
2145 FiltrationResult AbstractInterpreter<AbstractStateType>::filterByValue(
2146     AbstractValue& abstractValue, JSValue concreteValue)
2147 {
2148     if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
2149         return FiltrationOK;
2150     m_state.setIsValid(false);
2151     return Contradiction;
2152 }
2153
2154 } } // namespace JSC::DFG
2155
2156 #endif // ENABLE(DFG_JIT)
2157
2158 #endif // DFGAbstractInterpreterInlines_h
2159