Rename dataLog() and dataLogV() to dataLogF() and dataLogFV()
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGAbstractState.cpp
1 /*
2  * Copyright (C) 2011, 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGAbstractState.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "CodeBlock.h"
32 #include "DFGBasicBlock.h"
33 #include "GetByIdStatus.h"
34 #include "PutByIdStatus.h"
35
36 namespace JSC { namespace DFG {
37
38 AbstractState::AbstractState(Graph& graph)
39     : m_codeBlock(graph.m_codeBlock)
40     , m_graph(graph)
41     , m_variables(m_codeBlock->numParameters(), graph.m_localVars)
42     , m_block(0)
43 {
44     m_nodes.resize(graph.size());
45 }
46
47 AbstractState::~AbstractState() { }
48
49 void AbstractState::beginBasicBlock(BasicBlock* basicBlock)
50 {
51     ASSERT(!m_block);
52     
53     ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->valuesAtHead.numberOfLocals());
54     ASSERT(basicBlock->variablesAtTail.numberOfLocals() == basicBlock->valuesAtTail.numberOfLocals());
55     ASSERT(basicBlock->variablesAtHead.numberOfLocals() == basicBlock->variablesAtTail.numberOfLocals());
56     
57     // This is usually a no-op, but it is possible that the graph has grown since the
58     // abstract state was last used.
59     m_nodes.resize(m_graph.size());
60     
61     for (size_t i = 0; i < basicBlock->size(); i++)
62         m_nodes[basicBlock->at(i)].clear();
63
64     m_variables = basicBlock->valuesAtHead;
65     m_haveStructures = false;
66     for (size_t i = 0; i < m_variables.numberOfArguments(); ++i) {
67         if (m_variables.argument(i).m_currentKnownStructure.isNeitherClearNorTop()) {
68             m_haveStructures = true;
69             break;
70         }
71     }
72     for (size_t i = 0; i < m_variables.numberOfLocals(); ++i) {
73         if (m_variables.local(i).m_currentKnownStructure.isNeitherClearNorTop()) {
74             m_haveStructures = true;
75             break;
76         }
77     }
78     
79     basicBlock->cfaShouldRevisit = false;
80     basicBlock->cfaHasVisited = true;
81     m_block = basicBlock;
82     m_isValid = true;
83     m_foundConstants = false;
84     m_branchDirection = InvalidBranchDirection;
85 }
86
87 void AbstractState::initialize(Graph& graph)
88 {
89     BasicBlock* root = graph.m_blocks[0].get();
90     root->cfaShouldRevisit = true;
91     root->cfaHasVisited = false;
92     root->cfaFoundConstants = false;
93     for (size_t i = 0; i < root->valuesAtHead.numberOfArguments(); ++i) {
94         Node& node = graph[root->variablesAtHead.argument(i)];
95         ASSERT(node.op() == SetArgument);
96         if (!node.shouldGenerate()) {
97             // The argument is dead. We don't do any checks for such arguments, and so
98             // for the purpose of the analysis, they contain no value.
99             root->valuesAtHead.argument(i).clear();
100             continue;
101         }
102         
103         if (node.variableAccessData()->isCaptured()) {
104             root->valuesAtHead.argument(i).makeTop();
105             continue;
106         }
107         
108         SpeculatedType prediction = node.variableAccessData()->prediction();
109         if (isInt32Speculation(prediction))
110             root->valuesAtHead.argument(i).set(SpecInt32);
111         else if (isBooleanSpeculation(prediction))
112             root->valuesAtHead.argument(i).set(SpecBoolean);
113         else if (isCellSpeculation(prediction))
114             root->valuesAtHead.argument(i).set(SpecCell);
115         else
116             root->valuesAtHead.argument(i).makeTop();
117         
118         root->valuesAtTail.argument(i).clear();
119     }
120     for (size_t i = 0; i < root->valuesAtHead.numberOfLocals(); ++i) {
121         NodeIndex nodeIndex = root->variablesAtHead.local(i);
122         if (nodeIndex != NoNode && graph[nodeIndex].variableAccessData()->isCaptured())
123             root->valuesAtHead.local(i).makeTop();
124         else
125             root->valuesAtHead.local(i).clear();
126         root->valuesAtTail.local(i).clear();
127     }
128     for (BlockIndex blockIndex = 1 ; blockIndex < graph.m_blocks.size(); ++blockIndex) {
129         BasicBlock* block = graph.m_blocks[blockIndex].get();
130         if (!block)
131             continue;
132         if (!block->isReachable)
133             continue;
134         block->cfaShouldRevisit = false;
135         block->cfaHasVisited = false;
136         block->cfaFoundConstants = false;
137         for (size_t i = 0; i < block->valuesAtHead.numberOfArguments(); ++i) {
138             block->valuesAtHead.argument(i).clear();
139             block->valuesAtTail.argument(i).clear();
140         }
141         for (size_t i = 0; i < block->valuesAtHead.numberOfLocals(); ++i) {
142             block->valuesAtHead.local(i).clear();
143             block->valuesAtTail.local(i).clear();
144         }
145         if (!block->isOSRTarget)
146             continue;
147         if (block->bytecodeBegin != graph.m_osrEntryBytecodeIndex)
148             continue;
149         for (size_t i = 0; i < graph.m_mustHandleValues.size(); ++i) {
150             AbstractValue value;
151             value.setMostSpecific(graph.m_mustHandleValues[i]);
152             int operand = graph.m_mustHandleValues.operandForIndex(i);
153             block->valuesAtHead.operand(operand).merge(value);
154 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
155             dataLogF("    Initializing Block #%u, operand r%d, to ", blockIndex, operand);
156             block->valuesAtHead.operand(operand).dump(WTF::dataFile());
157             dataLogF("\n");
158 #endif
159         }
160         block->cfaShouldRevisit = true;
161     }
162 }
163
164 bool AbstractState::endBasicBlock(MergeMode mergeMode)
165 {
166     ASSERT(m_block);
167     
168     BasicBlock* block = m_block; // Save the block for successor merging.
169     
170     block->cfaFoundConstants = m_foundConstants;
171     block->cfaDidFinish = m_isValid;
172     block->cfaBranchDirection = m_branchDirection;
173     
174     if (!m_isValid) {
175         reset();
176         return false;
177     }
178     
179     bool changed = false;
180     
181     if (mergeMode != DontMerge || !ASSERT_DISABLED) {
182         for (size_t argument = 0; argument < block->variablesAtTail.numberOfArguments(); ++argument) {
183 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
184             dataLogF("        Merging state for argument %zu.\n", argument);
185 #endif
186             AbstractValue& destination = block->valuesAtTail.argument(argument);
187             changed |= mergeStateAtTail(destination, m_variables.argument(argument), block->variablesAtTail.argument(argument));
188         }
189         
190         for (size_t local = 0; local < block->variablesAtTail.numberOfLocals(); ++local) {
191 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
192             dataLogF("        Merging state for local %zu.\n", local);
193 #endif
194             AbstractValue& destination = block->valuesAtTail.local(local);
195             changed |= mergeStateAtTail(destination, m_variables.local(local), block->variablesAtTail.local(local));
196         }
197     }
198     
199     ASSERT(mergeMode != DontMerge || !changed);
200     
201 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
202     dataLogF("        Branch direction = %s\n", branchDirectionToString(m_branchDirection));
203 #endif
204     
205     reset();
206     
207     if (mergeMode != MergeToSuccessors)
208         return changed;
209     
210     return mergeToSuccessors(m_graph, block);
211 }
212
213 void AbstractState::reset()
214 {
215     m_block = 0;
216     m_isValid = false;
217     m_branchDirection = InvalidBranchDirection;
218 }
219
220 AbstractState::BooleanResult AbstractState::booleanResult(Node& node, AbstractValue& value)
221 {
222     JSValue childConst = value.value();
223     if (childConst) {
224         if (childConst.toBoolean(m_codeBlock->globalObjectFor(node.codeOrigin)->globalExec()))
225             return DefinitelyTrue;
226         return DefinitelyFalse;
227     }
228
229     // Next check if we can fold because we know that the source is an object or string and does not equal undefined.
230     if (isCellSpeculation(value.m_type)
231         && value.m_currentKnownStructure.hasSingleton()) {
232         Structure* structure = value.m_currentKnownStructure.singleton();
233         if (!structure->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin))
234             && structure->typeInfo().type() != StringType)
235             return DefinitelyTrue;
236     }
237     
238     return UnknownBooleanResult;
239 }
240
241 bool AbstractState::execute(unsigned indexInBlock)
242 {
243     ASSERT(m_block);
244     ASSERT(m_isValid);
245     
246     m_didClobber = false;
247     
248     NodeIndex nodeIndex = m_block->at(indexInBlock);
249     Node& node = m_graph[nodeIndex];
250         
251     if (!node.shouldGenerate())
252         return true;
253         
254     switch (node.op()) {
255     case JSConstant:
256     case WeakJSConstant:
257     case PhantomArguments: {
258         forNode(nodeIndex).set(m_graph.valueOfJSConstant(nodeIndex));
259         node.setCanExit(false);
260         break;
261     }
262         
263     case Identity: {
264         forNode(nodeIndex) = forNode(node.child1());
265         node.setCanExit(false);
266         break;
267     }
268             
269     case GetLocal: {
270         VariableAccessData* variableAccessData = node.variableAccessData();
271         if (variableAccessData->prediction() == SpecNone) {
272             m_isValid = false;
273             node.setCanExit(true);
274             break;
275         }
276         bool canExit = false;
277         AbstractValue value = m_variables.operand(variableAccessData->local());
278         if (!variableAccessData->isCaptured()) {
279             if (value.isClear())
280                 canExit |= true;
281         }
282         if (value.value())
283             m_foundConstants = true;
284         forNode(nodeIndex) = value;
285         node.setCanExit(canExit);
286         break;
287     }
288         
289     case GetLocalUnlinked: {
290         AbstractValue value = m_variables.operand(node.unlinkedLocal());
291         if (value.value())
292             m_foundConstants = true;
293         forNode(nodeIndex) = value;
294         node.setCanExit(false);
295         break;
296     }
297         
298     case SetLocal: {
299         if (node.variableAccessData()->isCaptured()
300             || m_graph.isCreatedThisArgument(node.local())) {
301             m_variables.operand(node.local()) = forNode(node.child1());
302             node.setCanExit(false);
303             break;
304         }
305         
306         if (node.variableAccessData()->shouldUseDoubleFormat()) {
307             speculateNumberUnary(node);
308             m_variables.operand(node.local()).set(SpecDouble);
309             break;
310         }
311         
312         SpeculatedType predictedType = node.variableAccessData()->argumentAwarePrediction();
313         if (isInt32Speculation(predictedType))
314             speculateInt32Unary(node);
315         else if (isCellSpeculation(predictedType)) {
316             node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
317             forNode(node.child1()).filter(SpecCell);
318         } else if (isBooleanSpeculation(predictedType))
319             speculateBooleanUnary(node);
320         else
321             node.setCanExit(false);
322         
323         m_variables.operand(node.local()) = forNode(node.child1());
324         break;
325     }
326             
327     case SetArgument:
328         // Assert that the state of arguments has been set.
329         ASSERT(!m_block->valuesAtHead.operand(node.local()).isClear());
330         node.setCanExit(false);
331         break;
332             
333     case BitAnd:
334     case BitOr:
335     case BitXor:
336     case BitRShift:
337     case BitLShift:
338     case BitURShift: {
339         JSValue left = forNode(node.child1()).value();
340         JSValue right = forNode(node.child2()).value();
341         if (left && right && left.isInt32() && right.isInt32()) {
342             int32_t a = left.asInt32();
343             int32_t b = right.asInt32();
344             bool constantWasSet;
345             switch (node.op()) {
346             case BitAnd:
347                 constantWasSet = trySetConstant(nodeIndex, JSValue(a & b));
348                 break;
349             case BitOr:
350                 constantWasSet = trySetConstant(nodeIndex, JSValue(a | b));
351                 break;
352             case BitXor:
353                 constantWasSet = trySetConstant(nodeIndex, JSValue(a ^ b));
354                 break;
355             case BitRShift:
356                 constantWasSet = trySetConstant(nodeIndex, JSValue(a >> static_cast<uint32_t>(b)));
357                 break;
358             case BitLShift:
359                 constantWasSet = trySetConstant(nodeIndex, JSValue(a << static_cast<uint32_t>(b)));
360                 break;
361             case BitURShift:
362                 constantWasSet = trySetConstant(nodeIndex, JSValue(static_cast<uint32_t>(a) >> static_cast<uint32_t>(b)));
363                 break;
364             default:
365                 ASSERT_NOT_REACHED();
366                 constantWasSet = false;
367             }
368             if (constantWasSet) {
369                 m_foundConstants = true;
370                 node.setCanExit(false);
371                 break;
372             }
373         }
374         speculateInt32Binary(node);
375         forNode(nodeIndex).set(SpecInt32);
376         break;
377     }
378         
379     case UInt32ToNumber: {
380         JSValue child = forNode(node.child1()).value();
381         if (child && child.isNumber()) {
382             ASSERT(child.isInt32());
383             if (trySetConstant(nodeIndex, JSValue(child.asUInt32()))) {
384                 m_foundConstants = true;
385                 node.setCanExit(false);
386                 break;
387             }
388         }
389         if (!node.canSpeculateInteger()) {
390             forNode(nodeIndex).set(SpecDouble);
391             node.setCanExit(false);
392         } else {
393             forNode(nodeIndex).set(SpecInt32);
394             node.setCanExit(true);
395         }
396         break;
397     }
398               
399             
400     case DoubleAsInt32: {
401         JSValue child = forNode(node.child1()).value();
402         if (child && child.isNumber()) {
403             double asDouble = child.asNumber();
404             int32_t asInt = JSC::toInt32(asDouble);
405             if (bitwise_cast<int64_t>(static_cast<double>(asInt)) == bitwise_cast<int64_t>(asDouble)
406                 && trySetConstant(nodeIndex, JSValue(asInt))) {
407                 m_foundConstants = true;
408                 break;
409             }
410         }
411         node.setCanExit(true);
412         forNode(node.child1()).filter(SpecNumber);
413         forNode(nodeIndex).set(SpecInt32);
414         break;
415     }
416             
417     case ValueToInt32: {
418         JSValue child = forNode(node.child1()).value();
419         if (child && child.isNumber()) {
420             bool constantWasSet;
421             if (child.isInt32())
422                 constantWasSet = trySetConstant(nodeIndex, child);
423             else
424                 constantWasSet = trySetConstant(nodeIndex, JSValue(JSC::toInt32(child.asDouble())));
425             if (constantWasSet) {
426                 m_foundConstants = true;
427                 node.setCanExit(false);
428                 break;
429             }
430         }
431         if (m_graph[node.child1()].shouldSpeculateInteger())
432             speculateInt32Unary(node);
433         else if (m_graph[node.child1()].shouldSpeculateNumber())
434             speculateNumberUnary(node);
435         else if (m_graph[node.child1()].shouldSpeculateBoolean())
436             speculateBooleanUnary(node);
437         else
438             node.setCanExit(false);
439         
440         forNode(nodeIndex).set(SpecInt32);
441         break;
442     }
443         
444     case Int32ToDouble: {
445         JSValue child = forNode(node.child1()).value();
446         if (child && child.isNumber()
447             && trySetConstant(nodeIndex, JSValue(JSValue::EncodeAsDouble, child.asNumber()))) {
448             m_foundConstants = true;
449             node.setCanExit(false);
450             break;
451         }
452         speculateNumberUnary(node);
453         if (isInt32Speculation(forNode(node.child1()).m_type))
454             forNode(nodeIndex).set(SpecDoubleReal);
455         else
456             forNode(nodeIndex).set(SpecDouble);
457         break;
458     }
459         
460     case CheckNumber:
461         forNode(node.child1()).filter(SpecNumber);
462         break;
463             
464     case ValueAdd:
465     case ArithAdd: {
466         JSValue left = forNode(node.child1()).value();
467         JSValue right = forNode(node.child2()).value();
468         if (left && right && left.isNumber() && right.isNumber()
469             && trySetConstant(nodeIndex, JSValue(left.asNumber() + right.asNumber()))) {
470             m_foundConstants = true;
471             node.setCanExit(false);
472             break;
473         }
474         if (m_graph.addShouldSpeculateInteger(node)) {
475             speculateInt32Binary(
476                 node, !nodeCanTruncateInteger(node.arithNodeFlags()));
477             forNode(nodeIndex).set(SpecInt32);
478             break;
479         }
480         if (Node::shouldSpeculateNumberExpectingDefined(m_graph[node.child1()], m_graph[node.child2()])) {
481             speculateNumberBinary(node);
482             if (isRealNumberSpeculation(forNode(node.child1()).m_type)
483                 && isRealNumberSpeculation(forNode(node.child2()).m_type))
484                 forNode(nodeIndex).set(SpecDoubleReal);
485             else
486                 forNode(nodeIndex).set(SpecDouble);
487             break;
488         }
489         if (node.op() == ValueAdd) {
490             clobberWorld(node.codeOrigin, indexInBlock);
491             forNode(nodeIndex).set(SpecString | SpecInt32 | SpecNumber);
492             node.setCanExit(false);
493             break;
494         }
495         // We don't handle this yet. :-(
496         m_isValid = false;
497         node.setCanExit(true);
498         break;
499     }
500             
501     case ArithSub: {
502         JSValue left = forNode(node.child1()).value();
503         JSValue right = forNode(node.child2()).value();
504         if (left && right && left.isNumber() && right.isNumber()
505             && trySetConstant(nodeIndex, JSValue(left.asNumber() - right.asNumber()))) {
506             m_foundConstants = true;
507             node.setCanExit(false);
508             break;
509         }
510         if (m_graph.addShouldSpeculateInteger(node)) {
511             speculateInt32Binary(
512                 node, !nodeCanTruncateInteger(node.arithNodeFlags()));
513             forNode(nodeIndex).set(SpecInt32);
514             break;
515         }
516         speculateNumberBinary(node);
517         forNode(nodeIndex).set(SpecDouble);
518         break;
519     }
520         
521     case ArithNegate: {
522         JSValue child = forNode(node.child1()).value();
523         if (child && child.isNumber()
524             && trySetConstant(nodeIndex, JSValue(-child.asNumber()))) {
525             m_foundConstants = true;
526             node.setCanExit(false);
527             break;
528         }
529         if (m_graph.negateShouldSpeculateInteger(node)) {
530             speculateInt32Unary(
531                 node, !nodeCanTruncateInteger(node.arithNodeFlags()));
532             forNode(nodeIndex).set(SpecInt32);
533             break;
534         }
535         speculateNumberUnary(node);
536         forNode(nodeIndex).set(SpecDouble);
537         break;
538     }
539         
540     case ArithMul: {
541         JSValue left = forNode(node.child1()).value();
542         JSValue right = forNode(node.child2()).value();
543         if (left && right && left.isNumber() && right.isNumber()
544             && trySetConstant(nodeIndex, JSValue(left.asNumber() * right.asNumber()))) {
545             m_foundConstants = true;
546             node.setCanExit(false);
547             break;
548         }
549         if (m_graph.mulShouldSpeculateInteger(node)) {
550             speculateInt32Binary(
551                 node,
552                 !nodeCanTruncateInteger(node.arithNodeFlags())
553                 || !nodeCanIgnoreNegativeZero(node.arithNodeFlags()));
554             forNode(nodeIndex).set(SpecInt32);
555             break;
556         }
557         speculateNumberBinary(node);
558         if (isRealNumberSpeculation(forNode(node.child1()).m_type)
559             || isRealNumberSpeculation(forNode(node.child2()).m_type))
560             forNode(nodeIndex).set(SpecDoubleReal);
561         else
562             forNode(nodeIndex).set(SpecDouble);
563         break;
564     }
565         
566     case ArithDiv:
567     case ArithMin:
568     case ArithMax:
569     case ArithMod: {
570         JSValue left = forNode(node.child1()).value();
571         JSValue right = forNode(node.child2()).value();
572         if (left && right && left.isNumber() && right.isNumber()) {
573             double a = left.asNumber();
574             double b = right.asNumber();
575             bool constantWasSet;
576             switch (node.op()) {
577             case ArithDiv:
578                 constantWasSet = trySetConstant(nodeIndex, JSValue(a / b));
579                 break;
580             case ArithMin:
581                 constantWasSet = trySetConstant(nodeIndex, JSValue(a < b ? a : (b <= a ? b : a + b)));
582                 break;
583             case ArithMax:
584                 constantWasSet = trySetConstant(nodeIndex, JSValue(a > b ? a : (b >= a ? b : a + b)));
585                 break;
586             case ArithMod:
587                 constantWasSet = trySetConstant(nodeIndex, JSValue(fmod(a, b)));
588                 break;
589             default:
590                 ASSERT_NOT_REACHED();
591                 constantWasSet = false;
592                 break;
593             }
594             if (constantWasSet) {
595                 m_foundConstants = true;
596                 node.setCanExit(false);
597                 break;
598             }
599         }
600         if (Node::shouldSpeculateIntegerForArithmetic(
601                 m_graph[node.child1()], m_graph[node.child2()])
602             && node.canSpeculateInteger()) {
603             speculateInt32Binary(node, true); // forcing can-exit, which is a bit on the conservative side.
604             forNode(nodeIndex).set(SpecInt32);
605             break;
606         }
607         speculateNumberBinary(node);
608         forNode(nodeIndex).set(SpecDouble);
609         break;
610     }
611             
612     case ArithAbs: {
613         JSValue child = forNode(node.child1()).value();
614         if (child && child.isNumber()
615             && trySetConstant(nodeIndex, JSValue(fabs(child.asNumber())))) {
616             m_foundConstants = true;
617             node.setCanExit(false);
618             break;
619         }
620         if (m_graph[node.child1()].shouldSpeculateIntegerForArithmetic()
621             && node.canSpeculateInteger()) {
622             speculateInt32Unary(node, true);
623             forNode(nodeIndex).set(SpecInt32);
624             break;
625         }
626         speculateNumberUnary(node);
627         forNode(nodeIndex).set(SpecDouble);
628         break;
629     }
630             
631     case ArithSqrt: {
632         JSValue child = forNode(node.child1()).value();
633         if (child && child.isNumber()
634             && trySetConstant(nodeIndex, JSValue(sqrt(child.asNumber())))) {
635             m_foundConstants = true;
636             node.setCanExit(false);
637             break;
638         }
639         speculateNumberUnary(node);
640         forNode(nodeIndex).set(SpecDouble);
641         break;
642     }
643             
644     case LogicalNot: {
645         bool didSetConstant = false;
646         switch (booleanResult(node, forNode(node.child1()))) {
647         case DefinitelyTrue:
648             didSetConstant = trySetConstant(nodeIndex, jsBoolean(false));
649             break;
650         case DefinitelyFalse:
651             didSetConstant = trySetConstant(nodeIndex, jsBoolean(true));
652             break;
653         default:
654             break;
655         }
656         if (didSetConstant) {
657             m_foundConstants = true;
658             node.setCanExit(false);
659             break;
660         }
661         Node& child = m_graph[node.child1()];
662         if (isBooleanSpeculation(child.prediction()))
663             speculateBooleanUnary(node);
664         else if (child.shouldSpeculateNonStringCellOrOther()) {
665             node.setCanExit(true);
666             forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
667         } else if (child.shouldSpeculateInteger())
668             speculateInt32Unary(node);
669         else if (child.shouldSpeculateNumber())
670             speculateNumberUnary(node);
671         else
672             node.setCanExit(false);
673         forNode(nodeIndex).set(SpecBoolean);
674         break;
675     }
676         
677     case IsUndefined:
678     case IsBoolean:
679     case IsNumber:
680     case IsString:
681     case IsObject:
682     case IsFunction: {
683         node.setCanExit(node.op() == IsUndefined && m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
684         JSValue child = forNode(node.child1()).value();
685         if (child) {
686             bool constantWasSet;
687             switch (node.op()) {
688             case IsUndefined:
689                 if (m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid()) {
690                     constantWasSet = trySetConstant(nodeIndex, jsBoolean(
691                         child.isCell()
692                         ? false 
693                         : child.isUndefined()));
694                 } else {
695                     constantWasSet = trySetConstant(nodeIndex, jsBoolean(
696                         child.isCell()
697                         ? child.asCell()->structure()->masqueradesAsUndefined(m_codeBlock->globalObjectFor(node.codeOrigin))
698                         : child.isUndefined()));
699                 }
700                 break;
701             case IsBoolean:
702                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(child.isBoolean()));
703                 break;
704             case IsNumber:
705                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(child.isNumber()));
706                 break;
707             case IsString:
708                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(isJSString(child)));
709                 break;
710             default:
711                 constantWasSet = false;
712                 break;
713             }
714             if (constantWasSet) {
715                 m_foundConstants = true;
716                 break;
717             }
718         }
719         forNode(nodeIndex).set(SpecBoolean);
720         break;
721     }
722             
723     case CompareLess:
724     case CompareLessEq:
725     case CompareGreater:
726     case CompareGreaterEq:
727     case CompareEq: {
728         bool constantWasSet = false;
729
730         JSValue leftConst = forNode(node.child1()).value();
731         JSValue rightConst = forNode(node.child2()).value();
732         if (leftConst && rightConst && leftConst.isNumber() && rightConst.isNumber()) {
733             double a = leftConst.asNumber();
734             double b = rightConst.asNumber();
735             switch (node.op()) {
736             case CompareLess:
737                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(a < b));
738                 break;
739             case CompareLessEq:
740                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(a <= b));
741                 break;
742             case CompareGreater:
743                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(a > b));
744                 break;
745             case CompareGreaterEq:
746                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(a >= b));
747                 break;
748             case CompareEq:
749                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(a == b));
750                 break;
751             default:
752                 ASSERT_NOT_REACHED();
753                 constantWasSet = false;
754                 break;
755             }
756         }
757         
758         if (!constantWasSet && node.op() == CompareEq) {
759             SpeculatedType leftType = forNode(node.child1()).m_type;
760             SpeculatedType rightType = forNode(node.child2()).m_type;
761             if ((isInt32Speculation(leftType) && isOtherSpeculation(rightType))
762                 || (isOtherSpeculation(leftType) && isInt32Speculation(rightType)))
763                 constantWasSet = trySetConstant(nodeIndex, jsBoolean(false));
764         }
765         
766         if (constantWasSet) {
767             m_foundConstants = true;
768             node.setCanExit(false);
769             break;
770         }
771         
772         forNode(nodeIndex).set(SpecBoolean);
773         
774         Node& left = m_graph[node.child1()];
775         Node& right = m_graph[node.child2()];
776         SpeculatedType filter;
777         SpeculatedTypeChecker checker;
778         if (Node::shouldSpeculateInteger(left, right)) {
779             filter = SpecInt32;
780             checker = isInt32Speculation;
781         } else if (Node::shouldSpeculateNumber(left, right)) {
782             filter = SpecNumber;
783             checker = isNumberSpeculation;
784         } else if (node.op() == CompareEq) {
785             if ((m_graph.isConstant(node.child1().index())
786                  && m_graph.valueOfJSConstant(node.child1().index()).isNull())
787                 || (m_graph.isConstant(node.child2().index())
788                     && m_graph.valueOfJSConstant(node.child2().index()).isNull())) {
789                 // We can exit if we haven't fired the MasqueradesAsUndefind watchpoint yet.
790                 node.setCanExit(m_codeBlock->globalObjectFor(node.codeOrigin)->masqueradesAsUndefinedWatchpoint()->isStillValid());
791                 break;
792             }
793             
794             if (left.shouldSpeculateString() || right.shouldSpeculateString()) {
795                 node.setCanExit(false);
796                 break;
797             } 
798             if (left.shouldSpeculateNonStringCell() && right.shouldSpeculateNonStringCellOrOther()) {
799                 node.setCanExit(true);
800                 forNode(node.child1()).filter(SpecCell & ~SpecString);
801                 forNode(node.child2()).filter((SpecCell & ~SpecString) | SpecOther);
802                 break;
803             }
804             if (left.shouldSpeculateNonStringCellOrOther() && right.shouldSpeculateNonStringCell()) {
805                 node.setCanExit(true);
806                 forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
807                 forNode(node.child2()).filter(SpecCell & ~SpecString);
808                 break;
809             }
810             if (left.shouldSpeculateNonStringCell() && right.shouldSpeculateNonStringCell()) {
811                 node.setCanExit(true);
812                 forNode(node.child1()).filter(SpecCell & ~SpecString);
813                 forNode(node.child2()).filter(SpecCell & ~SpecString);
814                 break;
815             }
816  
817             filter = SpecTop;
818             checker = isAnySpeculation;
819             clobberWorld(node.codeOrigin, indexInBlock);
820         } else {
821             filter = SpecTop;
822             checker = isAnySpeculation;
823             clobberWorld(node.codeOrigin, indexInBlock);
824         }
825         node.setCanExit(
826             !checker(forNode(node.child1()).m_type)
827             || !checker(forNode(node.child2()).m_type));
828         forNode(node.child1()).filter(filter);
829         forNode(node.child2()).filter(filter);
830         break;
831     }
832             
833     case CompareStrictEq: {
834         JSValue left = forNode(node.child1()).value();
835         JSValue right = forNode(node.child2()).value();
836         if (left && right && left.isNumber() && right.isNumber()
837             && trySetConstant(nodeIndex, jsBoolean(left.asNumber() == right.asNumber()))) {
838             m_foundConstants = true;
839             node.setCanExit(false);
840             break;
841         }
842         forNode(nodeIndex).set(SpecBoolean);
843         if (m_graph.isJSConstant(node.child1().index())) {
844             JSValue value = m_graph.valueOfJSConstant(node.child1().index());
845             if (!value.isNumber() && !value.isString()) {
846                 node.setCanExit(false);
847                 break;
848             }
849         }
850         if (m_graph.isJSConstant(node.child2().index())) {
851             JSValue value = m_graph.valueOfJSConstant(node.child2().index());
852             if (!value.isNumber() && !value.isString()) {
853                 node.setCanExit(false);
854                 break;
855             }
856         }
857         if (Node::shouldSpeculateInteger(
858                 m_graph[node.child1()], m_graph[node.child2()])) {
859             speculateInt32Binary(node);
860             break;
861         }
862         if (Node::shouldSpeculateNumber(
863                 m_graph[node.child1()], m_graph[node.child2()])) {
864             speculateNumberBinary(node);
865             break;
866         }
867         Node& leftNode = m_graph[node.child1()];
868         Node& rightNode = m_graph[node.child2()];
869         if (leftNode.shouldSpeculateString() || rightNode.shouldSpeculateString()) {
870             node.setCanExit(false);
871             break;
872         }
873         if (leftNode.shouldSpeculateNonStringCell() && rightNode.shouldSpeculateNonStringCell()) {
874             node.setCanExit(true);
875             forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
876             forNode(node.child2()).filter((SpecCell & ~SpecString) | SpecOther);
877             break;
878         }
879         node.setCanExit(false);
880         break;
881     }
882         
883     case StringCharCodeAt:
884         node.setCanExit(true);
885         forNode(node.child1()).filter(SpecString);
886         forNode(node.child2()).filter(SpecInt32);
887         forNode(nodeIndex).set(SpecInt32);
888         break;
889         
890     case StringCharAt:
891         node.setCanExit(true);
892         forNode(node.child1()).filter(SpecString);
893         forNode(node.child2()).filter(SpecInt32);
894         forNode(nodeIndex).set(SpecString);
895         break;
896             
897     case GetByVal: {
898         node.setCanExit(true);
899         switch (node.arrayMode().type()) {
900         case Array::SelectUsingPredictions:
901         case Array::Unprofiled:
902         case Array::Undecided:
903             ASSERT_NOT_REACHED();
904             break;
905         case Array::ForceExit:
906             m_isValid = false;
907             break;
908         case Array::Generic:
909             clobberWorld(node.codeOrigin, indexInBlock);
910             forNode(nodeIndex).makeTop();
911             break;
912         case Array::String:
913             forNode(node.child2()).filter(SpecInt32);
914             forNode(nodeIndex).set(SpecString);
915             break;
916         case Array::Arguments:
917             forNode(node.child2()).filter(SpecInt32);
918             forNode(nodeIndex).makeTop();
919             break;
920         case Array::Int32:
921             forNode(node.child2()).filter(SpecInt32);
922             if (node.arrayMode().isOutOfBounds()) {
923                 clobberWorld(node.codeOrigin, indexInBlock);
924                 forNode(nodeIndex).makeTop();
925             } else
926                 forNode(nodeIndex).set(SpecInt32);
927             break;
928         case Array::Double:
929             forNode(node.child2()).filter(SpecInt32);
930             if (node.arrayMode().isOutOfBounds()) {
931                 clobberWorld(node.codeOrigin, indexInBlock);
932                 forNode(nodeIndex).makeTop();
933             } else if (node.arrayMode().isSaneChain())
934                 forNode(nodeIndex).set(SpecDouble);
935             else
936                 forNode(nodeIndex).set(SpecDoubleReal);
937             break;
938         case Array::Contiguous:
939         case Array::ArrayStorage:
940         case Array::SlowPutArrayStorage:
941             forNode(node.child2()).filter(SpecInt32);
942             if (node.arrayMode().isOutOfBounds())
943                 clobberWorld(node.codeOrigin, indexInBlock);
944             forNode(nodeIndex).makeTop();
945             break;
946         case Array::Int8Array:
947             forNode(node.child2()).filter(SpecInt32);
948             forNode(nodeIndex).set(SpecInt32);
949             break;
950         case Array::Int16Array:
951             forNode(node.child2()).filter(SpecInt32);
952             forNode(nodeIndex).set(SpecInt32);
953             break;
954         case Array::Int32Array:
955             forNode(node.child2()).filter(SpecInt32);
956             forNode(nodeIndex).set(SpecInt32);
957             break;
958         case Array::Uint8Array:
959             forNode(node.child2()).filter(SpecInt32);
960             forNode(nodeIndex).set(SpecInt32);
961             break;
962         case Array::Uint8ClampedArray:
963             forNode(node.child2()).filter(SpecInt32);
964             forNode(nodeIndex).set(SpecInt32);
965             break;
966         case Array::Uint16Array:
967             forNode(node.child2()).filter(SpecInt32);
968             forNode(nodeIndex).set(SpecInt32);
969             break;
970         case Array::Uint32Array:
971             forNode(node.child2()).filter(SpecInt32);
972             if (node.shouldSpeculateInteger())
973                 forNode(nodeIndex).set(SpecInt32);
974             else
975                 forNode(nodeIndex).set(SpecDouble);
976             break;
977         case Array::Float32Array:
978             forNode(node.child2()).filter(SpecInt32);
979             forNode(nodeIndex).set(SpecDouble);
980             break;
981         case Array::Float64Array:
982             forNode(node.child2()).filter(SpecInt32);
983             forNode(nodeIndex).set(SpecDouble);
984             break;
985         default:
986             ASSERT_NOT_REACHED();
987             break;
988         }
989         break;
990     }
991             
992     case PutByVal:
993     case PutByValAlias: {
994         node.setCanExit(true);
995         Edge child1 = m_graph.varArgChild(node, 0);
996         Edge child2 = m_graph.varArgChild(node, 1);
997         Edge child3 = m_graph.varArgChild(node, 2);
998         switch (node.arrayMode().modeForPut().type()) {
999         case Array::ForceExit:
1000             m_isValid = false;
1001             break;
1002         case Array::Generic:
1003             clobberWorld(node.codeOrigin, indexInBlock);
1004             break;
1005         case Array::Int32:
1006             forNode(child1).filter(SpecCell);
1007             forNode(child2).filter(SpecInt32);
1008             forNode(child3).filter(SpecInt32);
1009             if (node.arrayMode().isOutOfBounds())
1010                 clobberWorld(node.codeOrigin, indexInBlock);
1011             break;
1012         case Array::Double:
1013             forNode(child1).filter(SpecCell);
1014             forNode(child2).filter(SpecInt32);
1015             forNode(child3).filter(SpecRealNumber);
1016             if (node.arrayMode().isOutOfBounds())
1017                 clobberWorld(node.codeOrigin, indexInBlock);
1018             break;
1019         case Array::Contiguous:
1020         case Array::ArrayStorage:
1021             forNode(child1).filter(SpecCell);
1022             forNode(child2).filter(SpecInt32);
1023             if (node.arrayMode().isOutOfBounds())
1024                 clobberWorld(node.codeOrigin, indexInBlock);
1025             break;
1026         case Array::SlowPutArrayStorage:
1027             forNode(child1).filter(SpecCell);
1028             forNode(child2).filter(SpecInt32);
1029             if (node.arrayMode().mayStoreToHole())
1030                 clobberWorld(node.codeOrigin, indexInBlock);
1031             break;
1032         case Array::Arguments:
1033             forNode(child1).filter(SpecCell);
1034             forNode(child2).filter(SpecInt32);
1035             break;
1036         case Array::Int8Array:
1037             forNode(child1).filter(SpecCell);
1038             forNode(child2).filter(SpecInt32);
1039             if (m_graph[child3].shouldSpeculateInteger())
1040                 forNode(child3).filter(SpecInt32);
1041             else
1042                 forNode(child3).filter(SpecNumber);
1043             break;
1044         case Array::Int16Array:
1045             forNode(child1).filter(SpecCell);
1046             forNode(child2).filter(SpecInt32);
1047             if (m_graph[child3].shouldSpeculateInteger())
1048                 forNode(child3).filter(SpecInt32);
1049             else
1050                 forNode(child3).filter(SpecNumber);
1051             break;
1052         case Array::Int32Array:
1053             forNode(child1).filter(SpecCell);
1054             forNode(child2).filter(SpecInt32);
1055             if (m_graph[child3].shouldSpeculateInteger())
1056                 forNode(child3).filter(SpecInt32);
1057             else
1058                 forNode(child3).filter(SpecNumber);
1059             break;
1060         case Array::Uint8Array:
1061             forNode(child1).filter(SpecCell);
1062             forNode(child2).filter(SpecInt32);
1063             if (m_graph[child3].shouldSpeculateInteger())
1064                 forNode(child3).filter(SpecInt32);
1065             else
1066                 forNode(child3).filter(SpecNumber);
1067             break;
1068         case Array::Uint8ClampedArray:
1069             forNode(child1).filter(SpecCell);
1070             forNode(child2).filter(SpecInt32);
1071             if (m_graph[child3].shouldSpeculateInteger())
1072                 forNode(child3).filter(SpecInt32);
1073             else
1074                 forNode(child3).filter(SpecNumber);
1075             break;
1076         case Array::Uint16Array:
1077             forNode(child1).filter(SpecCell);
1078             forNode(child2).filter(SpecInt32);
1079             if (m_graph[child3].shouldSpeculateInteger())
1080                 forNode(child3).filter(SpecInt32);
1081             else
1082                 forNode(child3).filter(SpecNumber);
1083             break;
1084         case Array::Uint32Array:
1085             forNode(child1).filter(SpecCell);
1086             forNode(child2).filter(SpecInt32);
1087             if (m_graph[child3].shouldSpeculateInteger())
1088                 forNode(child3).filter(SpecInt32);
1089             else
1090                 forNode(child3).filter(SpecNumber);
1091             break;
1092         case Array::Float32Array:
1093             forNode(child1).filter(SpecCell);
1094             forNode(child2).filter(SpecInt32);
1095             forNode(child3).filter(SpecNumber);
1096             break;
1097         case Array::Float64Array:
1098             forNode(child1).filter(SpecCell);
1099             forNode(child2).filter(SpecInt32);
1100             forNode(child3).filter(SpecNumber);
1101             break;
1102         default:
1103             CRASH();
1104             break;
1105         }
1106         break;
1107     }
1108             
1109     case ArrayPush:
1110         node.setCanExit(true);
1111         switch (node.arrayMode().type()) {
1112         case Array::Int32:
1113             forNode(node.child2()).filter(SpecInt32);
1114             break;
1115         case Array::Double:
1116             forNode(node.child2()).filter(SpecRealNumber);
1117             break;
1118         default:
1119             break;
1120         }
1121         clobberWorld(node.codeOrigin, indexInBlock);
1122         forNode(nodeIndex).set(SpecNumber);
1123         break;
1124             
1125     case ArrayPop:
1126         node.setCanExit(true);
1127         clobberWorld(node.codeOrigin, indexInBlock);
1128         forNode(nodeIndex).makeTop();
1129         break;
1130             
1131     case RegExpExec:
1132     case RegExpTest:
1133         node.setCanExit(
1134             !isCellSpeculation(forNode(node.child1()).m_type)
1135             || !isCellSpeculation(forNode(node.child2()).m_type));
1136         forNode(node.child1()).filter(SpecCell);
1137         forNode(node.child2()).filter(SpecCell);
1138         forNode(nodeIndex).makeTop();
1139         break;
1140             
1141     case Jump:
1142         node.setCanExit(false);
1143         break;
1144             
1145     case Branch: {
1146         BooleanResult result = booleanResult(node, forNode(node.child1()));
1147         if (result == DefinitelyTrue) {
1148             m_branchDirection = TakeTrue;
1149             node.setCanExit(false);
1150             break;
1151         }
1152         if (result == DefinitelyFalse) {
1153             m_branchDirection = TakeFalse;
1154             node.setCanExit(false);
1155             break;
1156         }
1157         // FIXME: The above handles the trivial cases of sparse conditional
1158         // constant propagation, but we can do better:
1159         // We can specialize the source variable's value on each direction of
1160         // the branch.
1161         Node& child = m_graph[node.child1()];
1162         if (child.shouldSpeculateBoolean())
1163             speculateBooleanUnary(node);
1164         else if (child.shouldSpeculateNonStringCellOrOther()) {
1165             node.setCanExit(true);
1166             forNode(node.child1()).filter((SpecCell & ~SpecString) | SpecOther);
1167         } else if (child.shouldSpeculateInteger())
1168             speculateInt32Unary(node);
1169         else if (child.shouldSpeculateNumber())
1170             speculateNumberUnary(node);
1171         else
1172             node.setCanExit(false);
1173         m_branchDirection = TakeBoth;
1174         break;
1175     }
1176             
1177     case Return:
1178         m_isValid = false;
1179         node.setCanExit(false);
1180         break;
1181         
1182     case Throw:
1183     case ThrowReferenceError:
1184         m_isValid = false;
1185         node.setCanExit(true);
1186         break;
1187             
1188     case ToPrimitive: {
1189         JSValue childConst = forNode(node.child1()).value();
1190         if (childConst && childConst.isNumber() && trySetConstant(nodeIndex, childConst)) {
1191             m_foundConstants = true;
1192             node.setCanExit(false);
1193             break;
1194         }
1195         
1196         Node& child = m_graph[node.child1()];
1197         if (child.shouldSpeculateInteger()) {
1198             speculateInt32Unary(node);
1199             forNode(nodeIndex).set(SpecInt32);
1200             break;
1201         }
1202
1203         AbstractValue& source = forNode(node.child1());
1204         AbstractValue& destination = forNode(nodeIndex);
1205             
1206         SpeculatedType type = source.m_type;
1207         if (type & ~(SpecNumber | SpecString | SpecBoolean)) {
1208             type &= (SpecNumber | SpecString | SpecBoolean);
1209             type |= SpecString;
1210         }
1211         destination.set(type);
1212         node.setCanExit(false);
1213         break;
1214     }
1215             
1216     case StrCat:
1217         node.setCanExit(false);
1218         forNode(nodeIndex).set(SpecString);
1219         break;
1220             
1221     case NewArray:
1222         node.setCanExit(true);
1223         forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()));
1224         m_haveStructures = true;
1225         break;
1226         
1227     case NewArrayBuffer:
1228         node.setCanExit(true);
1229         forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->arrayStructureForIndexingTypeDuringAllocation(node.indexingType()));
1230         m_haveStructures = true;
1231         break;
1232
1233     case NewArrayWithSize:
1234         node.setCanExit(true);
1235         forNode(node.child1()).filter(SpecInt32);
1236         forNode(nodeIndex).set(SpecArray);
1237         m_haveStructures = true;
1238         break;
1239             
1240     case NewRegexp:
1241         node.setCanExit(false);
1242         forNode(nodeIndex).set(m_graph.globalObjectFor(node.codeOrigin)->regExpStructure());
1243         m_haveStructures = true;
1244         break;
1245             
1246     case ConvertThis: {
1247         Node& child = m_graph[node.child1()];
1248         AbstractValue& source = forNode(node.child1());
1249         AbstractValue& destination = forNode(nodeIndex);
1250             
1251         if (isObjectSpeculation(source.m_type)) {
1252             // This is the simple case. We already know that the source is an
1253             // object, so there's nothing to do. I don't think this case will
1254             // be hit, but then again, you never know.
1255             destination = source;
1256             node.setCanExit(false);
1257             m_foundConstants = true; // Tell the constant folder to turn this into Identity.
1258             break;
1259         }
1260         
1261         node.setCanExit(true);
1262         
1263         if (isOtherSpeculation(child.prediction())) {
1264             source.filter(SpecOther);
1265             destination.set(SpecObjectOther);
1266             break;
1267         }
1268         
1269         if (isObjectSpeculation(child.prediction())) {
1270             source.filter(SpecObjectMask);
1271             destination = source;
1272             break;
1273         }
1274             
1275         destination = source;
1276         destination.merge(SpecObjectOther);
1277         break;
1278     }
1279
1280     case CreateThis: {
1281         AbstractValue& source = forNode(node.child1());
1282         AbstractValue& destination = forNode(nodeIndex);
1283         
1284         node.setCanExit(!isCellSpeculation(source.m_type));
1285             
1286         source.filter(SpecFunction);
1287         destination.set(SpecFinalObject);
1288         break;
1289     }
1290         
1291     case InheritorIDWatchpoint:
1292         node.setCanExit(true);
1293         break;
1294
1295     case NewObject:
1296         node.setCanExit(false);
1297         forNode(nodeIndex).set(node.structure());
1298         m_haveStructures = true;
1299         break;
1300         
1301     case CreateActivation:
1302         node.setCanExit(false);
1303         forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->activationStructure());
1304         m_haveStructures = true;
1305         break;
1306         
1307     case CreateArguments:
1308         node.setCanExit(false);
1309         forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->argumentsStructure());
1310         m_haveStructures = true;
1311         break;
1312         
1313     case TearOffActivation:
1314     case TearOffArguments:
1315         node.setCanExit(false);
1316         // Does nothing that is user-visible.
1317         break;
1318
1319     case CheckArgumentsNotCreated:
1320         if (isEmptySpeculation(
1321                 m_variables.operand(
1322                     m_graph.argumentsRegisterFor(node.codeOrigin)).m_type)) {
1323             node.setCanExit(false);
1324             m_foundConstants = true;
1325         } else
1326             node.setCanExit(true);
1327         break;
1328         
1329     case GetMyArgumentsLength:
1330         // We know that this executable does not escape its arguments, so we can optimize
1331         // the arguments a bit. Note that this is not sufficient to force constant folding
1332         // of GetMyArgumentsLength, because GetMyArgumentsLength is a clobbering operation.
1333         // We perform further optimizations on this later on.
1334         if (node.codeOrigin.inlineCallFrame)
1335             forNode(nodeIndex).set(jsNumber(node.codeOrigin.inlineCallFrame->arguments.size() - 1));
1336         else
1337             forNode(nodeIndex).set(SpecInt32);
1338         node.setCanExit(
1339             !isEmptySpeculation(
1340                 m_variables.operand(
1341                     m_graph.argumentsRegisterFor(node.codeOrigin)).m_type));
1342         break;
1343         
1344     case GetMyArgumentsLengthSafe:
1345         node.setCanExit(false);
1346         // This potentially clobbers all structures if the arguments object had a getter
1347         // installed on the length property.
1348         clobberWorld(node.codeOrigin, indexInBlock);
1349         // We currently make no guarantee about what this returns because it does not
1350         // speculate that the length property is actually a length.
1351         forNode(nodeIndex).makeTop();
1352         break;
1353         
1354     case GetMyArgumentByVal:
1355         node.setCanExit(true);
1356         // We know that this executable does not escape its arguments, so we can optimize
1357         // the arguments a bit. Note that this ends up being further optimized by the
1358         // ArgumentsSimplificationPhase.
1359         forNode(node.child1()).filter(SpecInt32);
1360         forNode(nodeIndex).makeTop();
1361         break;
1362         
1363     case GetMyArgumentByValSafe:
1364         node.setCanExit(true);
1365         // This potentially clobbers all structures if the property we're accessing has
1366         // a getter. We don't speculate against this.
1367         clobberWorld(node.codeOrigin, indexInBlock);
1368         // But we do speculate that the index is an integer.
1369         forNode(node.child1()).filter(SpecInt32);
1370         // And the result is unknown.
1371         forNode(nodeIndex).makeTop();
1372         break;
1373         
1374     case NewFunction:
1375     case NewFunctionExpression:
1376     case NewFunctionNoCheck:
1377         node.setCanExit(false);
1378         forNode(nodeIndex).set(m_codeBlock->globalObjectFor(node.codeOrigin)->functionStructure());
1379         break;
1380         
1381     case GetCallee:
1382         node.setCanExit(false);
1383         forNode(nodeIndex).set(SpecFunction);
1384         break;
1385             
1386     case GetScope:
1387         node.setCanExit(false);
1388         forNode(nodeIndex).set(SpecCellOther);
1389         break;
1390
1391     case GetScopeRegisters:
1392         node.setCanExit(false);
1393         forNode(node.child1()).filter(SpecCell);
1394         forNode(nodeIndex).clear(); // The result is not a JS value.
1395         break;
1396
1397     case GetScopedVar:
1398         node.setCanExit(false);
1399         forNode(nodeIndex).makeTop();
1400         break;
1401             
1402     case PutScopedVar:
1403         node.setCanExit(false);
1404         clobberCapturedVars(node.codeOrigin);
1405         break;
1406             
1407     case GetById:
1408     case GetByIdFlush:
1409         node.setCanExit(true);
1410         if (!node.prediction()) {
1411             m_isValid = false;
1412             break;
1413         }
1414         if (isCellSpeculation(m_graph[node.child1()].prediction())) {
1415             forNode(node.child1()).filter(SpecCell);
1416
1417             if (Structure* structure = forNode(node.child1()).bestProvenStructure()) {
1418                 GetByIdStatus status = GetByIdStatus::computeFor(
1419                     m_graph.m_globalData, structure,
1420                     m_graph.m_codeBlock->identifier(node.identifierNumber()));
1421                 if (status.isSimple()) {
1422                     // Assert things that we can't handle and that the computeFor() method
1423                     // above won't be able to return.
1424                     ASSERT(status.structureSet().size() == 1);
1425                     ASSERT(status.chain().isEmpty());
1426                     
1427                     if (status.specificValue())
1428                         forNode(nodeIndex).set(status.specificValue());
1429                     else
1430                         forNode(nodeIndex).makeTop();
1431                     forNode(node.child1()).filter(status.structureSet());
1432                     
1433                     m_foundConstants = true;
1434                     break;
1435                 }
1436             }
1437         }
1438         clobberWorld(node.codeOrigin, indexInBlock);
1439         forNode(nodeIndex).makeTop();
1440         break;
1441             
1442     case GetArrayLength:
1443         node.setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
1444         forNode(nodeIndex).set(SpecInt32);
1445         break;
1446
1447     case CheckStructure:
1448     case ForwardCheckStructure: {
1449         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1450         AbstractValue& value = forNode(node.child1());
1451         // If this structure check is attempting to prove knowledge already held in
1452         // the futurePossibleStructure set then the constant folding phase should
1453         // turn this into a watchpoint instead.
1454         StructureSet& set = node.structureSet();
1455         if (value.m_futurePossibleStructure.isSubsetOf(set)
1456             || value.m_currentKnownStructure.isSubsetOf(set))
1457             m_foundConstants = true;
1458         node.setCanExit(
1459             !value.m_currentKnownStructure.isSubsetOf(set)
1460             || !isCellSpeculation(value.m_type));
1461         value.filter(set);
1462         m_haveStructures = true;
1463         break;
1464     }
1465         
1466     case StructureTransitionWatchpoint:
1467     case ForwardStructureTransitionWatchpoint: {
1468         AbstractValue& value = forNode(node.child1());
1469
1470         // It's only valid to issue a structure transition watchpoint if we already
1471         // know that the watchpoint covers a superset of the structures known to
1472         // belong to the set of future structures that this value may have.
1473         // Currently, we only issue singleton watchpoints (that check one structure)
1474         // and our futurePossibleStructure set can only contain zero, one, or an
1475         // infinity of structures.
1476         ASSERT(value.m_futurePossibleStructure.isSubsetOf(StructureSet(node.structure())));
1477         
1478         ASSERT(value.isClear() || isCellSpeculation(value.m_type)); // Value could be clear if we've proven must-exit due to a speculation statically known to be bad.
1479         value.filter(node.structure());
1480         m_haveStructures = true;
1481         node.setCanExit(true);
1482         break;
1483     }
1484             
1485     case PutStructure:
1486     case PhantomPutStructure:
1487         node.setCanExit(false);
1488         if (!forNode(node.child1()).m_currentKnownStructure.isClear()) {
1489             clobberStructures(indexInBlock);
1490             forNode(node.child1()).set(node.structureTransitionData().newStructure);
1491             m_haveStructures = true;
1492         }
1493         break;
1494     case GetButterfly:
1495     case AllocatePropertyStorage:
1496     case ReallocatePropertyStorage:
1497         node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
1498         forNode(node.child1()).filter(SpecCell);
1499         forNode(nodeIndex).clear(); // The result is not a JS value.
1500         break;
1501     case CheckArray: {
1502         if (node.arrayMode().alreadyChecked(m_graph, node, forNode(node.child1()))) {
1503             m_foundConstants = true;
1504             node.setCanExit(false);
1505             break;
1506         }
1507         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.
1508         switch (node.arrayMode().type()) {
1509         case Array::String:
1510             forNode(node.child1()).filter(SpecString);
1511             break;
1512         case Array::Int32:
1513         case Array::Double:
1514         case Array::Contiguous:
1515         case Array::ArrayStorage:
1516         case Array::SlowPutArrayStorage:
1517             forNode(node.child1()).filter(SpecCell);
1518             break;
1519         case Array::Arguments:
1520             forNode(node.child1()).filter(SpecArguments);
1521             break;
1522         case Array::Int8Array:
1523             forNode(node.child1()).filter(SpecInt8Array);
1524             break;
1525         case Array::Int16Array:
1526             forNode(node.child1()).filter(SpecInt16Array);
1527             break;
1528         case Array::Int32Array:
1529             forNode(node.child1()).filter(SpecInt32Array);
1530             break;
1531         case Array::Uint8Array:
1532             forNode(node.child1()).filter(SpecUint8Array);
1533             break;
1534         case Array::Uint8ClampedArray:
1535             forNode(node.child1()).filter(SpecUint8ClampedArray);
1536             break;
1537         case Array::Uint16Array:
1538             forNode(node.child1()).filter(SpecUint16Array);
1539             break;
1540         case Array::Uint32Array:
1541             forNode(node.child1()).filter(SpecUint32Array);
1542             break;
1543         case Array::Float32Array:
1544             forNode(node.child1()).filter(SpecFloat32Array);
1545             break;
1546         case Array::Float64Array:
1547             forNode(node.child1()).filter(SpecFloat64Array);
1548             break;
1549         default:
1550             ASSERT_NOT_REACHED();
1551             break;
1552         }
1553         forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
1554         m_haveStructures = true;
1555         break;
1556     }
1557     case Arrayify: {
1558         if (node.arrayMode().alreadyChecked(m_graph, node, forNode(node.child1()))) {
1559             m_foundConstants = true;
1560             node.setCanExit(false);
1561             break;
1562         }
1563         ASSERT(node.arrayMode().conversion() == Array::Convert);
1564         node.setCanExit(true);
1565         forNode(node.child1()).filter(SpecCell);
1566         if (node.child2())
1567             forNode(node.child2()).filter(SpecInt32);
1568         clobberStructures(indexInBlock);
1569         forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
1570         m_haveStructures = true;
1571         break;
1572     }
1573     case ArrayifyToStructure: {
1574         AbstractValue& value = forNode(node.child1());
1575         StructureSet set = node.structure();
1576         if (value.m_futurePossibleStructure.isSubsetOf(set)
1577             || value.m_currentKnownStructure.isSubsetOf(set))
1578             m_foundConstants = true;
1579         node.setCanExit(true);
1580         clobberStructures(indexInBlock);
1581         value.filter(set);
1582         m_haveStructures = true;
1583         break;
1584     }
1585     case GetIndexedPropertyStorage: {
1586         switch (node.arrayMode().type()) {
1587         case Array::String:
1588             // Strings are weird - we may spec fail if the string was a rope. That is of course
1589             // stupid, and we should fix that, but for now let's at least be honest about it.
1590             node.setCanExit(true);
1591             break;
1592         default:
1593             node.setCanExit(false);
1594             break;
1595         }
1596         forNode(nodeIndex).clear();
1597         break; 
1598     }
1599     case GetByOffset:
1600         if (!m_graph[node.child1()].hasStorageResult()) {
1601             node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
1602             forNode(node.child1()).filter(SpecCell);
1603         }
1604         forNode(nodeIndex).makeTop();
1605         break;
1606             
1607     case PutByOffset: {
1608         bool canExit = false;
1609         if (!m_graph[node.child1()].hasStorageResult()) {
1610             canExit |= !isCellSpeculation(forNode(node.child1()).m_type);
1611             forNode(node.child1()).filter(SpecCell);
1612         }
1613         canExit |= !isCellSpeculation(forNode(node.child2()).m_type);
1614         forNode(node.child2()).filter(SpecCell);
1615         node.setCanExit(canExit);
1616         break;
1617     }
1618             
1619     case CheckFunction: {
1620         JSValue value = forNode(node.child1()).value();
1621         if (value == node.function()) {
1622             m_foundConstants = true;
1623             ASSERT(value);
1624             node.setCanExit(false);
1625             break;
1626         }
1627         
1628         node.setCanExit(true); // Lies! We can do better.
1629         if (!forNode(node.child1()).filterByValue(node.function())) {
1630             m_isValid = false;
1631             break;
1632         }
1633         break;
1634     }
1635         
1636     case PutById:
1637     case PutByIdDirect:
1638         node.setCanExit(true);
1639         if (Structure* structure = forNode(node.child1()).bestProvenStructure()) {
1640             PutByIdStatus status = PutByIdStatus::computeFor(
1641                 m_graph.m_globalData,
1642                 m_graph.globalObjectFor(node.codeOrigin),
1643                 structure,
1644                 m_graph.m_codeBlock->identifier(node.identifierNumber()),
1645                 node.op() == PutByIdDirect);
1646             if (status.isSimpleReplace()) {
1647                 forNode(node.child1()).filter(structure);
1648                 m_foundConstants = true;
1649                 break;
1650             }
1651             if (status.isSimpleTransition()) {
1652                 clobberStructures(indexInBlock);
1653                 forNode(node.child1()).set(status.newStructure());
1654                 m_haveStructures = true;
1655                 m_foundConstants = true;
1656                 break;
1657             }
1658         }
1659         forNode(node.child1()).filter(SpecCell);
1660         clobberWorld(node.codeOrigin, indexInBlock);
1661         break;
1662             
1663     case GetGlobalVar:
1664         node.setCanExit(false);
1665         forNode(nodeIndex).makeTop();
1666         break;
1667         
1668     case GlobalVarWatchpoint:
1669         node.setCanExit(true);
1670         break;
1671             
1672     case PutGlobalVar:
1673     case PutGlobalVarCheck:
1674         node.setCanExit(false);
1675         break;
1676             
1677     case CheckHasInstance:
1678         node.setCanExit(true);
1679         forNode(node.child1()).filter(SpecCell);
1680         // Sadly, we don't propagate the fact that we've done CheckHasInstance
1681         break;
1682             
1683     case InstanceOf:
1684         node.setCanExit(true);
1685         // Again, sadly, we don't propagate the fact that we've done InstanceOf
1686         if (!(m_graph[node.child1()].prediction() & ~SpecCell) && !(forNode(node.child1()).m_type & ~SpecCell))
1687             forNode(node.child1()).filter(SpecCell);
1688         forNode(node.child2()).filter(SpecCell);
1689         forNode(nodeIndex).set(SpecBoolean);
1690         break;
1691             
1692     case Phi:
1693     case Flush:
1694         node.setCanExit(false);
1695         break;
1696             
1697     case Breakpoint:
1698         node.setCanExit(false);
1699         break;
1700             
1701     case Call:
1702     case Construct:
1703     case Resolve:
1704     case ResolveBase:
1705     case ResolveBaseStrictPut:
1706     case ResolveGlobal:
1707         node.setCanExit(true);
1708         clobberWorld(node.codeOrigin, indexInBlock);
1709         forNode(nodeIndex).makeTop();
1710         break;
1711
1712     case GarbageValue:
1713         clobberWorld(node.codeOrigin, indexInBlock);
1714         forNode(nodeIndex).makeTop();
1715         break;
1716
1717     case ForceOSRExit:
1718         node.setCanExit(true);
1719         m_isValid = false;
1720         break;
1721             
1722     case Phantom:
1723     case InlineStart:
1724     case Nop:
1725         node.setCanExit(false);
1726         break;
1727         
1728     case LastNodeType:
1729         ASSERT_NOT_REACHED();
1730         break;
1731     }
1732     
1733     return m_isValid;
1734 }
1735
1736 inline void AbstractState::clobberWorld(const CodeOrigin& codeOrigin, unsigned indexInBlock)
1737 {
1738     clobberCapturedVars(codeOrigin);
1739     clobberStructures(indexInBlock);
1740 }
1741
1742 inline void AbstractState::clobberCapturedVars(const CodeOrigin& codeOrigin)
1743 {
1744     if (codeOrigin.inlineCallFrame) {
1745         const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
1746         for (size_t i = capturedVars.size(); i--;) {
1747             if (!capturedVars.quickGet(i))
1748                 continue;
1749             m_variables.local(i).makeTop();
1750         }
1751     } else {
1752         for (size_t i = m_codeBlock->m_numVars; i--;) {
1753             if (m_codeBlock->isCaptured(i))
1754                 m_variables.local(i).makeTop();
1755         }
1756     }
1757
1758     for (size_t i = m_variables.numberOfArguments(); i--;) {
1759         if (m_codeBlock->isCaptured(argumentToOperand(i)))
1760             m_variables.argument(i).makeTop();
1761     }
1762 }
1763
1764 inline void AbstractState::clobberStructures(unsigned indexInBlock)
1765 {
1766     if (!m_haveStructures)
1767         return;
1768     for (size_t i = indexInBlock + 1; i--;)
1769         forNode(m_block->at(i)).clobberStructures();
1770     for (size_t i = m_variables.numberOfArguments(); i--;)
1771         m_variables.argument(i).clobberStructures();
1772     for (size_t i = m_variables.numberOfLocals(); i--;)
1773         m_variables.local(i).clobberStructures();
1774     m_haveStructures = false;
1775     m_didClobber = true;
1776 }
1777
1778 inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex nodeIndex)
1779 {
1780     if (nodeIndex == NoNode)
1781         return false;
1782         
1783     AbstractValue source;
1784         
1785     Node& node = m_graph[nodeIndex];
1786     if (!node.refCount())
1787         return false;
1788     
1789 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1790     dataLogF("          It's live, node @%u.\n", nodeIndex);
1791 #endif
1792     
1793     if (node.variableAccessData()->isCaptured()) {
1794         source = inVariable;
1795 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1796         dataLogF("          Transfering ");
1797         source.dump(WTF::dataFile());
1798         dataLogF(" from last access due to captured variable.\n");
1799 #endif
1800     } else {
1801         switch (node.op()) {
1802         case Phi:
1803         case SetArgument:
1804         case Flush:
1805             // The block transfers the value from head to tail.
1806             source = inVariable;
1807 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1808             dataLogF("          Transfering ");
1809             source.dump(WTF::dataFile());
1810             dataLogF(" from head to tail.\n");
1811 #endif
1812             break;
1813             
1814         case GetLocal:
1815             // The block refines the value with additional speculations.
1816             source = forNode(nodeIndex);
1817 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1818             dataLogF("          Refining to ");
1819             source.dump(WTF::dataFile());
1820             dataLogF("\n");
1821 #endif
1822             break;
1823             
1824         case SetLocal:
1825             // The block sets the variable, and potentially refines it, both
1826             // before and after setting it.
1827             if (node.variableAccessData()->shouldUseDoubleFormat()) {
1828                 // FIXME: This unnecessarily loses precision.
1829                 source.set(SpecDouble);
1830             } else
1831                 source = forNode(node.child1());
1832 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1833             dataLogF("          Setting to ");
1834             source.dump(WTF::dataFile());
1835             dataLogF("\n");
1836 #endif
1837             break;
1838         
1839         default:
1840             ASSERT_NOT_REACHED();
1841             break;
1842         }
1843     }
1844     
1845     if (destination == source) {
1846         // Abstract execution did not change the output value of the variable, for this
1847         // basic block, on this iteration.
1848 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1849         dataLogF("          Not changed!\n");
1850 #endif
1851         return false;
1852     }
1853     
1854     // Abstract execution reached a new conclusion about the speculations reached about
1855     // this variable after execution of this basic block. Update the state, and return
1856     // true to indicate that the fixpoint must go on!
1857     destination = source;
1858 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1859     dataLogF("          Changed!\n");
1860 #endif
1861     return true;
1862 }
1863
1864 inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to)
1865 {
1866     ASSERT(from->variablesAtTail.numberOfArguments() == to->variablesAtHead.numberOfArguments());
1867     ASSERT(from->variablesAtTail.numberOfLocals() == to->variablesAtHead.numberOfLocals());
1868     
1869     bool changed = false;
1870     
1871     for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) {
1872         AbstractValue& destination = to->valuesAtHead.argument(argument);
1873         changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument));
1874     }
1875     
1876     for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) {
1877         AbstractValue& destination = to->valuesAtHead.local(local);
1878         changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local));
1879     }
1880
1881     if (!to->cfaHasVisited)
1882         changed = true;
1883     
1884     to->cfaShouldRevisit |= changed;
1885     
1886     return changed;
1887 }
1888
1889 inline bool AbstractState::mergeToSuccessors(
1890     Graph& graph, BasicBlock* basicBlock)
1891 {
1892     Node& terminal = graph[basicBlock->last()];
1893     
1894     ASSERT(terminal.isTerminal());
1895     
1896     switch (terminal.op()) {
1897     case Jump: {
1898         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
1899 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1900         dataLogF("        Merging to block #%u.\n", terminal.takenBlockIndex());
1901 #endif
1902         return merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get());
1903     }
1904         
1905     case Branch: {
1906         ASSERT(basicBlock->cfaBranchDirection != InvalidBranchDirection);
1907         bool changed = false;
1908 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1909         dataLogF("        Merging to block #%u.\n", terminal.takenBlockIndex());
1910 #endif
1911         if (basicBlock->cfaBranchDirection != TakeFalse)
1912             changed |= merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get());
1913 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1914         dataLogF("        Merging to block #%u.\n", terminal.notTakenBlockIndex());
1915 #endif
1916         if (basicBlock->cfaBranchDirection != TakeTrue)
1917             changed |= merge(basicBlock, graph.m_blocks[terminal.notTakenBlockIndex()].get());
1918         return changed;
1919     }
1920         
1921     case Return:
1922     case Throw:
1923     case ThrowReferenceError:
1924         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
1925         return false;
1926         
1927     default:
1928         ASSERT_NOT_REACHED();
1929         return false;
1930     }
1931 }
1932
1933 inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, NodeIndex destinationNodeIndex, NodeIndex sourceNodeIndex)
1934 {
1935     if (destinationNodeIndex == NoNode)
1936         return false;
1937     
1938     ASSERT_UNUSED(sourceNodeIndex, sourceNodeIndex != NoNode);
1939     
1940     // FIXME: We could do some sparse conditional propagation here!
1941     
1942     return destination.merge(source);
1943 }
1944
1945 void AbstractState::dump(FILE* out)
1946 {
1947     bool first = true;
1948     for (size_t i = 0; i < m_block->size(); ++i) {
1949         NodeIndex index = m_block->at(i);
1950         AbstractValue& value = m_nodes[index];
1951         if (value.isClear())
1952             continue;
1953         if (first)
1954             first = false;
1955         else
1956             fprintf(out, " ");
1957         fprintf(out, "@%lu:", static_cast<unsigned long>(index));
1958         value.dump(out);
1959     }
1960 }
1961
1962 } } // namespace JSC::DFG
1963
1964 #endif // ENABLE(DFG_JIT)
1965