DFG should inline code blocks that use scoped variable access
[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 GetMyScope:
1387     case SkipTopScope:
1388         node.setCanExit(false);
1389         forNode(nodeIndex).set(SpecCellOther);
1390         break;
1391
1392     case SkipScope: {
1393         node.setCanExit(false);
1394         JSValue child = forNode(node.child1()).value();
1395         if (child && trySetConstant(nodeIndex, JSValue(jsCast<JSScope*>(child.asCell())->next()))) {
1396             m_foundConstants = true;
1397             break;
1398         }
1399         forNode(nodeIndex).set(SpecCellOther);
1400         break;
1401     }
1402
1403     case GetScopeRegisters:
1404         node.setCanExit(false);
1405         forNode(node.child1()).filter(SpecCell);
1406         forNode(nodeIndex).clear(); // The result is not a JS value.
1407         break;
1408
1409     case GetScopedVar:
1410         node.setCanExit(false);
1411         forNode(nodeIndex).makeTop();
1412         break;
1413             
1414     case PutScopedVar:
1415         node.setCanExit(false);
1416         clobberCapturedVars(node.codeOrigin);
1417         break;
1418             
1419     case GetById:
1420     case GetByIdFlush:
1421         node.setCanExit(true);
1422         if (!node.prediction()) {
1423             m_isValid = false;
1424             break;
1425         }
1426         if (isCellSpeculation(m_graph[node.child1()].prediction())) {
1427             forNode(node.child1()).filter(SpecCell);
1428
1429             if (Structure* structure = forNode(node.child1()).bestProvenStructure()) {
1430                 GetByIdStatus status = GetByIdStatus::computeFor(
1431                     m_graph.m_globalData, structure,
1432                     m_graph.m_codeBlock->identifier(node.identifierNumber()));
1433                 if (status.isSimple()) {
1434                     // Assert things that we can't handle and that the computeFor() method
1435                     // above won't be able to return.
1436                     ASSERT(status.structureSet().size() == 1);
1437                     ASSERT(status.chain().isEmpty());
1438                     
1439                     if (status.specificValue())
1440                         forNode(nodeIndex).set(status.specificValue());
1441                     else
1442                         forNode(nodeIndex).makeTop();
1443                     forNode(node.child1()).filter(status.structureSet());
1444                     
1445                     m_foundConstants = true;
1446                     break;
1447                 }
1448             }
1449         }
1450         clobberWorld(node.codeOrigin, indexInBlock);
1451         forNode(nodeIndex).makeTop();
1452         break;
1453             
1454     case GetArrayLength:
1455         node.setCanExit(true); // Lies, but it's true for the common case of JSArray, so it's good enough.
1456         forNode(nodeIndex).set(SpecInt32);
1457         break;
1458
1459     case CheckStructure:
1460     case ForwardCheckStructure: {
1461         // FIXME: We should be able to propagate the structure sets of constants (i.e. prototypes).
1462         AbstractValue& value = forNode(node.child1());
1463         // If this structure check is attempting to prove knowledge already held in
1464         // the futurePossibleStructure set then the constant folding phase should
1465         // turn this into a watchpoint instead.
1466         StructureSet& set = node.structureSet();
1467         if (value.m_futurePossibleStructure.isSubsetOf(set)
1468             || value.m_currentKnownStructure.isSubsetOf(set))
1469             m_foundConstants = true;
1470         node.setCanExit(
1471             !value.m_currentKnownStructure.isSubsetOf(set)
1472             || !isCellSpeculation(value.m_type));
1473         value.filter(set);
1474         m_haveStructures = true;
1475         break;
1476     }
1477         
1478     case StructureTransitionWatchpoint:
1479     case ForwardStructureTransitionWatchpoint: {
1480         AbstractValue& value = forNode(node.child1());
1481
1482         // It's only valid to issue a structure transition watchpoint if we already
1483         // know that the watchpoint covers a superset of the structures known to
1484         // belong to the set of future structures that this value may have.
1485         // Currently, we only issue singleton watchpoints (that check one structure)
1486         // and our futurePossibleStructure set can only contain zero, one, or an
1487         // infinity of structures.
1488         ASSERT(value.m_futurePossibleStructure.isSubsetOf(StructureSet(node.structure())));
1489         
1490         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.
1491         value.filter(node.structure());
1492         m_haveStructures = true;
1493         node.setCanExit(true);
1494         break;
1495     }
1496             
1497     case PutStructure:
1498     case PhantomPutStructure:
1499         node.setCanExit(false);
1500         if (!forNode(node.child1()).m_currentKnownStructure.isClear()) {
1501             clobberStructures(indexInBlock);
1502             forNode(node.child1()).set(node.structureTransitionData().newStructure);
1503             m_haveStructures = true;
1504         }
1505         break;
1506     case GetButterfly:
1507     case AllocatePropertyStorage:
1508     case ReallocatePropertyStorage:
1509         node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
1510         forNode(node.child1()).filter(SpecCell);
1511         forNode(nodeIndex).clear(); // The result is not a JS value.
1512         break;
1513     case CheckArray: {
1514         if (node.arrayMode().alreadyChecked(m_graph, node, forNode(node.child1()))) {
1515             m_foundConstants = true;
1516             node.setCanExit(false);
1517             break;
1518         }
1519         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.
1520         switch (node.arrayMode().type()) {
1521         case Array::String:
1522             forNode(node.child1()).filter(SpecString);
1523             break;
1524         case Array::Int32:
1525         case Array::Double:
1526         case Array::Contiguous:
1527         case Array::ArrayStorage:
1528         case Array::SlowPutArrayStorage:
1529             forNode(node.child1()).filter(SpecCell);
1530             break;
1531         case Array::Arguments:
1532             forNode(node.child1()).filter(SpecArguments);
1533             break;
1534         case Array::Int8Array:
1535             forNode(node.child1()).filter(SpecInt8Array);
1536             break;
1537         case Array::Int16Array:
1538             forNode(node.child1()).filter(SpecInt16Array);
1539             break;
1540         case Array::Int32Array:
1541             forNode(node.child1()).filter(SpecInt32Array);
1542             break;
1543         case Array::Uint8Array:
1544             forNode(node.child1()).filter(SpecUint8Array);
1545             break;
1546         case Array::Uint8ClampedArray:
1547             forNode(node.child1()).filter(SpecUint8ClampedArray);
1548             break;
1549         case Array::Uint16Array:
1550             forNode(node.child1()).filter(SpecUint16Array);
1551             break;
1552         case Array::Uint32Array:
1553             forNode(node.child1()).filter(SpecUint32Array);
1554             break;
1555         case Array::Float32Array:
1556             forNode(node.child1()).filter(SpecFloat32Array);
1557             break;
1558         case Array::Float64Array:
1559             forNode(node.child1()).filter(SpecFloat64Array);
1560             break;
1561         default:
1562             ASSERT_NOT_REACHED();
1563             break;
1564         }
1565         forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
1566         m_haveStructures = true;
1567         break;
1568     }
1569     case Arrayify: {
1570         if (node.arrayMode().alreadyChecked(m_graph, node, forNode(node.child1()))) {
1571             m_foundConstants = true;
1572             node.setCanExit(false);
1573             break;
1574         }
1575         ASSERT(node.arrayMode().conversion() == Array::Convert
1576             || node.arrayMode().conversion() == Array::RageConvert);
1577         node.setCanExit(true);
1578         forNode(node.child1()).filter(SpecCell);
1579         if (node.child2())
1580             forNode(node.child2()).filter(SpecInt32);
1581         clobberStructures(indexInBlock);
1582         forNode(node.child1()).filterArrayModes(node.arrayMode().arrayModesThatPassFiltering());
1583         m_haveStructures = true;
1584         break;
1585     }
1586     case ArrayifyToStructure: {
1587         AbstractValue& value = forNode(node.child1());
1588         StructureSet set = node.structure();
1589         if (value.m_futurePossibleStructure.isSubsetOf(set)
1590             || value.m_currentKnownStructure.isSubsetOf(set))
1591             m_foundConstants = true;
1592         node.setCanExit(true);
1593         clobberStructures(indexInBlock);
1594         value.filter(set);
1595         m_haveStructures = true;
1596         break;
1597     }
1598     case GetIndexedPropertyStorage: {
1599         switch (node.arrayMode().type()) {
1600         case Array::String:
1601             // Strings are weird - we may spec fail if the string was a rope. That is of course
1602             // stupid, and we should fix that, but for now let's at least be honest about it.
1603             node.setCanExit(true);
1604             break;
1605         default:
1606             node.setCanExit(false);
1607             break;
1608         }
1609         forNode(nodeIndex).clear();
1610         break; 
1611     }
1612     case GetByOffset:
1613         if (!m_graph[node.child1()].hasStorageResult()) {
1614             node.setCanExit(!isCellSpeculation(forNode(node.child1()).m_type));
1615             forNode(node.child1()).filter(SpecCell);
1616         }
1617         forNode(nodeIndex).makeTop();
1618         break;
1619             
1620     case PutByOffset: {
1621         bool canExit = false;
1622         if (!m_graph[node.child1()].hasStorageResult()) {
1623             canExit |= !isCellSpeculation(forNode(node.child1()).m_type);
1624             forNode(node.child1()).filter(SpecCell);
1625         }
1626         canExit |= !isCellSpeculation(forNode(node.child2()).m_type);
1627         forNode(node.child2()).filter(SpecCell);
1628         node.setCanExit(canExit);
1629         break;
1630     }
1631             
1632     case CheckFunction: {
1633         JSValue value = forNode(node.child1()).value();
1634         if (value == node.function()) {
1635             m_foundConstants = true;
1636             ASSERT(value);
1637             node.setCanExit(false);
1638             break;
1639         }
1640         
1641         node.setCanExit(true); // Lies! We can do better.
1642         if (!forNode(node.child1()).filterByValue(node.function())) {
1643             m_isValid = false;
1644             break;
1645         }
1646         break;
1647     }
1648         
1649     case PutById:
1650     case PutByIdDirect:
1651         node.setCanExit(true);
1652         if (Structure* structure = forNode(node.child1()).bestProvenStructure()) {
1653             PutByIdStatus status = PutByIdStatus::computeFor(
1654                 m_graph.m_globalData,
1655                 m_graph.globalObjectFor(node.codeOrigin),
1656                 structure,
1657                 m_graph.m_codeBlock->identifier(node.identifierNumber()),
1658                 node.op() == PutByIdDirect);
1659             if (status.isSimpleReplace()) {
1660                 forNode(node.child1()).filter(structure);
1661                 m_foundConstants = true;
1662                 break;
1663             }
1664             if (status.isSimpleTransition()) {
1665                 clobberStructures(indexInBlock);
1666                 forNode(node.child1()).set(status.newStructure());
1667                 m_haveStructures = true;
1668                 m_foundConstants = true;
1669                 break;
1670             }
1671         }
1672         forNode(node.child1()).filter(SpecCell);
1673         clobberWorld(node.codeOrigin, indexInBlock);
1674         break;
1675             
1676     case GetGlobalVar:
1677         node.setCanExit(false);
1678         forNode(nodeIndex).makeTop();
1679         break;
1680         
1681     case GlobalVarWatchpoint:
1682         node.setCanExit(true);
1683         break;
1684             
1685     case PutGlobalVar:
1686     case PutGlobalVarCheck:
1687         node.setCanExit(false);
1688         break;
1689             
1690     case CheckHasInstance:
1691         node.setCanExit(true);
1692         forNode(node.child1()).filter(SpecCell);
1693         // Sadly, we don't propagate the fact that we've done CheckHasInstance
1694         break;
1695             
1696     case InstanceOf:
1697         node.setCanExit(true);
1698         // Again, sadly, we don't propagate the fact that we've done InstanceOf
1699         if (!(m_graph[node.child1()].prediction() & ~SpecCell) && !(forNode(node.child1()).m_type & ~SpecCell))
1700             forNode(node.child1()).filter(SpecCell);
1701         forNode(node.child2()).filter(SpecCell);
1702         forNode(nodeIndex).set(SpecBoolean);
1703         break;
1704             
1705     case Phi:
1706     case Flush:
1707         node.setCanExit(false);
1708         break;
1709             
1710     case Breakpoint:
1711         node.setCanExit(false);
1712         break;
1713             
1714     case Call:
1715     case Construct:
1716     case Resolve:
1717     case ResolveBase:
1718     case ResolveBaseStrictPut:
1719     case ResolveGlobal:
1720         node.setCanExit(true);
1721         clobberWorld(node.codeOrigin, indexInBlock);
1722         forNode(nodeIndex).makeTop();
1723         break;
1724
1725     case GarbageValue:
1726         clobberWorld(node.codeOrigin, indexInBlock);
1727         forNode(nodeIndex).makeTop();
1728         break;
1729
1730     case ForceOSRExit:
1731         node.setCanExit(true);
1732         m_isValid = false;
1733         break;
1734             
1735     case Phantom:
1736     case InlineStart:
1737     case Nop:
1738         node.setCanExit(false);
1739         break;
1740         
1741     case LastNodeType:
1742         ASSERT_NOT_REACHED();
1743         break;
1744     }
1745     
1746     return m_isValid;
1747 }
1748
1749 inline void AbstractState::clobberWorld(const CodeOrigin& codeOrigin, unsigned indexInBlock)
1750 {
1751     clobberCapturedVars(codeOrigin);
1752     clobberStructures(indexInBlock);
1753 }
1754
1755 inline void AbstractState::clobberCapturedVars(const CodeOrigin& codeOrigin)
1756 {
1757     if (codeOrigin.inlineCallFrame) {
1758         const BitVector& capturedVars = codeOrigin.inlineCallFrame->capturedVars;
1759         for (size_t i = capturedVars.size(); i--;) {
1760             if (!capturedVars.quickGet(i))
1761                 continue;
1762             m_variables.local(i).makeTop();
1763         }
1764     } else {
1765         for (size_t i = m_codeBlock->m_numVars; i--;) {
1766             if (m_codeBlock->isCaptured(i))
1767                 m_variables.local(i).makeTop();
1768         }
1769     }
1770
1771     for (size_t i = m_variables.numberOfArguments(); i--;) {
1772         if (m_codeBlock->isCaptured(argumentToOperand(i)))
1773             m_variables.argument(i).makeTop();
1774     }
1775 }
1776
1777 inline void AbstractState::clobberStructures(unsigned indexInBlock)
1778 {
1779     if (!m_haveStructures)
1780         return;
1781     for (size_t i = indexInBlock + 1; i--;)
1782         forNode(m_block->at(i)).clobberStructures();
1783     for (size_t i = m_variables.numberOfArguments(); i--;)
1784         m_variables.argument(i).clobberStructures();
1785     for (size_t i = m_variables.numberOfLocals(); i--;)
1786         m_variables.local(i).clobberStructures();
1787     m_haveStructures = false;
1788     m_didClobber = true;
1789 }
1790
1791 inline bool AbstractState::mergeStateAtTail(AbstractValue& destination, AbstractValue& inVariable, NodeIndex nodeIndex)
1792 {
1793     if (nodeIndex == NoNode)
1794         return false;
1795         
1796     AbstractValue source;
1797         
1798     Node& node = m_graph[nodeIndex];
1799     if (!node.refCount())
1800         return false;
1801     
1802 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1803     dataLogF("          It's live, node @%u.\n", nodeIndex);
1804 #endif
1805     
1806     if (node.variableAccessData()->isCaptured()) {
1807         source = inVariable;
1808 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1809         dataLogF("          Transfering ");
1810         source.dump(WTF::dataFile());
1811         dataLogF(" from last access due to captured variable.\n");
1812 #endif
1813     } else {
1814         switch (node.op()) {
1815         case Phi:
1816         case SetArgument:
1817         case Flush:
1818             // The block transfers the value from head to tail.
1819             source = inVariable;
1820 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1821             dataLogF("          Transfering ");
1822             source.dump(WTF::dataFile());
1823             dataLogF(" from head to tail.\n");
1824 #endif
1825             break;
1826             
1827         case GetLocal:
1828             // The block refines the value with additional speculations.
1829             source = forNode(nodeIndex);
1830 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1831             dataLogF("          Refining to ");
1832             source.dump(WTF::dataFile());
1833             dataLogF("\n");
1834 #endif
1835             break;
1836             
1837         case SetLocal:
1838             // The block sets the variable, and potentially refines it, both
1839             // before and after setting it.
1840             if (node.variableAccessData()->shouldUseDoubleFormat()) {
1841                 // FIXME: This unnecessarily loses precision.
1842                 source.set(SpecDouble);
1843             } else
1844                 source = forNode(node.child1());
1845 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1846             dataLogF("          Setting to ");
1847             source.dump(WTF::dataFile());
1848             dataLogF("\n");
1849 #endif
1850             break;
1851         
1852         default:
1853             ASSERT_NOT_REACHED();
1854             break;
1855         }
1856     }
1857     
1858     if (destination == source) {
1859         // Abstract execution did not change the output value of the variable, for this
1860         // basic block, on this iteration.
1861 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1862         dataLogF("          Not changed!\n");
1863 #endif
1864         return false;
1865     }
1866     
1867     // Abstract execution reached a new conclusion about the speculations reached about
1868     // this variable after execution of this basic block. Update the state, and return
1869     // true to indicate that the fixpoint must go on!
1870     destination = source;
1871 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1872     dataLogF("          Changed!\n");
1873 #endif
1874     return true;
1875 }
1876
1877 inline bool AbstractState::merge(BasicBlock* from, BasicBlock* to)
1878 {
1879     ASSERT(from->variablesAtTail.numberOfArguments() == to->variablesAtHead.numberOfArguments());
1880     ASSERT(from->variablesAtTail.numberOfLocals() == to->variablesAtHead.numberOfLocals());
1881     
1882     bool changed = false;
1883     
1884     for (size_t argument = 0; argument < from->variablesAtTail.numberOfArguments(); ++argument) {
1885         AbstractValue& destination = to->valuesAtHead.argument(argument);
1886         changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.argument(argument), to->variablesAtHead.argument(argument), from->variablesAtTail.argument(argument));
1887     }
1888     
1889     for (size_t local = 0; local < from->variablesAtTail.numberOfLocals(); ++local) {
1890         AbstractValue& destination = to->valuesAtHead.local(local);
1891         changed |= mergeVariableBetweenBlocks(destination, from->valuesAtTail.local(local), to->variablesAtHead.local(local), from->variablesAtTail.local(local));
1892     }
1893
1894     if (!to->cfaHasVisited)
1895         changed = true;
1896     
1897     to->cfaShouldRevisit |= changed;
1898     
1899     return changed;
1900 }
1901
1902 inline bool AbstractState::mergeToSuccessors(
1903     Graph& graph, BasicBlock* basicBlock)
1904 {
1905     Node& terminal = graph[basicBlock->last()];
1906     
1907     ASSERT(terminal.isTerminal());
1908     
1909     switch (terminal.op()) {
1910     case Jump: {
1911         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
1912 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1913         dataLogF("        Merging to block #%u.\n", terminal.takenBlockIndex());
1914 #endif
1915         return merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get());
1916     }
1917         
1918     case Branch: {
1919         ASSERT(basicBlock->cfaBranchDirection != InvalidBranchDirection);
1920         bool changed = false;
1921 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1922         dataLogF("        Merging to block #%u.\n", terminal.takenBlockIndex());
1923 #endif
1924         if (basicBlock->cfaBranchDirection != TakeFalse)
1925             changed |= merge(basicBlock, graph.m_blocks[terminal.takenBlockIndex()].get());
1926 #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
1927         dataLogF("        Merging to block #%u.\n", terminal.notTakenBlockIndex());
1928 #endif
1929         if (basicBlock->cfaBranchDirection != TakeTrue)
1930             changed |= merge(basicBlock, graph.m_blocks[terminal.notTakenBlockIndex()].get());
1931         return changed;
1932     }
1933         
1934     case Return:
1935     case Throw:
1936     case ThrowReferenceError:
1937         ASSERT(basicBlock->cfaBranchDirection == InvalidBranchDirection);
1938         return false;
1939         
1940     default:
1941         ASSERT_NOT_REACHED();
1942         return false;
1943     }
1944 }
1945
1946 inline bool AbstractState::mergeVariableBetweenBlocks(AbstractValue& destination, AbstractValue& source, NodeIndex destinationNodeIndex, NodeIndex sourceNodeIndex)
1947 {
1948     if (destinationNodeIndex == NoNode)
1949         return false;
1950     
1951     ASSERT_UNUSED(sourceNodeIndex, sourceNodeIndex != NoNode);
1952     
1953     // FIXME: We could do some sparse conditional propagation here!
1954     
1955     return destination.merge(source);
1956 }
1957
1958 void AbstractState::dump(PrintStream& out)
1959 {
1960     bool first = true;
1961     for (size_t i = 0; i < m_block->size(); ++i) {
1962         NodeIndex index = m_block->at(i);
1963         AbstractValue& value = m_nodes[index];
1964         if (value.isClear())
1965             continue;
1966         if (first)
1967             first = false;
1968         else
1969             out.printf(" ");
1970         out.printf("@%lu:", static_cast<unsigned long>(index));
1971         value.dump(out);
1972     }
1973 }
1974
1975 } } // namespace JSC::DFG
1976
1977 #endif // ENABLE(DFG_JIT)
1978