DFG does not speculate aggressively enough on comparisons
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT.cpp
1 /*
2  * Copyright (C) 2011 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 "DFGSpeculativeJIT.h"
28
29 #if ENABLE(DFG_JIT)
30
31 namespace JSC { namespace DFG {
32
33 template<bool strict>
34 GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat)
35 {
36 #if ENABLE(DFG_DEBUG_VERBOSE)
37     fprintf(stderr, "SpecInt@%d   ", nodeIndex);
38 #endif
39     Node& node = m_jit.graph()[nodeIndex];
40     VirtualRegister virtualRegister = node.virtualRegister();
41     GenerationInfo& info = m_generationInfo[virtualRegister];
42
43     switch (info.registerFormat()) {
44     case DataFormatNone: {
45         if (node.isConstant() && !isInt32Constant(nodeIndex)) {
46             terminateSpeculativeExecution();
47             returnFormat = DataFormatInteger;
48             return allocate();
49         }
50         
51         GPRReg gpr = allocate();
52
53         if (node.isConstant()) {
54             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
55             ASSERT(isInt32Constant(nodeIndex));
56             m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
57             info.fillInteger(gpr);
58             returnFormat = DataFormatInteger;
59             return gpr;
60         } else {
61             DataFormat spillFormat = info.spillFormat();
62             ASSERT(spillFormat & DataFormatJS);
63
64             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
65
66             if (spillFormat == DataFormatJSInteger) {
67                 // If we know this was spilled as an integer we can fill without checking.
68                 if (strict) {
69                     m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
70                     info.fillInteger(gpr);
71                     returnFormat = DataFormatInteger;
72                     return gpr;
73                 }
74                 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
75                 info.fillJSValue(gpr, DataFormatJSInteger);
76                 returnFormat = DataFormatJSInteger;
77                 return gpr;
78             }
79             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
80         }
81
82         // Fill as JSValue, and fall through.
83         info.fillJSValue(gpr, DataFormatJSInteger);
84         m_gprs.unlock(gpr);
85     }
86
87     case DataFormatJS: {
88         // Check the value is an integer.
89         GPRReg gpr = info.gpr();
90         m_gprs.lock(gpr);
91         speculationCheck(m_jit.branchPtr(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister));
92         info.fillJSValue(gpr, DataFormatJSInteger);
93         // If !strict we're done, return.
94         if (!strict) {
95             returnFormat = DataFormatJSInteger;
96             return gpr;
97         }
98         // else fall through & handle as DataFormatJSInteger.
99         m_gprs.unlock(gpr);
100     }
101
102     case DataFormatJSInteger: {
103         // In a strict fill we need to strip off the value tag.
104         if (strict) {
105             GPRReg gpr = info.gpr();
106             GPRReg result;
107             // If the register has already been locked we need to take a copy.
108             // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
109             if (m_gprs.isLocked(gpr))
110                 result = allocate();
111             else {
112                 m_gprs.lock(gpr);
113                 info.fillInteger(gpr);
114                 result = gpr;
115             }
116             m_jit.zeroExtend32ToPtr(gpr, result);
117             returnFormat = DataFormatInteger;
118             return result;
119         }
120
121         GPRReg gpr = info.gpr();
122         m_gprs.lock(gpr);
123         returnFormat = DataFormatJSInteger;
124         return gpr;
125     }
126
127     case DataFormatInteger: {
128         GPRReg gpr = info.gpr();
129         m_gprs.lock(gpr);
130         returnFormat = DataFormatInteger;
131         return gpr;
132     }
133
134     case DataFormatDouble:
135     case DataFormatCell:
136     case DataFormatBoolean:
137     case DataFormatJSDouble:
138     case DataFormatJSCell:
139     case DataFormatJSBoolean: {
140         terminateSpeculativeExecution();
141         returnFormat = DataFormatInteger;
142         return allocate();
143     }
144     }
145
146     ASSERT_NOT_REACHED();
147     return InvalidGPRReg;
148 }
149
150 #if !ENABLE(DFG_OSR_EXIT)
151 SpeculationCheck::SpeculationCheck(MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex)
152     : m_check(check)
153     , m_nodeIndex(jit->m_compileIndex)
154     , m_recoveryIndex(recoveryIndex)
155 {
156     for (gpr_iterator iter = jit->m_gprs.begin(); iter != jit->m_gprs.end(); ++iter) {
157         if (iter.name() != InvalidVirtualRegister) {
158             GenerationInfo& info =  jit->m_generationInfo[iter.name()];
159             m_gprInfo[iter.index()].nodeIndex = info.nodeIndex();
160             m_gprInfo[iter.index()].format = info.registerFormat();
161             ASSERT(m_gprInfo[iter.index()].format != DataFormatNone);
162             m_gprInfo[iter.index()].isSpilled = info.spillFormat() != DataFormatNone;
163         } else
164             m_gprInfo[iter.index()].nodeIndex = NoNode;
165     }
166     for (fpr_iterator iter = jit->m_fprs.begin(); iter != jit->m_fprs.end(); ++iter) {
167         if (iter.name() != InvalidVirtualRegister) {
168             GenerationInfo& info =  jit->m_generationInfo[iter.name()];
169             ASSERT(info.registerFormat() == DataFormatDouble);
170             m_fprInfo[iter.index()].nodeIndex = info.nodeIndex();
171             m_fprInfo[iter.index()].format = DataFormatDouble;
172             m_fprInfo[iter.index()].isSpilled = info.spillFormat() != DataFormatNone;
173         } else
174             m_fprInfo[iter.index()].nodeIndex = NoNode;
175     }
176 }
177 #endif
178
179 #ifndef NDEBUG
180 void ValueSource::dump(FILE* out) const
181 {
182     fprintf(out, "Node(%d)", m_nodeIndex);
183 }
184
185 void ValueRecovery::dump(FILE* out) const
186 {
187     switch (technique()) {
188     case AlreadyInRegisterFile:
189         fprintf(out, "-");
190         break;
191     case InGPR:
192         fprintf(out, "%%%s", GPRInfo::debugName(gpr()));
193         break;
194     case UnboxedInt32InGPR:
195         fprintf(out, "int32(%%%s)", GPRInfo::debugName(gpr()));
196         break;
197     case InFPR:
198         fprintf(out, "%%%s", FPRInfo::debugName(fpr()));
199         break;
200     case DisplacedInRegisterFile:
201         fprintf(out, "*%d", virtualRegister());
202         break;
203     case Constant:
204         fprintf(out, "[%s]", constant().description());
205         break;
206     case DontKnow:
207         fprintf(out, "!");
208         break;
209     default:
210         fprintf(out, "?%d", technique());
211         break;
212     }
213 }
214 #endif
215
216 #if ENABLE(DFG_OSR_EXIT)
217 OSRExit::OSRExit(MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex)
218     : m_check(check)
219     , m_nodeIndex(jit->m_compileIndex)
220     , m_bytecodeIndex(jit->m_bytecodeIndexForOSR)
221     , m_recoveryIndex(recoveryIndex)
222     , m_arguments(jit->m_arguments.size())
223     , m_variables(jit->m_variables.size())
224     , m_lastSetOperand(jit->m_lastSetOperand)
225 {
226     ASSERT(m_bytecodeIndex != std::numeric_limits<uint32_t>::max());
227     for (unsigned argument = 0; argument < m_arguments.size(); ++argument)
228         m_arguments[argument] = jit->computeValueRecoveryFor(jit->m_arguments[argument]);
229     for (unsigned variable = 0; variable < m_variables.size(); ++variable)
230         m_variables[variable] = jit->computeValueRecoveryFor(jit->m_variables[variable]);
231 }
232
233 #ifndef NDEBUG
234 void OSRExit::dump(FILE* out) const
235 {
236     for (unsigned argument = 0; argument < m_arguments.size(); ++argument)
237         m_arguments[argument].dump(out);
238     fprintf(out, " : ");
239     for (unsigned variable = 0; variable < m_variables.size(); ++variable)
240         m_variables[variable].dump(out);
241 }
242 #endif
243 #endif
244
245 GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat)
246 {
247     return fillSpeculateIntInternal<false>(nodeIndex, returnFormat);
248 }
249
250 GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
251 {
252     DataFormat mustBeDataFormatInteger;
253     GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger);
254     ASSERT(mustBeDataFormatInteger == DataFormatInteger);
255     return result;
256 }
257
258 FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex)
259 {
260 #if ENABLE(DFG_DEBUG_VERBOSE)
261     fprintf(stderr, "SpecDouble@%d   ", nodeIndex);
262 #endif
263     Node& node = m_jit.graph()[nodeIndex];
264     VirtualRegister virtualRegister = node.virtualRegister();
265     GenerationInfo& info = m_generationInfo[virtualRegister];
266
267     if (info.registerFormat() == DataFormatNone) {
268         GPRReg gpr = allocate();
269
270         if (node.isConstant()) {
271             if (isInt32Constant(nodeIndex)) {
272                 FPRReg fpr = fprAllocate();
273                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(static_cast<double>(valueOfInt32Constant(nodeIndex))))), gpr);
274                 m_jit.movePtrToDouble(gpr, fpr);
275                 unlock(gpr);
276
277                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
278                 info.fillDouble(fpr);
279                 return fpr;
280             }
281             if (isNumberConstant(nodeIndex)) {
282                 FPRReg fpr = fprAllocate();
283                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(nodeIndex)))), gpr);
284                 m_jit.movePtrToDouble(gpr, fpr);
285                 unlock(gpr);
286
287                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
288                 info.fillDouble(fpr);
289                 return fpr;
290             }
291             terminateSpeculativeExecution();
292             return fprAllocate();
293         } else {
294             DataFormat spillFormat = info.spillFormat();
295             ASSERT(spillFormat & DataFormatJS);
296             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
297             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
298             info.fillJSValue(gpr, spillFormat);
299             unlock(gpr);
300         }
301     }
302
303     switch (info.registerFormat()) {
304     case DataFormatNone: // Should have filled, above.
305     case DataFormatBoolean: // This type never occurs.
306         ASSERT_NOT_REACHED();
307         
308     case DataFormatCell:
309     case DataFormatJSCell:
310     case DataFormatJS:
311     case DataFormatJSBoolean: {
312         GPRReg jsValueGpr = info.gpr();
313         m_gprs.lock(jsValueGpr);
314         FPRReg fpr = fprAllocate();
315         GPRReg tempGpr = allocate();
316
317         JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
318
319         speculationCheck(m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));
320
321         // First, if we get here we have a double encoded as a JSValue
322         m_jit.move(jsValueGpr, tempGpr);
323         unboxDouble(tempGpr, fpr);
324         JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
325
326         // Finally, handle integers.
327         isInteger.link(&m_jit);
328         m_jit.convertInt32ToDouble(jsValueGpr, fpr);
329         hasUnboxedDouble.link(&m_jit);
330
331         m_gprs.release(jsValueGpr);
332         m_gprs.unlock(jsValueGpr);
333         m_gprs.unlock(tempGpr);
334         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
335         info.fillDouble(fpr);
336         info.killSpilled();
337         return fpr;
338     }
339
340     case DataFormatJSInteger:
341     case DataFormatInteger: {
342         FPRReg fpr = fprAllocate();
343         GPRReg gpr = info.gpr();
344         m_gprs.lock(gpr);
345         m_jit.convertInt32ToDouble(gpr, fpr);
346         m_gprs.unlock(gpr);
347         return fpr;
348     }
349
350     // Unbox the double
351     case DataFormatJSDouble: {
352         GPRReg gpr = info.gpr();
353         FPRReg fpr = fprAllocate();
354         if (m_gprs.isLocked(gpr)) {
355             // Make sure we don't trample gpr if it is in use.
356             GPRReg temp = allocate();
357             m_jit.move(gpr, temp);
358             unboxDouble(temp, fpr);
359             unlock(temp);
360         } else
361             unboxDouble(gpr, fpr);
362
363         m_gprs.release(gpr);
364         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
365
366         info.fillDouble(fpr);
367         return fpr;
368     }
369
370     case DataFormatDouble: {
371         FPRReg fpr = info.fpr();
372         m_fprs.lock(fpr);
373         return fpr;
374     }
375     }
376
377     ASSERT_NOT_REACHED();
378     return InvalidFPRReg;
379 }
380
381 GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
382 {
383 #if ENABLE(DFG_DEBUG_VERBOSE)
384     fprintf(stderr, "SpecCell@%d   ", nodeIndex);
385 #endif
386     Node& node = m_jit.graph()[nodeIndex];
387     VirtualRegister virtualRegister = node.virtualRegister();
388     GenerationInfo& info = m_generationInfo[virtualRegister];
389
390     switch (info.registerFormat()) {
391     case DataFormatNone: {
392         GPRReg gpr = allocate();
393
394         if (node.isConstant()) {
395             JSValue jsValue = valueOfJSConstant(nodeIndex);
396             if (jsValue.isCell()) {
397                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
398                 m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
399                 info.fillJSValue(gpr, DataFormatJSCell);
400                 return gpr;
401             }
402             terminateSpeculativeExecution();
403             return gpr;
404         }
405         ASSERT(info.spillFormat() & DataFormatJS);
406         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
407         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
408
409         info.fillJSValue(gpr, DataFormatJS);
410         if (info.spillFormat() != DataFormatJSCell)
411             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
412         info.fillJSValue(gpr, DataFormatJSCell);
413         return gpr;
414     }
415
416     case DataFormatCell:
417     case DataFormatJSCell: {
418         GPRReg gpr = info.gpr();
419         m_gprs.lock(gpr);
420         return gpr;
421     }
422
423     case DataFormatJS: {
424         GPRReg gpr = info.gpr();
425         m_gprs.lock(gpr);
426         speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
427         info.fillJSValue(gpr, DataFormatJSCell);
428         return gpr;
429     }
430
431     case DataFormatJSInteger:
432     case DataFormatInteger:
433     case DataFormatJSDouble:
434     case DataFormatDouble:
435     case DataFormatJSBoolean:
436     case DataFormatBoolean: {
437         terminateSpeculativeExecution();
438         return allocate();
439     }
440     }
441
442     ASSERT_NOT_REACHED();
443     return InvalidGPRReg;
444 }
445
446 GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex)
447 {
448 #if ENABLE(DFG_DEBUG_VERBOSE)
449     fprintf(stderr, "SpecBool@%d   ", nodeIndex);
450 #endif
451     Node& node = m_jit.graph()[nodeIndex];
452     VirtualRegister virtualRegister = node.virtualRegister();
453     GenerationInfo& info = m_generationInfo[virtualRegister];
454
455     switch (info.registerFormat()) {
456     case DataFormatNone: {
457         GPRReg gpr = allocate();
458
459         if (node.isConstant()) {
460             JSValue jsValue = valueOfJSConstant(nodeIndex);
461             if (jsValue.isBoolean()) {
462                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
463                 m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsValue)), gpr);
464                 info.fillJSValue(gpr, DataFormatJSBoolean);
465                 return gpr;
466             }
467             terminateSpeculativeExecution();
468             return gpr;
469         }
470         ASSERT(info.spillFormat() & DataFormatJS);
471         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
472         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
473
474         info.fillJSValue(gpr, DataFormatJS);
475         if (info.spillFormat() != DataFormatJSBoolean) {
476             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
477             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
478             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
479         }
480         info.fillJSValue(gpr, DataFormatJSBoolean);
481         return gpr;
482     }
483
484     case DataFormatBoolean:
485     case DataFormatJSBoolean: {
486         GPRReg gpr = info.gpr();
487         m_gprs.lock(gpr);
488         return gpr;
489     }
490
491     case DataFormatJS: {
492         GPRReg gpr = info.gpr();
493         m_gprs.lock(gpr);
494         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
495         speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
496         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
497         info.fillJSValue(gpr, DataFormatJSBoolean);
498         return gpr;
499     }
500
501     case DataFormatJSInteger:
502     case DataFormatInteger:
503     case DataFormatJSDouble:
504     case DataFormatDouble:
505     case DataFormatJSCell:
506     case DataFormatCell: {
507         terminateSpeculativeExecution();
508         return allocate();
509     }
510     }
511
512     ASSERT_NOT_REACHED();
513     return InvalidGPRReg;
514 }
515
516 void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition condition)
517 {
518     Node& branchNode = m_jit.graph()[branchNodeIndex];
519     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
520     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
521
522     // The branch instruction will branch to the taken block.
523     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
524     if (taken == (m_block + 1)) {
525         condition = JITCompiler::invert(condition);
526         BlockIndex tmp = taken;
527         taken = notTaken;
528         notTaken = tmp;
529     }
530
531     if (isInt32Constant(node.child1())) {
532         int32_t imm = valueOfInt32Constant(node.child1());
533         SpeculateIntegerOperand op2(this, node.child2());
534         addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken);
535     } else if (isInt32Constant(node.child2())) {
536         SpeculateIntegerOperand op1(this, node.child1());
537         int32_t imm = valueOfInt32Constant(node.child2());
538         addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken);
539     } else {
540         SpeculateIntegerOperand op1(this, node.child1());
541         SpeculateIntegerOperand op2(this, node.child2());
542         addBranch(m_jit.branch32(condition, op1.gpr(), op2.gpr()), taken);
543     }
544
545     // Check for fall through, otherwise we need to jump.
546     if (notTaken != (m_block + 1))
547         addBranch(m_jit.jump(), notTaken);
548 }
549
550 JITCompiler::Jump SpeculativeJIT::convertToDouble(GPRReg value, FPRReg result, GPRReg tmp)
551 {
552     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, value, GPRInfo::tagTypeNumberRegister);
553     
554     JITCompiler::Jump notNumber = m_jit.branchTestPtr(MacroAssembler::Zero, value, GPRInfo::tagTypeNumberRegister);
555     
556     m_jit.move(value, tmp);
557     unboxDouble(tmp, result);
558     
559     JITCompiler::Jump done = m_jit.jump();
560     
561     isInteger.link(&m_jit);
562     
563     m_jit.convertInt32ToDouble(value, result);
564     
565     done.link(&m_jit);
566
567     return notNumber;
568 }
569
570 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
571 {
572     Node& branchNode = m_jit.graph()[branchNodeIndex];
573     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
574     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
575     
576     SpeculateDoubleOperand op1(this, node.child1());
577     SpeculateDoubleOperand op2(this, node.child2());
578     
579     addBranch(m_jit.branchDouble(condition, op1.fpr(), op2.fpr()), taken);
580     
581     if (notTaken != (m_block + 1))
582         addBranch(m_jit.jump(), notTaken);
583 }
584
585 void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, void* vptr)
586 {
587     Node& branchNode = m_jit.graph()[branchNodeIndex];
588     BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.takenBytecodeOffset());
589     BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(branchNode.notTakenBytecodeOffset());
590
591     MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
592     
593     if (taken == (m_block + 1)) {
594         condition = MacroAssembler::NotEqual;
595         BlockIndex tmp = taken;
596         taken = notTaken;
597         notTaken = tmp;
598     }
599
600     SpeculateCellOperand op1(this, node.child1());
601     SpeculateCellOperand op2(this, node.child2());
602     
603     GPRReg op1GPR = op1.gpr();
604     GPRReg op2GPR = op2.gpr();
605     
606     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
607     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
608     
609     addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken);
610     if (notTaken != (m_block + 1))
611         addBranch(m_jit.jump(), notTaken);
612 }
613
614 void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr)
615 {
616     SpeculateCellOperand op1(this, node.child1());
617     SpeculateCellOperand op2(this, node.child2());
618     GPRTemporary result(this, op1);
619     
620     GPRReg op1GPR = op1.gpr();
621     GPRReg op2GPR = op2.gpr();
622     GPRReg resultGPR = result.gpr();
623     
624     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
625     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
626     
627     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
628     m_jit.move(Imm32(ValueTrue), resultGPR);
629     MacroAssembler::Jump done = m_jit.jump();
630     falseCase.link(&m_jit);
631     m_jit.move(Imm32(ValueFalse), resultGPR);
632     done.link(&m_jit);
633
634     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
635 }
636
637 // Returns true if the compare is fused with a subsequent branch.
638 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
639 {
640     // Fused compare & branch.
641     NodeIndex branchNodeIndex = detectPeepHoleBranch();
642     if (branchNodeIndex != NoNode) {
643         // detectPeepHoleBranch currently only permits the branch to be the very next node,
644         // so can be no intervening nodes to also reference the compare. 
645         ASSERT(node.adjustedRefCount() == 1);
646
647         if (shouldSpeculateInteger(node.child1(), node.child2())) {
648             compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
649             use(node.child1());
650             use(node.child2());
651         } else if (shouldSpeculateNumber(node.child1(), node.child2())) {
652             compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
653             use(node.child1());
654             use(node.child2());
655         } else if (node.op == CompareEq && shouldSpeculateFinalObject(node.child1(), node.child2())) {
656             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr);
657             use(node.child1());
658             use(node.child2());
659         } else if (node.op == CompareEq && shouldSpeculateArray(node.child1(), node.child2())) {
660             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr);
661             use(node.child1());
662             use(node.child2());
663         } else
664             nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
665
666         m_compileIndex = branchNodeIndex;
667         return true;
668     }
669     
670     if (shouldSpeculateFinalObject(node.child1(), node.child2()))
671         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr);
672     else if (shouldSpeculateArray(node.child1(), node.child2()))
673         compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr);
674     else if (!shouldSpeculateNumber(node.child1()) && !shouldSpeculateNumber(node.child2()))
675         nonSpeculativeNonPeepholeCompare(node, condition, operation);
676     else if ((shouldSpeculateNumber(node.child1()) || shouldSpeculateNumber(node.child2())) && !shouldSpeculateInteger(node.child1(), node.child2())) {
677         // Normal case, not fused to branch.
678         SpeculateDoubleOperand op1(this, node.child1());
679         SpeculateDoubleOperand op2(this, node.child2());
680         GPRTemporary result(this);
681         
682         m_jit.move(TrustedImm32(ValueTrue), result.gpr());
683         MacroAssembler::Jump trueCase = m_jit.branchDouble(doubleCondition, op1.fpr(), op2.fpr());
684         m_jit.xorPtr(Imm32(true), result.gpr());
685         trueCase.link(&m_jit);
686
687         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
688     } else {
689         // Normal case, not fused to branch.
690         SpeculateIntegerOperand op1(this, node.child1());
691         SpeculateIntegerOperand op2(this, node.child2());
692         GPRTemporary result(this, op1, op2);
693         
694         m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
695         
696         // If we add a DataFormatBool, we should use it here.
697         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
698         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
699     }
700     
701     return false;
702 }
703
704 void SpeculativeJIT::compile(Node& node)
705 {
706     NodeType op = node.op;
707
708     switch (op) {
709     case JSConstant:
710         initConstantInfo(m_compileIndex);
711         break;
712
713     case GetLocal: {
714         GPRTemporary result(this);
715         PredictedType prediction = m_jit.graph().getPrediction(node.local());
716         if (isInt32Prediction(prediction)) {
717             m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
718
719             // Like integerResult, but don't useChildren - our children are phi nodes,
720             // and don't represent values within this dataflow with virtual registers.
721             VirtualRegister virtualRegister = node.virtualRegister();
722             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
723             m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
724         } else {
725             m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
726
727             // Like jsValueResult, but don't useChildren - our children are phi nodes,
728             // and don't represent values within this dataflow with virtual registers.
729             VirtualRegister virtualRegister = node.virtualRegister();
730             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
731             
732             DataFormat format;
733             if (isArrayPrediction(prediction))
734                 format = DataFormatJSCell;
735             else if (isBooleanPrediction(prediction))
736                 format = DataFormatJSBoolean;
737             else
738                 format = DataFormatJS;
739             
740             m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
741         }
742         break;
743     }
744
745     case SetLocal: {
746         // SetLocal doubles as a hint as to where a node will be stored and
747         // as a speculation point. So before we speculate make sure that we
748         // know where the child of this node needs to go in the virtual
749         // register file.
750         compileMovHint(node);
751         
752         // As far as OSR is concerned, we're on the bytecode index corresponding
753         // to the *next* instruction, since we've already "executed" the
754         // SetLocal and whatever other DFG Nodes are associated with the same
755         // bytecode index as the SetLocal.
756         ASSERT(m_bytecodeIndexForOSR == node.codeOrigin.bytecodeIndex());
757         Node& nextNode = m_jit.graph()[m_compileIndex+1];
758         
759         // This assertion will fail if we ever emit multiple SetLocal's for
760         // a single bytecode instruction. That's unlikely to happen. But if
761         // it does, the solution is to to have this perform a search until
762         // it finds a Node with a different bytecode index from the one we've
763         // got, and to abstractly execute the SetLocal's along the way. Or,
764         // better yet, handle all of the SetLocal's at once: abstract interpret
765         // all of them, then emit code for all of them, with OSR exiting to
766         // the next non-SetLocal instruction. Note the special case for when
767         // both this SetLocal and the next op have a bytecode index of 0; this
768         // occurs for SetLocal's generated at the top of the code block to
769         // initialize locals to undefined. Ideally, we'd have a way of marking
770         // in the CodeOrigin that a SetLocal is synthetic. This will make the
771         // assertion more sensible-looking. We should then also assert that
772         // synthetic SetLocal's don't have speculation checks, since they
773         // should only be dropping values that we statically know we are
774         // allowed to drop into the variables. DFGPropagator will guarantee
775         // this, since it should have at least an approximation (if not
776         // exact knowledge) of the type of the SetLocal's child node, and
777         // should merge that information into the local that is being set.
778         ASSERT(m_bytecodeIndexForOSR != nextNode.codeOrigin.bytecodeIndex()
779                || (!m_bytecodeIndexForOSR && !nextNode.codeOrigin.bytecodeIndex()));
780         m_bytecodeIndexForOSR = nextNode.codeOrigin.bytecodeIndex();
781         
782         PredictedType predictedType = m_jit.graph().getPrediction(node.local());
783         if (isInt32Prediction(predictedType)) {
784             SpeculateIntegerOperand value(this, node.child1());
785             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
786             noResult(m_compileIndex);
787         } else if (isArrayPrediction(predictedType)) {
788             SpeculateCellOperand cell(this, node.child1());
789             GPRReg cellGPR = cell.gpr();
790             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
791             m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
792             noResult(m_compileIndex);
793         } else if (isBooleanPrediction(predictedType)) {
794             SpeculateBooleanOperand boolean(this, node.child1());
795             m_jit.storePtr(boolean.gpr(), JITCompiler::addressFor(node.local()));
796             noResult(m_compileIndex);
797         } else {
798             JSValueOperand value(this, node.child1());
799             m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
800             noResult(m_compileIndex);
801         }
802         
803         // Indicate that it's no longer necessary to retrieve the value of
804         // this bytecode variable from registers or other locations in the register file.
805         valueSourceReferenceForOperand(node.local()) = ValueSource();
806         break;
807     }
808
809     case BitAnd:
810     case BitOr:
811     case BitXor:
812         if (isInt32Constant(node.child1())) {
813             SpeculateIntegerOperand op2(this, node.child2());
814             GPRTemporary result(this, op2);
815
816             bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
817
818             integerResult(result.gpr(), m_compileIndex);
819         } else if (isInt32Constant(node.child2())) {
820             SpeculateIntegerOperand op1(this, node.child1());
821             GPRTemporary result(this, op1);
822
823             bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
824
825             integerResult(result.gpr(), m_compileIndex);
826         } else {
827             SpeculateIntegerOperand op1(this, node.child1());
828             SpeculateIntegerOperand op2(this, node.child2());
829             GPRTemporary result(this, op1, op2);
830
831             GPRReg reg1 = op1.gpr();
832             GPRReg reg2 = op2.gpr();
833             bitOp(op, reg1, reg2, result.gpr());
834
835             integerResult(result.gpr(), m_compileIndex);
836         }
837         break;
838
839     case BitRShift:
840     case BitLShift:
841     case BitURShift:
842         if (isInt32Constant(node.child2())) {
843             SpeculateIntegerOperand op1(this, node.child1());
844             GPRTemporary result(this, op1);
845
846             shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
847
848             integerResult(result.gpr(), m_compileIndex);
849         } else {
850             // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
851             SpeculateIntegerOperand op1(this, node.child1());
852             SpeculateIntegerOperand op2(this, node.child2());
853             GPRTemporary result(this, op1);
854
855             GPRReg reg1 = op1.gpr();
856             GPRReg reg2 = op2.gpr();
857             shiftOp(op, reg1, reg2, result.gpr());
858
859             integerResult(result.gpr(), m_compileIndex);
860         }
861         break;
862
863     case UInt32ToNumber: {
864         IntegerOperand op1(this, node.child1());
865         GPRTemporary result(this, op1);
866
867         // Test the operand is positive.
868         speculationCheck(m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));
869
870         m_jit.move(op1.gpr(), result.gpr());
871         integerResult(result.gpr(), m_compileIndex, op1.format());
872         break;
873     }
874
875     case ValueToInt32: {
876         SpeculateIntegerOperand op1(this, node.child1());
877         GPRTemporary result(this, op1);
878         m_jit.move(op1.gpr(), result.gpr());
879         integerResult(result.gpr(), m_compileIndex, op1.format());
880         break;
881     }
882
883     case ValueToNumber: {
884         if (shouldSpeculateInteger(node.child1())) {
885             SpeculateIntegerOperand op1(this, node.child1());
886             GPRTemporary result(this, op1);
887             m_jit.move(op1.gpr(), result.gpr());
888             integerResult(result.gpr(), m_compileIndex, op1.format());
889             break;
890         }
891         SpeculateDoubleOperand op1(this, node.child1());
892         FPRTemporary result(this, op1);
893         m_jit.moveDouble(op1.fpr(), result.fpr());
894         doubleResult(result.fpr(), m_compileIndex);
895         break;
896     }
897
898     case ValueToDouble: {
899         SpeculateDoubleOperand op1(this, node.child1());
900         FPRTemporary result(this, op1);
901         m_jit.moveDouble(op1.fpr(), result.fpr());
902         doubleResult(result.fpr(), m_compileIndex);
903         break;
904     }
905
906     case ValueAdd:
907     case ArithAdd: {
908         if (shouldSpeculateInteger(node.child1(), node.child2())) {
909             if (isInt32Constant(node.child1())) {
910                 int32_t imm1 = valueOfInt32Constant(node.child1());
911                 SpeculateIntegerOperand op2(this, node.child2());
912                 GPRTemporary result(this);
913
914                 speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
915
916                 integerResult(result.gpr(), m_compileIndex);
917                 break;
918             }
919                 
920             if (isInt32Constant(node.child2())) {
921                 SpeculateIntegerOperand op1(this, node.child1());
922                 int32_t imm2 = valueOfInt32Constant(node.child2());
923                 GPRTemporary result(this);
924                 
925                 speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
926
927                 integerResult(result.gpr(), m_compileIndex);
928                 break;
929             }
930                 
931             SpeculateIntegerOperand op1(this, node.child1());
932             SpeculateIntegerOperand op2(this, node.child2());
933             GPRTemporary result(this, op1, op2);
934
935             GPRReg gpr1 = op1.gpr();
936             GPRReg gpr2 = op2.gpr();
937             GPRReg gprResult = result.gpr();
938             MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
939
940             if (gpr1 == gprResult)
941                 speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
942             else if (gpr2 == gprResult)
943                 speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
944             else
945                 speculationCheck(check);
946
947             integerResult(gprResult, m_compileIndex);
948             break;
949         }
950
951         if (shouldSpeculateNumber(node.child1(), node.child2())) {
952             SpeculateDoubleOperand op1(this, node.child1());
953             SpeculateDoubleOperand op2(this, node.child2());
954             FPRTemporary result(this, op1, op2);
955             
956             FPRReg reg1 = op1.fpr();
957             FPRReg reg2 = op2.fpr();
958             m_jit.addDouble(reg1, reg2, result.fpr());
959             
960             doubleResult(result.fpr(), m_compileIndex);
961             break;
962         }
963         
964         ASSERT(op == ValueAdd);
965         
966         JSValueOperand op1(this, node.child1());
967         JSValueOperand op2(this, node.child2());
968         
969         GPRReg op1GPR = op1.gpr();
970         GPRReg op2GPR = op2.gpr();
971         
972         flushRegisters();
973         
974         GPRResult result(this);
975         if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
976             callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
977         else
978             callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
979         
980         jsValueResult(result.gpr(), m_compileIndex);
981         break;
982     }
983
984     case ArithSub: {
985         if (shouldSpeculateInteger(node.child1(), node.child2())) {
986             if (isInt32Constant(node.child2())) {
987                 SpeculateIntegerOperand op1(this, node.child1());
988                 int32_t imm2 = valueOfInt32Constant(node.child2());
989                 GPRTemporary result(this);
990
991                 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
992
993                 integerResult(result.gpr(), m_compileIndex);
994                 break;
995             }
996                 
997             SpeculateIntegerOperand op1(this, node.child1());
998             SpeculateIntegerOperand op2(this, node.child2());
999             GPRTemporary result(this);
1000
1001             speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
1002
1003             integerResult(result.gpr(), m_compileIndex);
1004             break;
1005         }
1006
1007         SpeculateDoubleOperand op1(this, node.child1());
1008         SpeculateDoubleOperand op2(this, node.child2());
1009         FPRTemporary result(this, op1);
1010
1011         FPRReg reg1 = op1.fpr();
1012         FPRReg reg2 = op2.fpr();
1013         m_jit.subDouble(reg1, reg2, result.fpr());
1014
1015         doubleResult(result.fpr(), m_compileIndex);
1016         break;
1017     }
1018
1019     case ArithMul: {
1020         if (shouldSpeculateInteger(node.child1(), node.child2())) {
1021             SpeculateIntegerOperand op1(this, node.child1());
1022             SpeculateIntegerOperand op2(this, node.child2());
1023             GPRTemporary result(this);
1024
1025             GPRReg reg1 = op1.gpr();
1026             GPRReg reg2 = op2.gpr();
1027             speculationCheck(m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
1028
1029             MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
1030             speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
1031             speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
1032             resultNonZero.link(&m_jit);
1033
1034             integerResult(result.gpr(), m_compileIndex);
1035             break;
1036         }
1037
1038         SpeculateDoubleOperand op1(this, node.child1());
1039         SpeculateDoubleOperand op2(this, node.child2());
1040         FPRTemporary result(this, op1, op2);
1041
1042         FPRReg reg1 = op1.fpr();
1043         FPRReg reg2 = op2.fpr();
1044         
1045         m_jit.mulDouble(reg1, reg2, result.fpr());
1046         
1047         doubleResult(result.fpr(), m_compileIndex);
1048         break;
1049     }
1050
1051     case ArithDiv: {
1052         SpeculateDoubleOperand op1(this, node.child1());
1053         SpeculateDoubleOperand op2(this, node.child2());
1054         FPRTemporary result(this, op1);
1055
1056         FPRReg reg1 = op1.fpr();
1057         FPRReg reg2 = op2.fpr();
1058         m_jit.divDouble(reg1, reg2, result.fpr());
1059
1060         doubleResult(result.fpr(), m_compileIndex);
1061         break;
1062     }
1063
1064     case ArithMod: {
1065         SpeculateIntegerOperand op1(this, node.child1());
1066         SpeculateIntegerOperand op2(this, node.child2());
1067         GPRTemporary eax(this, X86Registers::eax);
1068         GPRTemporary edx(this, X86Registers::edx);
1069         GPRReg op1Gpr = op1.gpr();
1070         GPRReg op2Gpr = op2.gpr();
1071
1072         speculationCheck(m_jit.branchTest32(JITCompiler::Zero, op2Gpr));
1073
1074         GPRReg temp2 = InvalidGPRReg;
1075         if (op2Gpr == X86Registers::eax || op2Gpr == X86Registers::edx) {
1076             temp2 = allocate();
1077             m_jit.move(op2Gpr, temp2);
1078             op2Gpr = temp2;
1079         }
1080
1081         m_jit.move(op1Gpr, eax.gpr());
1082         m_jit.assembler().cdq();
1083         m_jit.assembler().idivl_r(op2Gpr);
1084
1085         if (temp2 != InvalidGPRReg)
1086             unlock(temp2);
1087
1088         integerResult(edx.gpr(), m_compileIndex);
1089         break;
1090     }
1091
1092     case LogicalNot: {
1093         if (isKnownBoolean(node.child1())) {
1094             SpeculateBooleanOperand value(this, node.child1());
1095             GPRTemporary result(this, value);
1096             
1097             m_jit.move(value.gpr(), result.gpr());
1098             m_jit.xorPtr(TrustedImm32(true), result.gpr());
1099             
1100             jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1101             break;
1102         }
1103         
1104         PredictedType prediction = m_jit.graph().getPrediction(m_jit.graph()[node.child1()]);
1105         if (isBooleanPrediction(prediction) || !isStrongPrediction(prediction)) {
1106             JSValueOperand value(this, node.child1());
1107             GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
1108             
1109             m_jit.move(value.gpr(), result.gpr());
1110             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
1111             speculationCheck(m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1112             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
1113             
1114             // If we add a DataFormatBool, we should use it here.
1115             jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1116             break;
1117         }
1118         
1119         nonSpeculativeLogicalNot(node);
1120         
1121         break;
1122     }
1123
1124     case CompareLess:
1125         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
1126             return;
1127         break;
1128
1129     case CompareLessEq:
1130         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
1131             return;
1132         break;
1133
1134     case CompareGreater:
1135         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
1136             return;
1137         break;
1138
1139     case CompareGreaterEq:
1140         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
1141             return;
1142         break;
1143
1144     case CompareEq:
1145         if (isNullConstant(node.child1())) {
1146             if (nonSpeculativeCompareNull(node, node.child2()))
1147                 return;
1148             break;
1149         }
1150         if (isNullConstant(node.child2())) {
1151             if (nonSpeculativeCompareNull(node, node.child1()))
1152                 return;
1153             break;
1154         }
1155         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
1156             return;
1157         break;
1158
1159     case CompareStrictEq:
1160         if (nonSpeculativeStrictEq(node))
1161             return;
1162         break;
1163
1164     case GetByVal: {
1165         NodeIndex alias = node.child3();
1166         if (alias != NoNode) {
1167             // FIXME: result should be able to reuse child1, child2. Should have an 'UnusedOperand' type.
1168             JSValueOperand aliasedValue(this, node.child3());
1169             GPRTemporary result(this, aliasedValue);
1170             m_jit.move(aliasedValue.gpr(), result.gpr());
1171             jsValueResult(result.gpr(), m_compileIndex);
1172             break;
1173         }
1174
1175         SpeculateCellOperand base(this, node.child1());
1176         SpeculateStrictInt32Operand property(this, node.child2());
1177         GPRTemporary storage(this);
1178
1179         GPRReg baseReg = base.gpr();
1180         GPRReg propertyReg = property.gpr();
1181         GPRReg storageReg = storage.gpr();
1182         
1183         if (!m_compileOkay)
1184             return;
1185
1186         // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
1187         // an access with offset JSArray::storageOffset() is valid for all JSCells!
1188         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1189
1190         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
1191         // If we have predicted the base to be type array, we can skip the check.
1192         Node& baseNode = m_jit.graph()[node.child1()];
1193         if (baseNode.op != GetLocal || !isArrayPrediction(m_jit.graph().getPrediction(baseNode.local())))
1194             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1195         speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
1196
1197         // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache
1198         // the storage pointer - especially if there happens to be another register free right now. If we do so,
1199         // then we'll need to allocate a new temporary for result.
1200         GPRTemporary& result = storage;
1201         m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
1202         speculationCheck(m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));
1203
1204         jsValueResult(result.gpr(), m_compileIndex);
1205         break;
1206     }
1207
1208     case PutByVal: {
1209         SpeculateCellOperand base(this, node.child1());
1210         SpeculateStrictInt32Operand property(this, node.child2());
1211         JSValueOperand value(this, node.child3());
1212         GPRTemporary scratch(this);
1213
1214         // Map base, property & value into registers, allocate a scratch register.
1215         GPRReg baseReg = base.gpr();
1216         GPRReg propertyReg = property.gpr();
1217         GPRReg valueReg = value.gpr();
1218         GPRReg scratchReg = scratch.gpr();
1219         
1220         if (!m_compileOkay)
1221             return;
1222         
1223         writeBarrier(m_jit, baseReg, scratchReg, WriteBarrierForPropertyAccess);
1224
1225         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
1226         // If we have predicted the base to be type array, we can skip the check.
1227         Node& baseNode = m_jit.graph()[node.child1()];
1228         if (baseNode.op != GetLocal || !isArrayPrediction(m_jit.graph().getPrediction(baseNode.local())))
1229             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1230
1231         base.use();
1232         property.use();
1233         value.use();
1234         
1235         MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
1236
1237         // Code to handle put beyond array bounds.
1238         silentSpillAllRegisters(scratchReg);
1239         setupStubArguments(baseReg, propertyReg, valueReg);
1240         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1241         JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationPutByValBeyondArrayBounds);
1242         silentFillAllRegisters(scratchReg);
1243         JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
1244
1245         withinArrayBounds.link(&m_jit);
1246
1247         // Get the array storage.
1248         GPRReg storageReg = scratchReg;
1249         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1250
1251         // Check if we're writing to a hole; if so increment m_numValuesInVector.
1252         MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
1253         m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
1254
1255         // If we're writing to a hole we might be growing the array; 
1256         MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
1257         m_jit.add32(TrustedImm32(1), propertyReg);
1258         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
1259         m_jit.sub32(TrustedImm32(1), propertyReg);
1260
1261         lengthDoesNotNeedUpdate.link(&m_jit);
1262         notHoleValue.link(&m_jit);
1263
1264         // Store the value to the array.
1265         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
1266
1267         wasBeyondArrayBounds.link(&m_jit);
1268
1269         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1270         break;
1271     }
1272
1273     case PutByValAlias: {
1274         SpeculateCellOperand base(this, node.child1());
1275         SpeculateStrictInt32Operand property(this, node.child2());
1276         JSValueOperand value(this, node.child3());
1277         GPRTemporary scratch(this);
1278         
1279         GPRReg baseReg = base.gpr();
1280         GPRReg scratchReg = scratch.gpr();
1281
1282         writeBarrier(m_jit, baseReg, scratchReg, WriteBarrierForPropertyAccess);
1283
1284         // Get the array storage.
1285         GPRReg storageReg = scratchReg;
1286         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1287
1288         // Store the value to the array.
1289         GPRReg propertyReg = property.gpr();
1290         GPRReg valueReg = value.gpr();
1291         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
1292
1293         noResult(m_compileIndex);
1294         break;
1295     }
1296
1297     case DFG::Jump: {
1298         BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1299         if (taken != (m_block + 1))
1300             addBranch(m_jit.jump(), taken);
1301         noResult(m_compileIndex);
1302         break;
1303     }
1304
1305     case Branch:
1306         if (isStrictInt32(node.child1())) {
1307             SpeculateStrictInt32Operand op(this, node.child1());
1308             
1309             BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1310             BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
1311             
1312             MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1313             
1314             if (taken == (m_block + 1)) {
1315                 condition = MacroAssembler::Zero;
1316                 BlockIndex tmp = taken;
1317                 taken = notTaken;
1318                 notTaken = tmp;
1319             }
1320             
1321             addBranch(m_jit.branchTest32(condition, op.gpr()), taken);
1322             if (notTaken != (m_block + 1))
1323                 addBranch(m_jit.jump(), notTaken);
1324             
1325             noResult(m_compileIndex);
1326             break;
1327         }
1328         if (shouldSpeculateInteger(node.child1())) {
1329             SpeculateIntegerOperand op(this, node.child1());
1330
1331             BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1332             BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
1333             
1334             MacroAssembler::RelationalCondition condition = MacroAssembler::NotEqual;
1335
1336             if (taken == (m_block + 1)) {
1337                 condition = MacroAssembler::Equal;
1338                 BlockIndex tmp = taken;
1339                 taken = notTaken;
1340                 notTaken = tmp;
1341             }
1342             
1343             addBranch(m_jit.branchPtr(condition, op.gpr(), GPRInfo::tagTypeNumberRegister), taken);
1344
1345             if (notTaken != (m_block + 1))
1346                 addBranch(m_jit.jump(), notTaken);
1347             
1348             noResult(m_compileIndex);
1349             break;
1350         }
1351         emitBranch(node);
1352         break;
1353
1354     case Return: {
1355         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);
1356         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
1357         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
1358
1359 #if ENABLE(DFG_SUCCESS_STATS)
1360         static SamplingCounter counter("SpeculativeJIT");
1361         m_jit.emitCount(counter);
1362 #endif
1363
1364         // Return the result in returnValueGPR.
1365         JSValueOperand op1(this, node.child1());
1366         m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
1367
1368         // Grab the return address.
1369         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, GPRInfo::regT1);
1370         // Restore our caller's "r".
1371         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, GPRInfo::callFrameRegister);
1372         // Return.
1373         m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT1);
1374         m_jit.ret();
1375         
1376         noResult(m_compileIndex);
1377         break;
1378     }
1379
1380     case ConvertThis: {
1381         SpeculateCellOperand thisValue(this, node.child1());
1382
1383         speculationCheck(m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValue.gpr()), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
1384
1385         cellResult(thisValue.gpr(), m_compileIndex);
1386         break;
1387     }
1388
1389     case GetById: {
1390         SpeculateCellOperand base(this, node.child1());
1391         GPRTemporary result(this, base);
1392         
1393         GPRReg baseGPR = base.gpr();
1394         GPRReg resultGPR = result.gpr();
1395         GPRReg scratchGPR;
1396         
1397         if (resultGPR == baseGPR)
1398             scratchGPR = tryAllocate();
1399         else
1400             scratchGPR = resultGPR;
1401         
1402         base.use();
1403
1404         cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
1405
1406         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1407         break;
1408     }
1409         
1410     case GetMethod: {
1411         SpeculateCellOperand base(this, node.child1());
1412         GPRTemporary result(this, base);
1413
1414         GPRReg baseGPR = base.gpr();
1415         GPRReg resultGPR = result.gpr();
1416         GPRReg scratchGPR;
1417         
1418         if (resultGPR == baseGPR)
1419             scratchGPR = tryAllocate();
1420         else
1421             scratchGPR = resultGPR;
1422         
1423         base.use();
1424
1425         cachedGetMethod(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
1426
1427         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1428         break;
1429     }
1430
1431     case PutById: {
1432         SpeculateCellOperand base(this, node.child1());
1433         JSValueOperand value(this, node.child2());
1434         GPRTemporary scratch(this);
1435         
1436         GPRReg baseGPR = base.gpr();
1437         GPRReg valueGPR = value.gpr();
1438         GPRReg scratchGPR = scratch.gpr();
1439         
1440         base.use();
1441         value.use();
1442
1443         cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), NotDirect);
1444         
1445         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1446         break;
1447     }
1448
1449     case PutByIdDirect: {
1450         SpeculateCellOperand base(this, node.child1());
1451         JSValueOperand value(this, node.child2());
1452         GPRTemporary scratch(this);
1453         
1454         GPRReg baseGPR = base.gpr();
1455         GPRReg valueGPR = value.gpr();
1456         GPRReg scratchGPR = scratch.gpr();
1457         
1458         base.use();
1459         value.use();
1460
1461         cachedPutById(baseGPR, valueGPR, scratchGPR, node.identifierNumber(), Direct);
1462
1463         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1464         break;
1465     }
1466
1467     case GetGlobalVar: {
1468         GPRTemporary result(this);
1469
1470         JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
1471         m_jit.loadPtr(globalObject->addressOfRegisters(), result.gpr());
1472         m_jit.loadPtr(JITCompiler::addressForGlobalVar(result.gpr(), node.varNumber()), result.gpr());
1473
1474         jsValueResult(result.gpr(), m_compileIndex);
1475         break;
1476     }
1477
1478     case PutGlobalVar: {
1479         JSValueOperand value(this, node.child1());
1480         GPRTemporary globalObject(this);
1481         GPRTemporary scratch(this);
1482         
1483         GPRReg globalObjectReg = globalObject.gpr();
1484         GPRReg scratchReg = scratch.gpr();
1485
1486         m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectReg);
1487
1488         writeBarrier(m_jit, globalObjectReg, scratchReg, WriteBarrierForVariableAccess);
1489
1490         m_jit.loadPtr(MacroAssembler::Address(globalObjectReg, JSVariableObject::offsetOfRegisters()), scratchReg);
1491         m_jit.storePtr(value.gpr(), JITCompiler::addressForGlobalVar(scratchReg, node.varNumber()));
1492
1493         noResult(m_compileIndex);
1494         break;
1495     }
1496
1497     case CheckHasInstance: {
1498         SpeculateCellOperand base(this, node.child1());
1499         GPRTemporary structure(this);
1500
1501         // Speculate that base 'ImplementsDefaultHasInstance'.
1502         m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
1503         speculationCheck(m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
1504
1505         noResult(m_compileIndex);
1506         break;
1507     }
1508
1509     case InstanceOf: {
1510         SpeculateCellOperand value(this, node.child1());
1511         // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
1512         SpeculateCellOperand prototype(this, node.child3());
1513
1514         GPRTemporary scratch(this);
1515
1516         GPRReg valueReg = value.gpr();
1517         GPRReg prototypeReg = prototype.gpr();
1518         GPRReg scratchReg = scratch.gpr();
1519
1520         // Check that prototype is an object.
1521         m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
1522         speculationCheck(m_jit.branchIfNotObject(scratchReg));
1523
1524         // Initialize scratchReg with the value being checked.
1525         m_jit.move(valueReg, scratchReg);
1526
1527         // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
1528         MacroAssembler::Label loop(&m_jit);
1529         m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
1530         m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset()), scratchReg);
1531         MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
1532         m_jit.branchTestPtr(MacroAssembler::Zero, scratchReg, GPRInfo::tagMaskRegister).linkTo(loop, &m_jit);
1533
1534         // No match - result is false.
1535         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
1536         MacroAssembler::Jump putResult = m_jit.jump();
1537
1538         isInstance.link(&m_jit);
1539         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), scratchReg);
1540
1541         putResult.link(&m_jit);
1542         jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
1543         break;
1544     }
1545
1546     case Phi:
1547         ASSERT_NOT_REACHED();
1548
1549     case Breakpoint:
1550 #if ENABLE(DEBUG_WITH_BREAKPOINT)
1551         m_jit.breakpoint();
1552 #else
1553         ASSERT_NOT_REACHED();
1554 #endif
1555         break;
1556         
1557     case Call:
1558     case Construct:
1559         emitCall(node);
1560         break;
1561
1562     case Resolve: {
1563         flushRegisters();
1564         GPRResult result(this);
1565         callOperation(operationResolve, result.gpr(), identifier(node.identifierNumber()));
1566         jsValueResult(result.gpr(), m_compileIndex);
1567         break;
1568     }
1569
1570     case ResolveBase: {
1571         flushRegisters();
1572         GPRResult result(this);
1573         callOperation(operationResolveBase, result.gpr(), identifier(node.identifierNumber()));
1574         jsValueResult(result.gpr(), m_compileIndex);
1575         break;
1576     }
1577
1578     case ResolveBaseStrictPut: {
1579         flushRegisters();
1580         GPRResult result(this);
1581         callOperation(operationResolveBaseStrictPut, result.gpr(), identifier(node.identifierNumber()));
1582         jsValueResult(result.gpr(), m_compileIndex);
1583         break;
1584     }
1585     }
1586     
1587     if (node.hasResult() && node.mustGenerate())
1588         use(m_compileIndex);
1589 }
1590
1591 void SpeculativeJIT::compileMovHint(Node& node)
1592 {
1593     ASSERT(node.op == SetLocal);
1594     
1595     setNodeIndexForOperand(node.child1(), node.local());
1596     m_lastSetOperand = node.local();
1597 }
1598
1599 void SpeculativeJIT::compile(BasicBlock& block)
1600 {
1601     ASSERT(m_compileOkay);
1602     ASSERT(m_compileIndex == block.begin);
1603     
1604     if (block.isOSRTarget)
1605         m_jit.noticeOSREntry(block);
1606     
1607     m_blockHeads[m_block] = m_jit.label();
1608 #if ENABLE(DFG_JIT_BREAK_ON_EVERY_BLOCK)
1609     m_jit.breakpoint();
1610 #endif
1611     
1612     for (size_t i = 0; i < m_arguments.size(); ++i)
1613         m_arguments[i] = ValueSource();
1614     for (size_t i = 0; i < m_variables.size(); ++i)
1615         m_variables[i] = ValueSource();
1616     m_lastSetOperand = std::numeric_limits<int>::max();
1617     m_bytecodeIndexForOSR = std::numeric_limits<uint32_t>::max();
1618
1619     for (; m_compileIndex < block.end; ++m_compileIndex) {
1620         Node& node = m_jit.graph()[m_compileIndex];
1621         m_bytecodeIndexForOSR = node.codeOrigin.bytecodeIndex();
1622         if (!node.shouldGenerate()) {
1623 #if ENABLE(DFG_DEBUG_VERBOSE)
1624             fprintf(stderr, "SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x     ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex(), m_jit.debugOffset());
1625 #endif
1626             if (node.op == SetLocal)
1627                 compileMovHint(node);
1628         } else {
1629             
1630 #if ENABLE(DFG_DEBUG_VERBOSE)
1631             fprintf(stderr, "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x   ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex(), m_jit.debugOffset());
1632 #endif
1633 #if ENABLE(DFG_JIT_BREAK_ON_EVERY_NODE)
1634             m_jit.breakpoint();
1635 #endif
1636             checkConsistency();
1637             compile(node);
1638             if (!m_compileOkay) {
1639 #if ENABLE(DYNAMIC_TERMINATE_SPECULATION)
1640                 m_compileOkay = true;
1641                 m_compileIndex = block.end;
1642                 clearGenerationInfo();
1643 #endif
1644                 return;
1645             }
1646             
1647 #if ENABLE(DFG_DEBUG_VERBOSE)
1648             if (node.hasResult()) {
1649                 GenerationInfo& info = m_generationInfo[node.virtualRegister()];
1650                 fprintf(stderr, "-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)node.virtualRegister());
1651                 if (info.registerFormat() != DataFormatNone) {
1652                     if (info.registerFormat() == DataFormatDouble)
1653                         fprintf(stderr, ", %s", FPRInfo::debugName(info.fpr()));
1654                     else
1655                         fprintf(stderr, ", %s", GPRInfo::debugName(info.gpr()));
1656                 }
1657                 fprintf(stderr, "    ");
1658             } else
1659                 fprintf(stderr, "    ");
1660 #endif
1661         }
1662         
1663 #if ENABLE(DFG_VERBOSE_VALUE_RECOVERIES)
1664         for (int operand = -m_arguments.size() - RegisterFile::CallFrameHeaderSize; operand < -RegisterFile::CallFrameHeaderSize; ++operand)
1665             computeValueRecoveryFor(operand).dump(stderr);
1666         
1667         fprintf(stderr, " : ");
1668         
1669         for (int operand = 0; operand < (int)m_variables.size(); ++operand)
1670             computeValueRecoveryFor(operand).dump(stderr);
1671 #endif
1672       
1673 #if ENABLE(DFG_DEBUG_VERBOSE)
1674         fprintf(stderr, "\n");
1675 #endif
1676         
1677         if (node.shouldGenerate())
1678             checkConsistency();
1679     }
1680 }
1681
1682 // If we are making type predictions about our arguments then
1683 // we need to check that they are correct on function entry.
1684 void SpeculativeJIT::checkArgumentTypes()
1685 {
1686     ASSERT(!m_compileIndex);
1687     m_bytecodeIndexForOSR = 0;
1688     for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) {
1689         VirtualRegister virtualRegister = (VirtualRegister)(m_jit.codeBlock()->thisRegister() + i);
1690         PredictedType predictedType = m_jit.graph().getPrediction(virtualRegister);
1691         if (isInt32Prediction(predictedType))
1692             speculationCheck(m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
1693         else if (isArrayPrediction(predictedType)) {
1694             GPRTemporary temp(this);
1695             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1696             speculationCheck(m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1697             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1698         }
1699     }
1700 }
1701
1702 // For any vars that we will be treating as numeric, write 0 to
1703 // the var on entry. Throughout the block we will only read/write
1704 // to the payload, by writing the tag now we prevent the GC from
1705 // misinterpreting values as pointers.
1706 void SpeculativeJIT::initializeVariableTypes()
1707 {
1708     ASSERT(!m_compileIndex);
1709     for (int var = 0; var < (int)m_jit.graph().predictions().numberOfVariables(); ++var) {
1710         if (isInt32Prediction(m_jit.graph().getPrediction(var)))
1711             m_jit.storePtr(GPRInfo::tagTypeNumberRegister, JITCompiler::addressFor((VirtualRegister)var));
1712     }
1713 }
1714
1715 bool SpeculativeJIT::compile()
1716 {
1717     checkArgumentTypes();
1718     initializeVariableTypes();
1719
1720     ASSERT(!m_compileIndex);
1721     for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
1722         compile(*m_jit.graph().m_blocks[m_block]);
1723 #if !ENABLE(DYNAMIC_TERMINATE_SPECULATION)
1724         if (!m_compileOkay)
1725             return false;
1726 #endif
1727     }
1728     linkBranches();
1729     return true;
1730 }
1731
1732 ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
1733 {
1734     if (!valueSource.isSet())
1735         return ValueRecovery::alreadyInRegisterFile();
1736
1737     if (m_jit.isConstant(valueSource.nodeIndex()))
1738         return ValueRecovery::constant(m_jit.valueOfJSConstant(valueSource.nodeIndex()));
1739     
1740     Node* nodePtr = &m_jit.graph()[valueSource.nodeIndex()];
1741     if (!nodePtr->shouldGenerate()) {
1742         // It's legitimately dead. As in, nobody will ever use this node, or operand,
1743         // ever. Set it to Undefined to make the GC happy after the OSR.
1744         return ValueRecovery::constant(jsUndefined());
1745     }
1746     
1747     GenerationInfo* infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1748     if (!infoPtr->alive() || infoPtr->nodeIndex() != valueSource.nodeIndex()) {
1749         // Try to see if there is an alternate node that would contain the value we want.
1750         // There are four possibilities:
1751         //
1752         // ValueToNumber: If the only live version of the value is a ValueToNumber node
1753         //    then it means that all remaining uses of the value would have performed a
1754         //    ValueToNumber conversion anyway. Thus, we can substitute ValueToNumber.
1755         //
1756         // ValueToInt32: Likewise, if the only remaining live version of the value is
1757         //    ValueToInt32, then we can use it. But if there is both a ValueToInt32
1758         //    and a ValueToNumber, then we better go with ValueToNumber because it
1759         //    means that some remaining uses would have converted to number while
1760         //    others would have converted to Int32.
1761         //
1762         // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
1763         //    then the only remaining uses are ones that want a properly formed number
1764         //    rather than a UInt32 intermediate.
1765         //
1766         // The reverse of the above: This node could be a UInt32ToNumber, but its
1767         //    alternative is still alive. This means that the only remaining uses of
1768         //    the number would be fine with a UInt32 intermediate.
1769         
1770         bool found = false;
1771         
1772         if (nodePtr->op == UInt32ToNumber) {
1773             NodeIndex nodeIndex = nodePtr->child1();
1774             nodePtr = &m_jit.graph()[nodeIndex];
1775             infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1776             if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
1777                 found = true;
1778         }
1779         
1780         if (!found) {
1781             NodeIndex valueToNumberIndex = NoNode;
1782             NodeIndex valueToInt32Index = NoNode;
1783             NodeIndex uint32ToNumberIndex = NoNode;
1784             
1785             for (unsigned virtualRegister = 0; virtualRegister < m_generationInfo.size(); ++virtualRegister) {
1786                 GenerationInfo& info = m_generationInfo[virtualRegister];
1787                 if (!info.alive())
1788                     continue;
1789                 if (info.nodeIndex() == NoNode)
1790                     continue;
1791                 Node& node = m_jit.graph()[info.nodeIndex()];
1792                 if (node.child1Unchecked() != valueSource.nodeIndex())
1793                     continue;
1794                 switch (node.op) {
1795                 case ValueToNumber:
1796                 case ValueToDouble:
1797                     valueToNumberIndex = info.nodeIndex();
1798                     break;
1799                 case ValueToInt32:
1800                     valueToInt32Index = info.nodeIndex();
1801                     break;
1802                 case UInt32ToNumber:
1803                     uint32ToNumberIndex = info.nodeIndex();
1804                     break;
1805                 default:
1806                     break;
1807                 }
1808             }
1809             
1810             NodeIndex nodeIndexToUse;
1811             if (valueToNumberIndex != NoNode)
1812                 nodeIndexToUse = valueToNumberIndex;
1813             else if (valueToInt32Index != NoNode)
1814                 nodeIndexToUse = valueToInt32Index;
1815             else if (uint32ToNumberIndex != NoNode)
1816                 nodeIndexToUse = uint32ToNumberIndex;
1817             else
1818                 nodeIndexToUse = NoNode;
1819             
1820             if (nodeIndexToUse != NoNode) {
1821                 nodePtr = &m_jit.graph()[nodeIndexToUse];
1822                 infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1823                 ASSERT(infoPtr->alive() && infoPtr->nodeIndex() == nodeIndexToUse);
1824                 found = true;
1825             }
1826         }
1827         
1828         if (!found)
1829             return ValueRecovery::constant(jsUndefined());
1830     }
1831     
1832     ASSERT(infoPtr->alive());
1833
1834     if (infoPtr->registerFormat() != DataFormatNone) {
1835         if (infoPtr->registerFormat() == DataFormatDouble)
1836             return ValueRecovery::inFPR(infoPtr->fpr());
1837         return ValueRecovery::inGPR(infoPtr->gpr(), infoPtr->registerFormat());
1838     }
1839     if (infoPtr->spillFormat() != DataFormatNone)
1840         return ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(nodePtr->virtualRegister()));
1841     
1842     ASSERT_NOT_REACHED();
1843     return ValueRecovery();
1844 }
1845
1846 } } // namespace JSC::DFG
1847
1848 #endif