DFG CSE should be able to eliminate unnecessary flushes of arguments and captured...
[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 #include "Arguments.h"
32 #include "DFGSlowPathGenerator.h"
33 #include "LinkBuffer.h"
34
35 namespace JSC { namespace DFG {
36
37 SpeculativeJIT::SpeculativeJIT(JITCompiler& jit)
38     : m_compileOkay(true)
39     , m_jit(jit)
40     , m_compileIndex(0)
41     , m_indexInBlock(0)
42     , m_generationInfo(m_jit.codeBlock()->m_numCalleeRegisters)
43     , m_blockHeads(jit.graph().m_blocks.size())
44     , m_arguments(jit.codeBlock()->numParameters())
45     , m_variables(jit.graph().m_localVars)
46     , m_lastSetOperand(std::numeric_limits<int>::max())
47     , m_state(m_jit.graph())
48     , m_isCheckingArgumentTypes(false)
49 {
50 }
51
52 SpeculativeJIT::~SpeculativeJIT()
53 {
54     WTF::deleteAllValues(m_slowPathGenerators);
55 }
56
57 void SpeculativeJIT::addSlowPathGenerator(PassOwnPtr<SlowPathGenerator> slowPathGenerator)
58 {
59     m_slowPathGenerators.append(slowPathGenerator.leakPtr());
60 }
61
62 void SpeculativeJIT::runSlowPathGenerators()
63 {
64 #if DFG_ENABLE(DEBUG_VERBOSE)
65     dataLog("Running %lu slow path generators.\n", m_slowPathGenerators.size());
66 #endif
67     for (unsigned i = 0; i < m_slowPathGenerators.size(); ++i)
68         m_slowPathGenerators[i]->generate(this);
69 }
70
71 // On Windows we need to wrap fmod; on other platforms we can call it directly.
72 // On ARMv7 we assert that all function pointers have to low bit set (point to thumb code).
73 #if CALLING_CONVENTION_IS_STDCALL || CPU(ARM_THUMB2)
74 static double DFG_OPERATION fmodAsDFGOperation(double x, double y)
75 {
76     return fmod(x, y);
77 }
78 #else
79 #define fmodAsDFGOperation fmod
80 #endif
81
82 void SpeculativeJIT::clearGenerationInfo()
83 {
84     for (unsigned i = 0; i < m_generationInfo.size(); ++i)
85         m_generationInfo[i] = GenerationInfo();
86     m_gprs = RegisterBank<GPRInfo>();
87     m_fprs = RegisterBank<FPRInfo>();
88 }
89
90 GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
91 {
92     Node& node = m_jit.graph()[nodeIndex];
93     VirtualRegister virtualRegister = node.virtualRegister();
94     GenerationInfo& info = m_generationInfo[virtualRegister];
95     
96     switch (info.registerFormat()) {
97     case DataFormatNone: {
98         if (info.spillFormat() == DataFormatStorage) {
99             GPRReg gpr = allocate();
100             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
101             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
102             info.fillStorage(gpr);
103             return gpr;
104         }
105         
106         // Must be a cell; fill it as a cell and then return the pointer.
107         return fillSpeculateCell(nodeIndex);
108     }
109         
110     case DataFormatStorage: {
111         GPRReg gpr = info.gpr();
112         m_gprs.lock(gpr);
113         return gpr;
114     }
115         
116     default:
117         return fillSpeculateCell(nodeIndex);
118     }
119 }
120
121 void SpeculativeJIT::useChildren(Node& node)
122 {
123     if (node.flags() & NodeHasVarArgs) {
124         for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
125             use(m_jit.graph().m_varArgChildren[childIdx]);
126     } else {
127         Edge child1 = node.child1();
128         if (!child1) {
129             ASSERT(!node.child2() && !node.child3());
130             return;
131         }
132         use(child1);
133         
134         Edge child2 = node.child2();
135         if (!child2) {
136             ASSERT(!node.child3());
137             return;
138         }
139         use(child2);
140         
141         Edge child3 = node.child3();
142         if (!child3)
143             return;
144         use(child3);
145     }
146 }
147
148 bool SpeculativeJIT::isStrictInt32(NodeIndex nodeIndex)
149 {
150     if (isInt32Constant(nodeIndex))
151         return true;
152     
153     Node& node = m_jit.graph()[nodeIndex];
154     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
155     
156     return info.registerFormat() == DataFormatInteger;
157 }
158
159 bool SpeculativeJIT::isKnownInteger(NodeIndex nodeIndex)
160 {
161     if (isInt32Constant(nodeIndex))
162         return true;
163
164     Node& node = m_jit.graph()[nodeIndex];
165     
166     if (node.hasInt32Result())
167         return true;
168     
169     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
170
171     return info.isJSInteger();
172 }
173
174 bool SpeculativeJIT::isKnownNumeric(NodeIndex nodeIndex)
175 {
176     if (isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex))
177         return true;
178
179     Node& node = m_jit.graph()[nodeIndex];
180     
181     if (node.hasNumberResult())
182         return true;
183     
184     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
185
186     return info.isJSInteger() || info.isJSDouble();
187 }
188
189 bool SpeculativeJIT::isKnownCell(NodeIndex nodeIndex)
190 {
191     return m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()].isJSCell();
192 }
193
194 bool SpeculativeJIT::isKnownNotCell(NodeIndex nodeIndex)
195 {
196     Node& node = m_jit.graph()[nodeIndex];
197     VirtualRegister virtualRegister = node.virtualRegister();
198     GenerationInfo& info = m_generationInfo[virtualRegister];
199     if (node.hasConstant() && !valueOfJSConstant(nodeIndex).isCell())
200         return true;
201     return !(info.isJSCell() || info.isUnknownJS());
202 }
203
204 bool SpeculativeJIT::isKnownNotInteger(NodeIndex nodeIndex)
205 {
206     Node& node = m_jit.graph()[nodeIndex];
207     VirtualRegister virtualRegister = node.virtualRegister();
208     GenerationInfo& info = m_generationInfo[virtualRegister];
209     
210     return info.isJSDouble() || info.isJSCell() || info.isJSBoolean()
211         || (node.hasConstant() && !valueOfJSConstant(nodeIndex).isInt32());
212 }
213
214 bool SpeculativeJIT::isKnownNotNumber(NodeIndex nodeIndex)
215 {
216     Node& node = m_jit.graph()[nodeIndex];
217     VirtualRegister virtualRegister = node.virtualRegister();
218     GenerationInfo& info = m_generationInfo[virtualRegister];
219     
220     return (!info.isJSDouble() && !info.isJSInteger() && !info.isUnknownJS())
221         || (node.hasConstant() && !isNumberConstant(nodeIndex));
222 }
223
224 void SpeculativeJIT::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
225 {
226     UNUSED_PARAM(jit);
227     UNUSED_PARAM(owner);
228     UNUSED_PARAM(scratch1);
229     UNUSED_PARAM(scratch2);
230     UNUSED_PARAM(useKind);
231     ASSERT(owner != scratch1);
232     ASSERT(owner != scratch2);
233     ASSERT(scratch1 != scratch2);
234
235 #if ENABLE(WRITE_BARRIER_PROFILING)
236     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
237 #endif
238     markCellCard(jit, owner, scratch1, scratch2);
239 }
240
241 void SpeculativeJIT::markCellCard(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
242 {
243     UNUSED_PARAM(jit);
244     UNUSED_PARAM(owner);
245     UNUSED_PARAM(scratch1);
246     UNUSED_PARAM(scratch2);
247     
248 #if ENABLE(GGC)
249     jit.move(owner, scratch1);
250     jit.andPtr(TrustedImm32(static_cast<int32_t>(MarkedBlock::blockMask)), scratch1);
251     jit.move(owner, scratch2);
252     // consume additional 8 bits as we're using an approximate filter
253     jit.rshift32(TrustedImm32(MarkedBlock::atomShift + 8), scratch2);
254     jit.andPtr(TrustedImm32(MarkedBlock::atomMask >> 8), scratch2);
255     MacroAssembler::Jump filter = jit.branchTest8(MacroAssembler::Zero, MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfMarks()));
256     jit.move(owner, scratch2);
257     jit.rshift32(TrustedImm32(MarkedBlock::cardShift), scratch2);
258     jit.andPtr(TrustedImm32(MarkedBlock::cardMask), scratch2);
259     jit.store8(TrustedImm32(1), MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfCards()));
260     filter.link(&jit);
261 #endif
262 }
263
264 void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
265 {
266     UNUSED_PARAM(ownerGPR);
267     UNUSED_PARAM(valueGPR);
268     UNUSED_PARAM(scratch1);
269     UNUSED_PARAM(scratch2);
270     UNUSED_PARAM(useKind);
271
272     if (isKnownNotCell(valueUse.index()))
273         return;
274
275 #if ENABLE(WRITE_BARRIER_PROFILING)
276     JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
277 #endif
278
279 #if ENABLE(GGC)
280     GPRTemporary temp1;
281     GPRTemporary temp2;
282     if (scratch1 == InvalidGPRReg) {
283         GPRTemporary scratchGPR(this);
284         temp1.adopt(scratchGPR);
285         scratch1 = temp1.gpr();
286     }
287     if (scratch2 == InvalidGPRReg) {
288         GPRTemporary scratchGPR(this);
289         temp2.adopt(scratchGPR);
290         scratch2 = temp2.gpr();
291     }
292     
293     JITCompiler::Jump rhsNotCell;
294     bool hadCellCheck = false;
295     if (!isKnownCell(valueUse.index()) && !isCellPrediction(m_jit.getPrediction(valueUse.index()))) {
296         hadCellCheck = true;
297         rhsNotCell = m_jit.branchIfNotCell(valueGPR);
298     }
299
300     markCellCard(m_jit, ownerGPR, scratch1, scratch2);
301
302     if (hadCellCheck)
303         rhsNotCell.link(&m_jit);
304 #endif
305 }
306
307 void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
308 {
309     UNUSED_PARAM(ownerGPR);
310     UNUSED_PARAM(value);
311     UNUSED_PARAM(scratch1);
312     UNUSED_PARAM(scratch2);
313     UNUSED_PARAM(useKind);
314     
315     if (Heap::isMarked(value))
316         return;
317
318 #if ENABLE(WRITE_BARRIER_PROFILING)
319     JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
320 #endif
321
322 #if ENABLE(GGC)
323     GPRTemporary temp1;
324     GPRTemporary temp2;
325     if (scratch1 == InvalidGPRReg) {
326         GPRTemporary scratchGPR(this);
327         temp1.adopt(scratchGPR);
328         scratch1 = temp1.gpr();
329     }
330     if (scratch2 == InvalidGPRReg) {
331         GPRTemporary scratchGPR(this);
332         temp2.adopt(scratchGPR);
333         scratch2 = temp2.gpr();
334     }
335
336     markCellCard(m_jit, ownerGPR, scratch1, scratch2);
337 #endif
338 }
339
340 void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind useKind, GPRReg scratch)
341 {
342     UNUSED_PARAM(owner);
343     UNUSED_PARAM(valueGPR);
344     UNUSED_PARAM(scratch);
345     UNUSED_PARAM(useKind);
346
347     if (isKnownNotCell(valueUse.index()))
348         return;
349
350 #if ENABLE(WRITE_BARRIER_PROFILING)
351     JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
352 #endif
353
354 #if ENABLE(GGC)
355     JITCompiler::Jump rhsNotCell;
356     bool hadCellCheck = false;
357     if (!isKnownCell(valueUse.index()) && !isCellPrediction(m_jit.getPrediction(valueUse.index()))) {
358         hadCellCheck = true;
359         rhsNotCell = m_jit.branchIfNotCell(valueGPR);
360     }
361     
362     GPRTemporary temp;
363     if (scratch == InvalidGPRReg) {
364         GPRTemporary scratchGPR(this);
365         temp.adopt(scratchGPR);
366         scratch = temp.gpr();
367     }
368
369     uint8_t* cardAddress = Heap::addressOfCardFor(owner);
370     m_jit.move(JITCompiler::TrustedImmPtr(cardAddress), scratch);
371     m_jit.store8(JITCompiler::TrustedImm32(1), JITCompiler::Address(scratch));
372
373     if (hadCellCheck)
374         rhsNotCell.link(&m_jit);
375 #endif
376 }
377
378 bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
379 {
380     unsigned branchIndexInBlock = detectPeepHoleBranch();
381     if (branchIndexInBlock != UINT_MAX) {
382         NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
383
384         ASSERT(node.adjustedRefCount() == 1);
385         
386         nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
387     
388         m_indexInBlock = branchIndexInBlock;
389         m_compileIndex = branchNodeIndex;
390         
391         return true;
392     }
393     
394     nonSpeculativeNonPeepholeCompare(node, cond, helperFunction);
395     
396     return false;
397 }
398
399 bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert)
400 {
401     unsigned branchIndexInBlock = detectPeepHoleBranch();
402     if (branchIndexInBlock != UINT_MAX) {
403         NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
404
405         ASSERT(node.adjustedRefCount() == 1);
406         
407         nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
408     
409         m_indexInBlock = branchIndexInBlock;
410         m_compileIndex = branchNodeIndex;
411         
412         return true;
413     }
414     
415     nonSpeculativeNonPeepholeStrictEq(node, invert);
416     
417     return false;
418 }
419
420 #ifndef NDEBUG
421 static const char* dataFormatString(DataFormat format)
422 {
423     // These values correspond to the DataFormat enum.
424     const char* strings[] = {
425         "[  ]",
426         "[ i]",
427         "[ d]",
428         "[ c]",
429         "Err!",
430         "Err!",
431         "Err!",
432         "Err!",
433         "[J ]",
434         "[Ji]",
435         "[Jd]",
436         "[Jc]",
437         "Err!",
438         "Err!",
439         "Err!",
440         "Err!",
441     };
442     return strings[format];
443 }
444
445 void SpeculativeJIT::dump(const char* label)
446 {
447     if (label)
448         dataLog("<%s>\n", label);
449
450     dataLog("  gprs:\n");
451     m_gprs.dump();
452     dataLog("  fprs:\n");
453     m_fprs.dump();
454     dataLog("  VirtualRegisters:\n");
455     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
456         GenerationInfo& info = m_generationInfo[i];
457         if (info.alive())
458             dataLog("    % 3d:%s%s", i, dataFormatString(info.registerFormat()), dataFormatString(info.spillFormat()));
459         else
460             dataLog("    % 3d:[__][__]", i);
461         if (info.registerFormat() == DataFormatDouble)
462             dataLog(":fpr%d\n", info.fpr());
463         else if (info.registerFormat() != DataFormatNone
464 #if USE(JSVALUE32_64)
465             && !(info.registerFormat() & DataFormatJS)
466 #endif
467             ) {
468             ASSERT(info.gpr() != InvalidGPRReg);
469             dataLog(":%s\n", GPRInfo::debugName(info.gpr()));
470         } else
471             dataLog("\n");
472     }
473     if (label)
474         dataLog("</%s>\n", label);
475 }
476 #endif
477
478
479 #if DFG_ENABLE(CONSISTENCY_CHECK)
480 void SpeculativeJIT::checkConsistency()
481 {
482     bool failed = false;
483
484     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
485         if (iter.isLocked()) {
486             dataLog("DFG_CONSISTENCY_CHECK failed: gpr %s is locked.\n", iter.debugName());
487             failed = true;
488         }
489     }
490     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
491         if (iter.isLocked()) {
492             dataLog("DFG_CONSISTENCY_CHECK failed: fpr %s is locked.\n", iter.debugName());
493             failed = true;
494         }
495     }
496
497     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
498         VirtualRegister virtualRegister = (VirtualRegister)i;
499         GenerationInfo& info = m_generationInfo[virtualRegister];
500         if (!info.alive())
501             continue;
502         switch (info.registerFormat()) {
503         case DataFormatNone:
504             break;
505         case DataFormatJS:
506         case DataFormatJSInteger:
507         case DataFormatJSDouble:
508         case DataFormatJSCell:
509         case DataFormatJSBoolean:
510 #if USE(JSVALUE32_64)
511             break;
512 #endif
513         case DataFormatInteger:
514         case DataFormatCell:
515         case DataFormatBoolean:
516         case DataFormatStorage: {
517             GPRReg gpr = info.gpr();
518             ASSERT(gpr != InvalidGPRReg);
519             if (m_gprs.name(gpr) != virtualRegister) {
520                 dataLog("DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (gpr %s).\n", virtualRegister, GPRInfo::debugName(gpr));
521                 failed = true;
522             }
523             break;
524         }
525         case DataFormatDouble: {
526             FPRReg fpr = info.fpr();
527             ASSERT(fpr != InvalidFPRReg);
528             if (m_fprs.name(fpr) != virtualRegister) {
529                 dataLog("DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (fpr %s).\n", virtualRegister, FPRInfo::debugName(fpr));
530                 failed = true;
531             }
532             break;
533         }
534         }
535     }
536
537     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
538         VirtualRegister virtualRegister = iter.name();
539         if (virtualRegister == InvalidVirtualRegister)
540             continue;
541
542         GenerationInfo& info = m_generationInfo[virtualRegister];
543 #if USE(JSVALUE64)
544         if (iter.regID() != info.gpr()) {
545             dataLog("DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
546             failed = true;
547         }
548 #else
549         if (!(info.registerFormat() & DataFormatJS)) {
550             if (iter.regID() != info.gpr()) {
551                 dataLog("DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
552                 failed = true;
553             }
554         } else {
555             if (iter.regID() != info.tagGPR() && iter.regID() != info.payloadGPR()) {
556                 dataLog("DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
557                 failed = true;
558             }
559         }
560 #endif
561     }
562
563     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
564         VirtualRegister virtualRegister = iter.name();
565         if (virtualRegister == InvalidVirtualRegister)
566             continue;
567
568         GenerationInfo& info = m_generationInfo[virtualRegister];
569         if (iter.regID() != info.fpr()) {
570             dataLog("DFG_CONSISTENCY_CHECK failed: name mismatch for fpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
571             failed = true;
572         }
573     }
574
575     if (failed) {
576         dump();
577         CRASH();
578     }
579 }
580 #endif
581
582 GPRTemporary::GPRTemporary()
583     : m_jit(0)
584     , m_gpr(InvalidGPRReg)
585 {
586 }
587
588 GPRTemporary::GPRTemporary(SpeculativeJIT* jit)
589     : m_jit(jit)
590     , m_gpr(InvalidGPRReg)
591 {
592     m_gpr = m_jit->allocate();
593 }
594
595 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, GPRReg specific)
596     : m_jit(jit)
597     , m_gpr(InvalidGPRReg)
598 {
599     m_gpr = m_jit->allocate(specific);
600 }
601
602 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateIntegerOperand& op1)
603     : m_jit(jit)
604     , m_gpr(InvalidGPRReg)
605 {
606     if (m_jit->canReuse(op1.index()))
607         m_gpr = m_jit->reuse(op1.gpr());
608     else
609         m_gpr = m_jit->allocate();
610 }
611
612 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateIntegerOperand& op1, SpeculateIntegerOperand& op2)
613     : m_jit(jit)
614     , m_gpr(InvalidGPRReg)
615 {
616     if (m_jit->canReuse(op1.index()))
617         m_gpr = m_jit->reuse(op1.gpr());
618     else if (m_jit->canReuse(op2.index()))
619         m_gpr = m_jit->reuse(op2.gpr());
620     else
621         m_gpr = m_jit->allocate();
622 }
623
624 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateStrictInt32Operand& op1)
625     : m_jit(jit)
626     , m_gpr(InvalidGPRReg)
627 {
628     if (m_jit->canReuse(op1.index()))
629         m_gpr = m_jit->reuse(op1.gpr());
630     else
631         m_gpr = m_jit->allocate();
632 }
633
634 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, IntegerOperand& op1)
635     : m_jit(jit)
636     , m_gpr(InvalidGPRReg)
637 {
638     if (m_jit->canReuse(op1.index()))
639         m_gpr = m_jit->reuse(op1.gpr());
640     else
641         m_gpr = m_jit->allocate();
642 }
643
644 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, IntegerOperand& op1, IntegerOperand& op2)
645     : m_jit(jit)
646     , m_gpr(InvalidGPRReg)
647 {
648     if (m_jit->canReuse(op1.index()))
649         m_gpr = m_jit->reuse(op1.gpr());
650     else if (m_jit->canReuse(op2.index()))
651         m_gpr = m_jit->reuse(op2.gpr());
652     else
653         m_gpr = m_jit->allocate();
654 }
655
656 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateCellOperand& op1)
657     : m_jit(jit)
658     , m_gpr(InvalidGPRReg)
659 {
660     if (m_jit->canReuse(op1.index()))
661         m_gpr = m_jit->reuse(op1.gpr());
662     else
663         m_gpr = m_jit->allocate();
664 }
665
666 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateBooleanOperand& op1)
667     : m_jit(jit)
668     , m_gpr(InvalidGPRReg)
669 {
670     if (m_jit->canReuse(op1.index()))
671         m_gpr = m_jit->reuse(op1.gpr());
672     else
673         m_gpr = m_jit->allocate();
674 }
675
676 #if USE(JSVALUE64)
677 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
678     : m_jit(jit)
679     , m_gpr(InvalidGPRReg)
680 {
681     if (m_jit->canReuse(op1.index()))
682         m_gpr = m_jit->reuse(op1.gpr());
683     else
684         m_gpr = m_jit->allocate();
685 }
686 #else
687 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1, bool tag)
688     : m_jit(jit)
689     , m_gpr(InvalidGPRReg)
690 {
691     if (!op1.isDouble() && m_jit->canReuse(op1.index()))
692         m_gpr = m_jit->reuse(tag ? op1.tagGPR() : op1.payloadGPR());
693     else
694         m_gpr = m_jit->allocate();
695 }
696 #endif
697
698 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, StorageOperand& op1)
699     : m_jit(jit)
700     , m_gpr(InvalidGPRReg)
701 {
702     if (m_jit->canReuse(op1.index()))
703         m_gpr = m_jit->reuse(op1.gpr());
704     else
705         m_gpr = m_jit->allocate();
706 }
707
708 void GPRTemporary::adopt(GPRTemporary& other)
709 {
710     ASSERT(!m_jit);
711     ASSERT(m_gpr == InvalidGPRReg);
712     ASSERT(other.m_jit);
713     ASSERT(other.m_gpr != InvalidGPRReg);
714     m_jit = other.m_jit;
715     m_gpr = other.m_gpr;
716     other.m_jit = 0;
717     other.m_gpr = InvalidGPRReg;
718 }
719
720 FPRTemporary::FPRTemporary(SpeculativeJIT* jit)
721     : m_jit(jit)
722     , m_fpr(InvalidFPRReg)
723 {
724     m_fpr = m_jit->fprAllocate();
725 }
726
727 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, DoubleOperand& op1)
728     : m_jit(jit)
729     , m_fpr(InvalidFPRReg)
730 {
731     if (m_jit->canReuse(op1.index()))
732         m_fpr = m_jit->reuse(op1.fpr());
733     else
734         m_fpr = m_jit->fprAllocate();
735 }
736
737 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, DoubleOperand& op1, DoubleOperand& op2)
738     : m_jit(jit)
739     , m_fpr(InvalidFPRReg)
740 {
741     if (m_jit->canReuse(op1.index()))
742         m_fpr = m_jit->reuse(op1.fpr());
743     else if (m_jit->canReuse(op2.index()))
744         m_fpr = m_jit->reuse(op2.fpr());
745     else
746         m_fpr = m_jit->fprAllocate();
747 }
748
749 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, SpeculateDoubleOperand& op1)
750     : m_jit(jit)
751     , m_fpr(InvalidFPRReg)
752 {
753     if (m_jit->canReuse(op1.index()))
754         m_fpr = m_jit->reuse(op1.fpr());
755     else
756         m_fpr = m_jit->fprAllocate();
757 }
758
759 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, SpeculateDoubleOperand& op1, SpeculateDoubleOperand& op2)
760     : m_jit(jit)
761     , m_fpr(InvalidFPRReg)
762 {
763     if (m_jit->canReuse(op1.index()))
764         m_fpr = m_jit->reuse(op1.fpr());
765     else if (m_jit->canReuse(op2.index()))
766         m_fpr = m_jit->reuse(op2.fpr());
767     else
768         m_fpr = m_jit->fprAllocate();
769 }
770
771 #if USE(JSVALUE32_64)
772 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
773     : m_jit(jit)
774     , m_fpr(InvalidFPRReg)
775 {
776     if (op1.isDouble() && m_jit->canReuse(op1.index()))
777         m_fpr = m_jit->reuse(op1.fpr());
778     else
779         m_fpr = m_jit->fprAllocate();
780 }
781 #endif
782
783 void ValueSource::dump(FILE* out) const
784 {
785     switch (kind()) {
786     case SourceNotSet:
787         fprintf(out, "NotSet");
788         break;
789     case SourceIsDead:
790         fprintf(out, "IsDead");
791         break;
792     case ValueInRegisterFile:
793         fprintf(out, "InRegFile");
794         break;
795     case Int32InRegisterFile:
796         fprintf(out, "Int32");
797         break;
798     case CellInRegisterFile:
799         fprintf(out, "Cell");
800         break;
801     case BooleanInRegisterFile:
802         fprintf(out, "Bool");
803         break;
804     case DoubleInRegisterFile:
805         fprintf(out, "Double");
806         break;
807     case ArgumentsSource:
808         fprintf(out, "Arguments");
809         break;
810     case HaveNode:
811         fprintf(out, "Node(%d)", m_nodeIndex);
812         break;
813     }
814 }
815
816 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
817 {
818     Node& branchNode = at(branchNodeIndex);
819     BlockIndex taken = branchNode.takenBlockIndex();
820     BlockIndex notTaken = branchNode.notTakenBlockIndex();
821     
822     SpeculateDoubleOperand op1(this, node.child1());
823     SpeculateDoubleOperand op2(this, node.child2());
824     
825     branchDouble(condition, op1.fpr(), op2.fpr(), taken);
826     jump(notTaken);
827 }
828
829 void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, const ClassInfo* classInfo, PredictionChecker predictionCheck)
830 {
831     Node& branchNode = at(branchNodeIndex);
832     BlockIndex taken = branchNode.takenBlockIndex();
833     BlockIndex notTaken = branchNode.notTakenBlockIndex();
834
835     MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
836     
837     if (taken == nextBlock()) {
838         condition = MacroAssembler::NotEqual;
839         BlockIndex tmp = taken;
840         taken = notTaken;
841         notTaken = tmp;
842     }
843
844     SpeculateCellOperand op1(this, node.child1());
845     SpeculateCellOperand op2(this, node.child2());
846     
847     GPRReg op1GPR = op1.gpr();
848     GPRReg op2GPR = op2.gpr();
849     
850     if (!predictionCheck(m_state.forNode(node.child1()).m_type))
851         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
852     if (!predictionCheck(m_state.forNode(node.child2()).m_type))
853         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2().index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(classInfo)));
854     
855     branchPtr(condition, op1GPR, op2GPR, taken);
856     jump(notTaken);
857 }
858
859 void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition condition)
860 {
861     Node& branchNode = at(branchNodeIndex);
862     BlockIndex taken = branchNode.takenBlockIndex();
863     BlockIndex notTaken = branchNode.notTakenBlockIndex();
864
865     // The branch instruction will branch to the taken block.
866     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
867     if (taken == nextBlock()) {
868         condition = JITCompiler::invert(condition);
869         BlockIndex tmp = taken;
870         taken = notTaken;
871         notTaken = tmp;
872     }
873
874     if (isInt32Constant(node.child1().index())) {
875         int32_t imm = valueOfInt32Constant(node.child1().index());
876         SpeculateIntegerOperand op2(this, node.child2());
877         branch32(condition, JITCompiler::Imm32(imm), op2.gpr(), taken);
878     } else if (isInt32Constant(node.child2().index())) {
879         SpeculateIntegerOperand op1(this, node.child1());
880         int32_t imm = valueOfInt32Constant(node.child2().index());
881         branch32(condition, op1.gpr(), JITCompiler::Imm32(imm), taken);
882     } else {
883         SpeculateIntegerOperand op1(this, node.child1());
884         SpeculateIntegerOperand op2(this, node.child2());
885         branch32(condition, op1.gpr(), op2.gpr(), taken);
886     }
887
888     jump(notTaken);
889 }
890
891 // Returns true if the compare is fused with a subsequent branch.
892 bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
893 {
894     // Fused compare & branch.
895     unsigned branchIndexInBlock = detectPeepHoleBranch();
896     if (branchIndexInBlock != UINT_MAX) {
897         NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
898
899         // detectPeepHoleBranch currently only permits the branch to be the very next node,
900         // so can be no intervening nodes to also reference the compare. 
901         ASSERT(node.adjustedRefCount() == 1);
902
903         if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())))
904             compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
905         else if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2())))
906             compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
907         else if (node.op() == CompareEq) {
908             if (Node::shouldSpeculateFinalObject(
909                     at(node.child1()), at(node.child2()))) {
910                 compilePeepHoleObjectEquality(
911                     node, branchNodeIndex, &JSFinalObject::s_info,
912                     isFinalObjectPrediction);
913             } else if (Node::shouldSpeculateArray(
914                            at(node.child1()), at(node.child2()))) {
915                 compilePeepHoleObjectEquality(
916                     node, branchNodeIndex, &JSArray::s_info,
917                     isArrayPrediction);
918             } else if (at(node.child1()).shouldSpeculateFinalObject()
919                        && at(node.child2()).shouldSpeculateFinalObjectOrOther()) {
920                 compilePeepHoleObjectToObjectOrOtherEquality(
921                     node.child1(), node.child2(), branchNodeIndex,
922                     &JSFinalObject::s_info, isFinalObjectPrediction);
923             } else if (at(node.child1()).shouldSpeculateFinalObjectOrOther()
924                        && at(node.child2()).shouldSpeculateFinalObject()) {
925                 compilePeepHoleObjectToObjectOrOtherEquality(
926                     node.child2(), node.child1(), branchNodeIndex,
927                     &JSFinalObject::s_info, isFinalObjectPrediction);
928             } else if (at(node.child1()).shouldSpeculateArray()
929                        && at(node.child2()).shouldSpeculateArrayOrOther()) {
930                 compilePeepHoleObjectToObjectOrOtherEquality(
931                     node.child1(), node.child2(), branchNodeIndex,
932                     &JSArray::s_info, isArrayPrediction);
933             } else if (at(node.child1()).shouldSpeculateArrayOrOther()
934                        && at(node.child2()).shouldSpeculateArray()) {
935                 compilePeepHoleObjectToObjectOrOtherEquality(
936                     node.child2(), node.child1(), branchNodeIndex,
937                     &JSArray::s_info, isArrayPrediction);
938             } else {
939                 nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
940                 return true;
941             }
942         } else {
943             nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
944             return true;
945         }
946
947         use(node.child1());
948         use(node.child2());
949         m_indexInBlock = branchIndexInBlock;
950         m_compileIndex = branchNodeIndex;
951         return true;
952     }
953     return false;
954 }
955
956 void SpeculativeJIT::compileMovHint(Node& node)
957 {
958     ASSERT(node.op() == SetLocal);
959     
960     setNodeIndexForOperand(node.child1().index(), node.local());
961     m_lastSetOperand = node.local();
962 }
963
964 void SpeculativeJIT::compile(BasicBlock& block)
965 {
966     ASSERT(m_compileOkay);
967     
968     if (!block.isReachable)
969         return;
970     
971     if (!block.cfaHasVisited) {
972         // Don't generate code for basic blocks that are unreachable according to CFA.
973         // But to be sure that nobody has generated a jump to this block, drop in a
974         // breakpoint here.
975 #if !ASSERT_DISABLED
976         m_jit.breakpoint();
977 #endif
978         return;
979     }
980
981     m_blockHeads[m_block] = m_jit.label();
982 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK)
983     m_jit.breakpoint();
984 #endif
985     
986     m_jit.jitAssertHasValidCallFrame();
987
988     ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
989     for (size_t i = 0; i < m_arguments.size(); ++i) {
990         NodeIndex nodeIndex = block.variablesAtHead.argument(i);
991         if (nodeIndex == NoNode || m_jit.codeBlock()->argumentIsCaptured(i))
992             m_arguments[i] = ValueSource(ValueInRegisterFile);
993         else
994             m_arguments[i] = ValueSource::forPrediction(at(nodeIndex).variableAccessData()->prediction());
995     }
996     
997     m_state.reset();
998     m_state.beginBasicBlock(&block);
999     
1000     ASSERT(m_variables.size() == block.variablesAtHead.numberOfLocals());
1001     for (size_t i = 0; i < m_variables.size(); ++i) {
1002         NodeIndex nodeIndex = block.variablesAtHead.local(i);
1003         if (nodeIndex == NoNode)
1004             m_variables[i] = ValueSource(SourceIsDead);
1005         else if (at(nodeIndex).variableAccessData()->isArgumentsAlias())
1006             m_variables[i] = ValueSource(ArgumentsSource);
1007         else if (at(nodeIndex).variableAccessData()->isCaptured())
1008             m_variables[i] = ValueSource(ValueInRegisterFile);
1009         else if (!at(nodeIndex).refCount())
1010             m_variables[i] = ValueSource(SourceIsDead);
1011         else if (at(nodeIndex).variableAccessData()->shouldUseDoubleFormat())
1012             m_variables[i] = ValueSource(DoubleInRegisterFile);
1013         else
1014             m_variables[i] = ValueSource::forPrediction(at(nodeIndex).variableAccessData()->argumentAwarePrediction());
1015     }
1016     
1017     m_lastSetOperand = std::numeric_limits<int>::max();
1018     m_codeOriginForOSR = CodeOrigin();
1019     
1020     if (DFG_ENABLE_EDGE_CODE_VERIFICATION) {
1021         JITCompiler::Jump verificationSucceeded =
1022             m_jit.branch32(JITCompiler::Equal, GPRInfo::regT0, TrustedImm32(m_block));
1023         m_jit.breakpoint();
1024         verificationSucceeded.link(&m_jit);
1025     }
1026
1027     for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
1028         m_compileIndex = block[m_indexInBlock];
1029         Node& node = at(m_compileIndex);
1030         m_codeOriginForOSR = node.codeOrigin;
1031         if (!node.shouldGenerate()) {
1032 #if DFG_ENABLE(DEBUG_VERBOSE)
1033             dataLog("SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x     ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
1034 #endif
1035             switch (node.op()) {
1036             case SetLocal:
1037                 compileMovHint(node);
1038                 break;
1039
1040             case InlineStart: {
1041                 InlineCallFrame* inlineCallFrame = node.codeOrigin.inlineCallFrame;
1042                 int argumentCountIncludingThis = inlineCallFrame->arguments.size();
1043                 unsigned argumentPositionStart = node.argumentPositionStart();
1044                 bool argumentsAreCaptured =
1045                     baselineCodeBlockForInlineCallFrame(inlineCallFrame)->argumentsAreCaptured();
1046                 for (int i = 0; i < argumentCountIncludingThis; ++i) {
1047                     ValueRecovery recovery;
1048                     if (argumentsAreCaptured)
1049                         recovery = ValueRecovery::alreadyInRegisterFile();
1050                     else {
1051                         ArgumentPosition& argumentPosition =
1052                             m_jit.graph().m_argumentPositions[argumentPositionStart + i];
1053                         ValueSource valueSource;
1054                         if (argumentPosition.shouldUseDoubleFormat())
1055                             valueSource = ValueSource(DoubleInRegisterFile);
1056                         else if (isInt32Prediction(argumentPosition.prediction()))
1057                             valueSource = ValueSource(Int32InRegisterFile);
1058                         else if (isArrayPrediction(argumentPosition.prediction()))
1059                             valueSource = ValueSource(CellInRegisterFile);
1060                         else if (isBooleanPrediction(argumentPosition.prediction()))
1061                             valueSource = ValueSource(BooleanInRegisterFile);
1062                         else
1063                             valueSource = ValueSource(ValueInRegisterFile);
1064                         recovery = computeValueRecoveryFor(valueSource);
1065                     }
1066                     // The recovery should refer either to something that has already been
1067                     // stored into the register file at the right place, or to a constant,
1068                     // since the Arguments code isn't smart enough to handle anything else.
1069                     // The exception is the this argument, which we don't really need to be
1070                     // able to recover.
1071 #if DFG_ENABLE(DEBUG_VERBOSE)
1072                     dataLog("\nRecovery for argument %d: ", i);
1073                     recovery.dump(WTF::dataFile());
1074 #endif
1075                     inlineCallFrame->arguments[i] = recovery;
1076                 }
1077                 break;
1078             }
1079                 
1080             default:
1081                 break;
1082             }
1083         } else {
1084             
1085 #if DFG_ENABLE(DEBUG_VERBOSE)
1086             dataLog("SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x   ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
1087 #endif
1088 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_NODE)
1089             m_jit.breakpoint();
1090 #endif
1091 #if DFG_ENABLE(XOR_DEBUG_AID)
1092             m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
1093             m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
1094 #endif
1095             checkConsistency();
1096             compile(node);
1097             if (!m_compileOkay) {
1098                 m_compileOkay = true;
1099                 clearGenerationInfo();
1100                 return;
1101             }
1102             
1103 #if DFG_ENABLE(DEBUG_VERBOSE)
1104             if (node.hasResult()) {
1105                 GenerationInfo& info = m_generationInfo[node.virtualRegister()];
1106                 dataLog("-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)node.virtualRegister());
1107                 if (info.registerFormat() != DataFormatNone) {
1108                     if (info.registerFormat() == DataFormatDouble)
1109                         dataLog(", %s", FPRInfo::debugName(info.fpr()));
1110 #if USE(JSVALUE32_64)
1111                     else if (info.registerFormat() & DataFormatJS)
1112                         dataLog(", %s %s", GPRInfo::debugName(info.tagGPR()), GPRInfo::debugName(info.payloadGPR()));
1113 #endif
1114                     else
1115                         dataLog(", %s", GPRInfo::debugName(info.gpr()));
1116                 }
1117                 dataLog("    ");
1118             } else
1119                 dataLog("    ");
1120 #endif
1121         }
1122         
1123 #if DFG_ENABLE(VERBOSE_VALUE_RECOVERIES)
1124         for (size_t i = 0; i < m_arguments.size(); ++i)
1125             computeValueRecoveryFor(argumentToOperand(i)).dump(stderr);
1126         
1127         dataLog(" : ");
1128         
1129         for (int operand = 0; operand < (int)m_variables.size(); ++operand)
1130             computeValueRecoveryFor(operand).dump(stderr);
1131 #endif
1132
1133 #if DFG_ENABLE(DEBUG_VERBOSE)
1134         dataLog("\n");
1135 #endif
1136         
1137         // Make sure that the abstract state is rematerialized for the next node.
1138         m_state.execute(m_indexInBlock);
1139         
1140         if (node.shouldGenerate())
1141             checkConsistency();
1142     }
1143     
1144     // Perform the most basic verification that children have been used correctly.
1145 #if !ASSERT_DISABLED
1146     for (unsigned index = 0; index < m_generationInfo.size(); ++index) {
1147         GenerationInfo& info = m_generationInfo[index];
1148         ASSERT(!info.alive());
1149     }
1150 #endif
1151 }
1152
1153 // If we are making type predictions about our arguments then
1154 // we need to check that they are correct on function entry.
1155 void SpeculativeJIT::checkArgumentTypes()
1156 {
1157     ASSERT(!m_compileIndex);
1158     m_isCheckingArgumentTypes = true;
1159     m_codeOriginForOSR = CodeOrigin(0);
1160
1161     for (size_t i = 0; i < m_arguments.size(); ++i)
1162         m_arguments[i] = ValueSource(ValueInRegisterFile);
1163     for (size_t i = 0; i < m_variables.size(); ++i)
1164         m_variables[i] = ValueSource(ValueInRegisterFile);
1165     
1166     for (int i = 0; i < m_jit.codeBlock()->numParameters(); ++i) {
1167         NodeIndex nodeIndex = m_jit.graph().m_arguments[i];
1168         Node& node = at(nodeIndex);
1169         ASSERT(node.op() == SetArgument);
1170         if (!node.shouldGenerate()) {
1171             // The argument is dead. We don't do any checks for such arguments.
1172             continue;
1173         }
1174         
1175         VariableAccessData* variableAccessData = node.variableAccessData();
1176         VirtualRegister virtualRegister = variableAccessData->local();
1177         PredictedType predictedType = variableAccessData->prediction();
1178
1179         JSValueSource valueSource = JSValueSource(JITCompiler::addressFor(virtualRegister));
1180         
1181 #if USE(JSVALUE64)
1182         if (isInt32Prediction(predictedType))
1183             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
1184         else if (isArrayPrediction(predictedType)) {
1185             GPRTemporary temp(this);
1186             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1187             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1188             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
1189         } else if (isBooleanPrediction(predictedType)) {
1190             GPRTemporary temp(this);
1191             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1192             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), temp.gpr());
1193             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1194         } else if (isInt8ArrayPrediction(predictedType)) {
1195             GPRTemporary temp(this);
1196             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1197             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1198             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_classInfo)));
1199         } else if (isInt16ArrayPrediction(predictedType)) {
1200             GPRTemporary temp(this);
1201             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1202             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1203             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_classInfo)));
1204         } else if (isInt32ArrayPrediction(predictedType)) {
1205             GPRTemporary temp(this);
1206             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1207             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1208             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_classInfo)));
1209         } else if (isUint8ArrayPrediction(predictedType)) {
1210             GPRTemporary temp(this);
1211             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1212             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1213             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_classInfo)));
1214         } else if (isUint8ClampedArrayPrediction(predictedType)) {
1215             GPRTemporary temp(this);
1216             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1217             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1218             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ClampedArrayDescriptor().m_classInfo)));
1219         } else if (isUint16ArrayPrediction(predictedType)) {
1220             GPRTemporary temp(this);
1221             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1222             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1223             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_classInfo)));
1224         } else if (isUint32ArrayPrediction(predictedType)) {
1225             GPRTemporary temp(this);
1226             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1227             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1228             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_classInfo)));
1229         } else if (isFloat32ArrayPrediction(predictedType)) {
1230             GPRTemporary temp(this);
1231             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1232             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1233             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_classInfo)));
1234         } else if (isFloat64ArrayPrediction(predictedType)) {
1235             GPRTemporary temp(this);
1236             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1237             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1238             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
1239         }
1240 #else
1241         if (isInt32Prediction(predictedType))
1242             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
1243         else if (isArrayPrediction(predictedType)) {
1244             GPRTemporary temp(this);
1245             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1246             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1247             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1248             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
1249         } else if (isBooleanPrediction(predictedType))
1250             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
1251         else if (isInt8ArrayPrediction(predictedType)) {
1252             GPRTemporary temp(this);
1253             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1254             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1255             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1256             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_classInfo)));
1257         } else if (isInt16ArrayPrediction(predictedType)) {
1258             GPRTemporary temp(this);
1259             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1260             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1261             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1262             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_classInfo)));
1263         } else if (isInt32ArrayPrediction(predictedType)) {
1264             GPRTemporary temp(this);
1265             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1266             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1267             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1268             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_classInfo)));
1269         } else if (isUint8ArrayPrediction(predictedType)) {
1270             GPRTemporary temp(this);
1271             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1272             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1273             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1274             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_classInfo)));
1275         } else if (isUint8ClampedArrayPrediction(predictedType)) {
1276             GPRTemporary temp(this);
1277             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1278             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1279             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1280             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ClampedArrayDescriptor().m_classInfo)));
1281         } else if (isUint16ArrayPrediction(predictedType)) {
1282             GPRTemporary temp(this);
1283             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1284             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1285             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1286             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_classInfo)));
1287         }  else if (isUint32ArrayPrediction(predictedType)) {
1288             GPRTemporary temp(this);
1289             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1290             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1291             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1292             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_classInfo)));
1293         }  else if (isFloat32ArrayPrediction(predictedType)) {
1294             GPRTemporary temp(this);
1295             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1296             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1297             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1298             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_classInfo)));
1299         }   else if (isFloat64ArrayPrediction(predictedType)) {
1300             GPRTemporary temp(this);
1301             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1302             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1303             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1304             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
1305         } 
1306 #endif
1307     }
1308     m_isCheckingArgumentTypes = false;
1309 }
1310
1311 bool SpeculativeJIT::compile()
1312 {
1313     checkArgumentTypes();
1314
1315     if (DFG_ENABLE_EDGE_CODE_VERIFICATION)
1316         m_jit.move(TrustedImm32(0), GPRInfo::regT0);
1317
1318     ASSERT(!m_compileIndex);
1319     for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
1320         BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
1321         if (block)
1322             compile(*block);
1323     }
1324     linkBranches();
1325     return true;
1326 }
1327
1328 void SpeculativeJIT::createOSREntries()
1329 {
1330     for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
1331         BasicBlock* block = m_jit.graph().m_blocks[blockIndex].get();
1332         if (!block)
1333             continue;
1334         if (!block->isOSRTarget)
1335             continue;
1336
1337         // Currently we only need to create OSR entry trampolines when using edge code
1338         // verification. But in the future, we'll need this for other things as well (like
1339         // when we have global reg alloc).
1340         // If we don't need OSR entry trampolin
1341         if (!DFG_ENABLE_EDGE_CODE_VERIFICATION) {
1342             m_osrEntryHeads.append(m_blockHeads[blockIndex]);
1343             continue;
1344         }
1345         
1346         m_osrEntryHeads.append(m_jit.label());
1347         m_jit.move(TrustedImm32(blockIndex), GPRInfo::regT0);
1348         m_jit.jump().linkTo(m_blockHeads[blockIndex], &m_jit);
1349     }
1350 }
1351
1352 void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
1353 {
1354     unsigned osrEntryIndex = 0;
1355     for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
1356         BasicBlock* block = m_jit.graph().m_blocks[blockIndex].get();
1357         if (!block)
1358             continue;
1359         if (!block->isOSRTarget)
1360             continue;
1361         m_jit.noticeOSREntry(*block, m_osrEntryHeads[osrEntryIndex++], linkBuffer);
1362     }
1363     ASSERT(osrEntryIndex == m_osrEntryHeads.size());
1364 }
1365
1366 ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
1367 {
1368     switch (valueSource.kind()) {
1369     case SourceIsDead:
1370         return ValueRecovery::constant(jsUndefined());
1371         
1372     case ValueInRegisterFile:
1373         return ValueRecovery::alreadyInRegisterFile();
1374         
1375     case Int32InRegisterFile:
1376         return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
1377
1378     case CellInRegisterFile:
1379         return ValueRecovery::alreadyInRegisterFileAsUnboxedCell();
1380
1381     case BooleanInRegisterFile:
1382         return ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean();
1383         
1384     case DoubleInRegisterFile:
1385         return ValueRecovery::alreadyInRegisterFileAsUnboxedDouble();
1386         
1387     case ArgumentsSource:
1388         return ValueRecovery::argumentsThatWereNotCreated();
1389
1390     case HaveNode: {
1391         Node* nodePtr = &at(valueSource.nodeIndex());
1392
1393         if (nodePtr->isPhantomArguments())
1394             return ValueRecovery::argumentsThatWereNotCreated();
1395         
1396         if (nodePtr->hasConstant())
1397             return ValueRecovery::constant(valueOfJSConstant(valueSource.nodeIndex()));
1398         
1399         if (!nodePtr->shouldGenerate()) {
1400             // It's legitimately dead. As in, nobody will ever use this node, or operand,
1401             // ever. Set it to Undefined to make the GC happy after the OSR.
1402             return ValueRecovery::constant(jsUndefined());
1403         }
1404     
1405         GenerationInfo* infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1406         if (!infoPtr->alive() || infoPtr->nodeIndex() != valueSource.nodeIndex()) {
1407             // Try to see if there is an alternate node that would contain the value we want.
1408             // There are four possibilities:
1409             //
1410             // Int32ToDouble: We can use this in place of the original node, but
1411             //    we'd rather not; so we use it only if it is the only remaining
1412             //    live version.
1413             //
1414             // ValueToInt32: If the only remaining live version of the value is
1415             //    ValueToInt32, then we can use it.
1416             //
1417             // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
1418             //    then the only remaining uses are ones that want a properly formed number
1419             //    rather than a UInt32 intermediate.
1420             //
1421             // The reverse of the above: This node could be a UInt32ToNumber, but its
1422             //    alternative is still alive. This means that the only remaining uses of
1423             //    the number would be fine with a UInt32 intermediate.
1424             //
1425             // DoubleAsInt32: Same as UInt32ToNumber.
1426             //
1427         
1428             bool found = false;
1429         
1430             if (nodePtr->op() == UInt32ToNumber || nodePtr->op() == DoubleAsInt32) {
1431                 NodeIndex nodeIndex = nodePtr->child1().index();
1432                 nodePtr = &at(nodeIndex);
1433                 infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1434                 if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
1435                     found = true;
1436             }
1437         
1438             if (!found) {
1439                 NodeIndex int32ToDoubleIndex = NoNode;
1440                 NodeIndex valueToInt32Index = NoNode;
1441                 NodeIndex uint32ToNumberIndex = NoNode;
1442                 NodeIndex doubleAsInt32Index = NoNode;
1443             
1444                 for (unsigned virtualRegister = 0; virtualRegister < m_generationInfo.size(); ++virtualRegister) {
1445                     GenerationInfo& info = m_generationInfo[virtualRegister];
1446                     if (!info.alive())
1447                         continue;
1448                     if (info.nodeIndex() == NoNode)
1449                         continue;
1450                     Node& node = at(info.nodeIndex());
1451                     if (node.child1Unchecked() != valueSource.nodeIndex())
1452                         continue;
1453                     switch (node.op()) {
1454                     case Int32ToDouble:
1455                         int32ToDoubleIndex = info.nodeIndex();
1456                         break;
1457                     case ValueToInt32:
1458                         valueToInt32Index = info.nodeIndex();
1459                         break;
1460                     case UInt32ToNumber:
1461                         uint32ToNumberIndex = info.nodeIndex();
1462                         break;
1463                     case DoubleAsInt32:
1464                         doubleAsInt32Index = info.nodeIndex();
1465                     default:
1466                         break;
1467                     }
1468                 }
1469             
1470                 NodeIndex nodeIndexToUse;
1471                 if (doubleAsInt32Index != NoNode)
1472                     nodeIndexToUse = doubleAsInt32Index;
1473                 else if (int32ToDoubleIndex != NoNode)
1474                     nodeIndexToUse = int32ToDoubleIndex;
1475                 else if (valueToInt32Index != NoNode)
1476                     nodeIndexToUse = valueToInt32Index;
1477                 else if (uint32ToNumberIndex != NoNode)
1478                     nodeIndexToUse = uint32ToNumberIndex;
1479                 else
1480                     nodeIndexToUse = NoNode;
1481             
1482                 if (nodeIndexToUse != NoNode) {
1483                     nodePtr = &at(nodeIndexToUse);
1484                     infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1485                     ASSERT(infoPtr->alive() && infoPtr->nodeIndex() == nodeIndexToUse);
1486                     found = true;
1487                 }
1488             }
1489         
1490             if (!found)
1491                 return ValueRecovery::constant(jsUndefined());
1492         }
1493     
1494         ASSERT(infoPtr->alive());
1495
1496         if (infoPtr->registerFormat() != DataFormatNone) {
1497             if (infoPtr->registerFormat() == DataFormatDouble)
1498                 return ValueRecovery::inFPR(infoPtr->fpr());
1499 #if USE(JSVALUE32_64)
1500             if (infoPtr->registerFormat() & DataFormatJS)
1501                 return ValueRecovery::inPair(infoPtr->tagGPR(), infoPtr->payloadGPR());
1502 #endif
1503             return ValueRecovery::inGPR(infoPtr->gpr(), infoPtr->registerFormat());
1504         }
1505         if (infoPtr->spillFormat() != DataFormatNone)
1506             return ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(nodePtr->virtualRegister()), infoPtr->spillFormat());
1507     
1508         ASSERT_NOT_REACHED();
1509         return ValueRecovery();
1510     }
1511         
1512     default:
1513         ASSERT_NOT_REACHED();
1514         return ValueRecovery();
1515     }
1516 }
1517
1518 void SpeculativeJIT::compileGetCharCodeAt(Node& node)
1519 {
1520     ASSERT(node.child3() == NoNode);
1521     SpeculateCellOperand string(this, node.child1());
1522     SpeculateStrictInt32Operand index(this, node.child2());
1523     StorageOperand storage(this, node.child3());
1524
1525     GPRReg stringReg = string.gpr();
1526     GPRReg indexReg = index.gpr();
1527     GPRReg storageReg = storage.gpr();
1528     
1529     if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) {
1530         ASSERT(!(at(node.child1()).prediction() & PredictString));
1531         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1532         noResult(m_compileIndex);
1533         return;
1534     }
1535
1536     // unsigned comparison so we can filter out negative indices and indices that are too large
1537     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));
1538
1539     GPRTemporary scratch(this);
1540     GPRReg scratchReg = scratch.gpr();
1541
1542     m_jit.loadPtr(MacroAssembler::Address(stringReg, JSString::offsetOfValue()), scratchReg);
1543
1544     // Load the character into scratchReg
1545     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1546
1547     m_jit.load8(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesOne, 0), scratchReg);
1548     JITCompiler::Jump cont8Bit = m_jit.jump();
1549
1550     is16Bit.link(&m_jit);
1551
1552     m_jit.load16(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesTwo, 0), scratchReg);
1553
1554     cont8Bit.link(&m_jit);
1555
1556     integerResult(scratchReg, m_compileIndex);
1557 }
1558
1559 void SpeculativeJIT::compileGetByValOnString(Node& node)
1560 {
1561     SpeculateCellOperand base(this, node.child1());
1562     SpeculateStrictInt32Operand property(this, node.child2());
1563     StorageOperand storage(this, node.child3());
1564     GPRReg baseReg = base.gpr();
1565     GPRReg propertyReg = property.gpr();
1566     GPRReg storageReg = storage.gpr();
1567
1568     if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) {
1569         ASSERT(!(at(node.child1()).prediction() & PredictString));
1570         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1571         noResult(m_compileIndex);
1572         return;
1573     }
1574
1575     // unsigned comparison so we can filter out negative indices and indices that are too large
1576     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));
1577
1578     GPRTemporary scratch(this);
1579     GPRReg scratchReg = scratch.gpr();
1580
1581     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), scratchReg);
1582
1583     // Load the character into scratchReg
1584     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1585
1586     m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne, 0), scratchReg);
1587     JITCompiler::Jump cont8Bit = m_jit.jump();
1588
1589     is16Bit.link(&m_jit);
1590
1591     m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
1592
1593     // We only support ascii characters
1594     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
1595
1596     // 8 bit string values don't need the isASCII check.
1597     cont8Bit.link(&m_jit);
1598
1599     GPRTemporary smallStrings(this);
1600     GPRReg smallStringsReg = smallStrings.gpr();
1601     m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg);
1602     m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg);
1603     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
1604     cellResult(scratchReg, m_compileIndex);
1605 }
1606
1607 GeneratedOperandType SpeculativeJIT::checkGeneratedTypeForToInt32(NodeIndex nodeIndex)
1608 {
1609 #if DFG_ENABLE(DEBUG_VERBOSE)
1610     dataLog("checkGeneratedTypeForToInt32@%d   ", nodeIndex);
1611 #endif
1612     Node& node = at(nodeIndex);
1613     VirtualRegister virtualRegister = node.virtualRegister();
1614     GenerationInfo& info = m_generationInfo[virtualRegister];
1615
1616     if (info.registerFormat() == DataFormatNone) {
1617         if (node.hasConstant()) {
1618             if (isInt32Constant(nodeIndex))
1619                 return GeneratedOperandInteger;
1620
1621             if (isNumberConstant(nodeIndex))
1622                 return GeneratedOperandDouble;
1623
1624             terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1625             return GeneratedOperandTypeUnknown;
1626         }
1627
1628         if (info.spillFormat() == DataFormatDouble)
1629             return GeneratedOperandDouble;
1630     }
1631
1632     switch (info.registerFormat()) {
1633     case DataFormatBoolean: // This type never occurs.
1634     case DataFormatStorage:
1635         ASSERT_NOT_REACHED();
1636
1637     case DataFormatCell:
1638         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1639         return GeneratedOperandTypeUnknown;
1640
1641     case DataFormatNone:
1642     case DataFormatJSCell:
1643     case DataFormatJS:
1644     case DataFormatJSBoolean:
1645         return GeneratedOperandJSValue;
1646
1647     case DataFormatJSInteger:
1648     case DataFormatInteger:
1649         return GeneratedOperandInteger;
1650
1651     case DataFormatJSDouble:
1652     case DataFormatDouble:
1653         return GeneratedOperandDouble;
1654     }
1655
1656     ASSERT_NOT_REACHED();
1657     return GeneratedOperandTypeUnknown;
1658 }
1659
1660 void SpeculativeJIT::compileValueToInt32(Node& node)
1661 {
1662     if (at(node.child1()).shouldSpeculateInteger()) {
1663         SpeculateIntegerOperand op1(this, node.child1());
1664         GPRTemporary result(this, op1);
1665         m_jit.move(op1.gpr(), result.gpr());
1666         integerResult(result.gpr(), m_compileIndex, op1.format());
1667         return;
1668     }
1669     
1670     if (at(node.child1()).shouldSpeculateNumber()) {
1671         switch (checkGeneratedTypeForToInt32(node.child1().index())) {
1672         case GeneratedOperandInteger: {
1673             SpeculateIntegerOperand op1(this, node.child1());
1674             GPRTemporary result(this, op1);
1675             m_jit.move(op1.gpr(), result.gpr());
1676             integerResult(result.gpr(), m_compileIndex, op1.format());
1677             return;
1678         }
1679         case GeneratedOperandDouble: {
1680             GPRTemporary result(this);
1681             DoubleOperand op1(this, node.child1());
1682             FPRReg fpr = op1.fpr();
1683             GPRReg gpr = result.gpr();
1684             JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
1685             
1686             addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
1687
1688             integerResult(gpr, m_compileIndex);
1689             return;
1690         }
1691         case GeneratedOperandJSValue: {
1692             GPRTemporary result(this);
1693 #if USE(JSVALUE64)
1694             JSValueOperand op1(this, node.child1());
1695
1696             GPRReg gpr = op1.gpr();
1697             GPRReg resultGpr = result.gpr();
1698             FPRTemporary tempFpr(this);
1699             FPRReg fpr = tempFpr.fpr();
1700
1701             JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
1702
1703             if (!isNumberPrediction(m_state.forNode(node.child1()).m_type))
1704                 speculationCheck(BadType, JSValueRegs(gpr), node.child1().index(), m_jit.branchTestPtr(MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
1705
1706             // First, if we get here we have a double encoded as a JSValue
1707             m_jit.move(gpr, resultGpr);
1708             unboxDouble(resultGpr, fpr);
1709
1710             silentSpillAllRegisters(resultGpr);
1711             callOperation(toInt32, resultGpr, fpr);
1712             silentFillAllRegisters(resultGpr);
1713
1714             JITCompiler::Jump converted = m_jit.jump();
1715
1716             isInteger.link(&m_jit);
1717             m_jit.zeroExtend32ToPtr(gpr, resultGpr);
1718
1719             converted.link(&m_jit);
1720 #else
1721             Node& childNode = at(node.child1().index());
1722             VirtualRegister virtualRegister = childNode.virtualRegister();
1723             GenerationInfo& info = m_generationInfo[virtualRegister];
1724
1725             JSValueOperand op1(this, node.child1());
1726
1727             GPRReg payloadGPR = op1.payloadGPR();
1728             GPRReg resultGpr = result.gpr();
1729
1730             if (info.registerFormat() == DataFormatJSInteger)
1731                 m_jit.move(payloadGPR, resultGpr);
1732             else {
1733                 GPRReg tagGPR = op1.tagGPR();
1734                 FPRTemporary tempFpr(this);
1735                 FPRReg fpr = tempFpr.fpr();
1736                 FPRTemporary scratch(this);
1737
1738                 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
1739
1740                 if (!isNumberPrediction(m_state.forNode(node.child1()).m_type))
1741                     speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node.child1().index(), m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
1742
1743                 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
1744
1745                 silentSpillAllRegisters(resultGpr);
1746                 callOperation(toInt32, resultGpr, fpr);
1747                 silentFillAllRegisters(resultGpr);
1748
1749                 JITCompiler::Jump converted = m_jit.jump();
1750
1751                 isInteger.link(&m_jit);
1752                 m_jit.move(payloadGPR, resultGpr);
1753
1754                 converted.link(&m_jit);
1755             }
1756 #endif
1757             integerResult(resultGpr, m_compileIndex);
1758             return;
1759         }
1760         case GeneratedOperandTypeUnknown:
1761             ASSERT_NOT_REACHED();
1762             break;
1763         }
1764     }
1765     
1766     if (at(node.child1()).shouldSpeculateBoolean()) {
1767         SpeculateBooleanOperand op1(this, node.child1());
1768         GPRTemporary result(this, op1);
1769         
1770         m_jit.and32(JITCompiler::TrustedImm32(1), op1.gpr());
1771         
1772         integerResult(op1.gpr(), m_compileIndex);
1773         return;
1774     }
1775     
1776     // Do it the safe way.
1777     nonSpeculativeValueToInt32(node);
1778     return;
1779 }
1780
1781 void SpeculativeJIT::compileUInt32ToNumber(Node& node)
1782 {
1783     if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
1784         // We know that this sometimes produces doubles. So produce a double every
1785         // time. This at least allows subsequent code to not have weird conditionals.
1786             
1787         IntegerOperand op1(this, node.child1());
1788         FPRTemporary result(this);
1789             
1790         GPRReg inputGPR = op1.gpr();
1791         FPRReg outputFPR = result.fpr();
1792             
1793         m_jit.convertInt32ToDouble(inputGPR, outputFPR);
1794             
1795         JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
1796         m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), outputFPR);
1797         positive.link(&m_jit);
1798             
1799         doubleResult(outputFPR, m_compileIndex);
1800         return;
1801     }
1802
1803     IntegerOperand op1(this, node.child1());
1804     GPRTemporary result(this, op1);
1805
1806     // Test the operand is positive. This is a very special speculation check - we actually
1807     // use roll-forward speculation here, where if this fails, we jump to the baseline
1808     // instruction that follows us, rather than the one we're executing right now. We have
1809     // to do this because by this point, the original values necessary to compile whatever
1810     // operation the UInt32ToNumber originated from might be dead.
1811     forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(op1.gpr()));
1812
1813     m_jit.move(op1.gpr(), result.gpr());
1814     integerResult(result.gpr(), m_compileIndex, op1.format());
1815 }
1816
1817 void SpeculativeJIT::compileDoubleAsInt32(Node& node)
1818 {
1819     SpeculateDoubleOperand op1(this, node.child1());
1820     FPRTemporary scratch(this);
1821     GPRTemporary result(this);
1822     
1823     FPRReg valueFPR = op1.fpr();
1824     FPRReg scratchFPR = scratch.fpr();
1825     GPRReg resultGPR = result.gpr();
1826
1827     JITCompiler::JumpList failureCases;
1828     m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR);
1829     forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, failureCases, ValueRecovery::inFPR(valueFPR));
1830
1831     integerResult(resultGPR, m_compileIndex);
1832 }
1833
1834 void SpeculativeJIT::compileInt32ToDouble(Node& node)
1835 {
1836 #if USE(JSVALUE64)
1837     // On JSVALUE64 we have a way of loading double constants in a more direct manner
1838     // than a int->double conversion. On 32_64, unfortunately, we currently don't have
1839     // any such mechanism - though we could have it, if we just provisioned some memory
1840     // in CodeBlock for the double form of integer constants.
1841     if (at(node.child1()).hasConstant()) {
1842         ASSERT(isInt32Constant(node.child1().index()));
1843         FPRTemporary result(this);
1844         GPRTemporary temp(this);
1845         m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(node.child1().index())))), temp.gpr());
1846         m_jit.movePtrToDouble(temp.gpr(), result.fpr());
1847         doubleResult(result.fpr(), m_compileIndex);
1848         return;
1849     }
1850 #endif
1851     
1852     if (isInt32Prediction(m_state.forNode(node.child1()).m_type)) {
1853         SpeculateIntegerOperand op1(this, node.child1());
1854         FPRTemporary result(this);
1855         m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
1856         doubleResult(result.fpr(), m_compileIndex);
1857         return;
1858     }
1859     
1860     JSValueOperand op1(this, node.child1());
1861     FPRTemporary result(this);
1862     
1863 #if USE(JSVALUE64)
1864     GPRTemporary temp(this);
1865
1866     GPRReg op1GPR = op1.gpr();
1867     GPRReg tempGPR = temp.gpr();
1868     FPRReg resultFPR = result.fpr();
1869     
1870     JITCompiler::Jump isInteger = m_jit.branchPtr(
1871         MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
1872     
1873     if (!isNumberPrediction(m_state.forNode(node.child1()).m_type)) {
1874         speculationCheck(
1875             BadType, JSValueRegs(op1GPR), node.child1(),
1876             m_jit.branchTestPtr(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
1877     }
1878     
1879     m_jit.move(op1GPR, tempGPR);
1880     unboxDouble(tempGPR, resultFPR);
1881     JITCompiler::Jump done = m_jit.jump();
1882     
1883     isInteger.link(&m_jit);
1884     m_jit.convertInt32ToDouble(op1GPR, resultFPR);
1885     done.link(&m_jit);
1886 #else
1887     FPRTemporary temp(this);
1888     
1889     GPRReg op1TagGPR = op1.tagGPR();
1890     GPRReg op1PayloadGPR = op1.payloadGPR();
1891     FPRReg tempFPR = temp.fpr();
1892     FPRReg resultFPR = result.fpr();
1893     
1894     JITCompiler::Jump isInteger = m_jit.branch32(
1895         MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
1896     
1897     if (!isNumberPrediction(m_state.forNode(node.child1()).m_type)) {
1898         speculationCheck(
1899             BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node.child1(),
1900             m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
1901     }
1902     
1903     unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
1904     JITCompiler::Jump done = m_jit.jump();
1905     
1906     isInteger.link(&m_jit);
1907     m_jit.convertInt32ToDouble(op1PayloadGPR, resultFPR);
1908     done.link(&m_jit);
1909 #endif
1910     
1911     doubleResult(resultFPR, m_compileIndex);
1912 }
1913
1914 static double clampDoubleToByte(double d)
1915 {
1916     d += 0.5;
1917     if (!(d > 0))
1918         d = 0;
1919     else if (d > 255)
1920         d = 255;
1921     return d;
1922 }
1923
1924 static void compileClampIntegerToByte(JITCompiler& jit, GPRReg result)
1925 {
1926     MacroAssembler::Jump inBounds = jit.branch32(MacroAssembler::BelowOrEqual, result, JITCompiler::TrustedImm32(0xff));
1927     MacroAssembler::Jump tooBig = jit.branch32(MacroAssembler::GreaterThan, result, JITCompiler::TrustedImm32(0xff));
1928     jit.xorPtr(result, result);
1929     MacroAssembler::Jump clamped = jit.jump();
1930     tooBig.link(&jit);
1931     jit.move(JITCompiler::TrustedImm32(255), result);
1932     clamped.link(&jit);
1933     inBounds.link(&jit);
1934 }
1935
1936 static void compileClampDoubleToByte(JITCompiler& jit, GPRReg result, FPRReg source, FPRReg scratch)
1937 {
1938     // Unordered compare so we pick up NaN
1939     static const double zero = 0;
1940     static const double byteMax = 255;
1941     static const double half = 0.5;
1942     jit.loadDouble(&zero, scratch);
1943     MacroAssembler::Jump tooSmall = jit.branchDouble(MacroAssembler::DoubleLessThanOrEqualOrUnordered, source, scratch);
1944     jit.loadDouble(&byteMax, scratch);
1945     MacroAssembler::Jump tooBig = jit.branchDouble(MacroAssembler::DoubleGreaterThan, source, scratch);
1946     
1947     jit.loadDouble(&half, scratch);
1948     // FIXME: This should probably just use a floating point round!
1949     // https://bugs.webkit.org/show_bug.cgi?id=72054
1950     jit.addDouble(source, scratch);
1951     jit.truncateDoubleToInt32(scratch, result);   
1952     MacroAssembler::Jump truncatedInt = jit.jump();
1953     
1954     tooSmall.link(&jit);
1955     jit.xorPtr(result, result);
1956     MacroAssembler::Jump zeroed = jit.jump();
1957     
1958     tooBig.link(&jit);
1959     jit.move(JITCompiler::TrustedImm32(255), result);
1960     
1961     truncatedInt.link(&jit);
1962     zeroed.link(&jit);
1963
1964 }
1965
1966 void SpeculativeJIT::compileGetTypedArrayLength(const TypedArrayDescriptor& descriptor, Node& node, bool needsSpeculationCheck)
1967 {
1968     SpeculateCellOperand base(this, node.child1());
1969     GPRTemporary result(this);
1970     
1971     GPRReg baseGPR = base.gpr();
1972     GPRReg resultGPR = result.gpr();
1973     
1974     if (needsSpeculationCheck)
1975         speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
1976     
1977     m_jit.load32(MacroAssembler::Address(baseGPR, descriptor.m_lengthOffset), resultGPR);
1978     
1979     integerResult(resultGPR, m_compileIndex);
1980 }
1981
1982 void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness)
1983 {
1984     SpeculateCellOperand base(this, node.child1());
1985     SpeculateStrictInt32Operand property(this, node.child2());
1986     StorageOperand storage(this, node.child3());
1987
1988     GPRReg baseReg = base.gpr();
1989     GPRReg propertyReg = property.gpr();
1990     GPRReg storageReg = storage.gpr();
1991
1992     GPRTemporary result(this);
1993     GPRReg resultReg = result.gpr();
1994
1995     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
1996         ASSERT_NOT_REACHED();
1997         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1998         noResult(m_compileIndex);
1999         return;
2000     }
2001
2002     MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
2003     m_jit.xorPtr(resultReg, resultReg);
2004     MacroAssembler::Jump outOfBounds = m_jit.jump();
2005     inBounds.link(&m_jit);
2006     switch (elementSize) {
2007     case 1:
2008         if (signedness == SignedTypedArray)
2009             m_jit.load8Signed(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
2010         else
2011             m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
2012         break;
2013     case 2:
2014         if (signedness == SignedTypedArray)
2015             m_jit.load16Signed(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
2016         else
2017             m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
2018         break;
2019     case 4:
2020         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
2021         break;
2022     default:
2023         ASSERT_NOT_REACHED();
2024     }
2025     outOfBounds.link(&m_jit);
2026     if (elementSize < 4 || signedness == SignedTypedArray) {
2027         integerResult(resultReg, m_compileIndex);
2028         return;
2029     }
2030     
2031     ASSERT(elementSize == 4 && signedness == UnsignedTypedArray);
2032     if (node.shouldSpeculateInteger()) {
2033         forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultReg, TrustedImm32(0)), ValueRecovery::uint32InGPR(resultReg));
2034         integerResult(resultReg, m_compileIndex);
2035         return;
2036     }
2037     
2038     FPRTemporary fresult(this);
2039     m_jit.convertInt32ToDouble(resultReg, fresult.fpr());
2040     JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, resultReg, TrustedImm32(0));
2041     m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), fresult.fpr());
2042     positive.link(&m_jit);
2043     doubleResult(fresult.fpr(), m_compileIndex);
2044 }
2045
2046 void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness, TypedArrayRounding rounding)
2047 {
2048     Edge baseUse = node.child1();
2049     Edge valueUse = node.child3();
2050     
2051     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
2052         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
2053     GPRTemporary value;
2054     GPRReg valueGPR;
2055     
2056     if (at(valueUse).isConstant()) {
2057         JSValue jsValue = valueOfJSConstant(valueUse.index());
2058         if (!jsValue.isNumber()) {
2059             terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2060             noResult(m_compileIndex);
2061             return;
2062         }
2063         double d = jsValue.asNumber();
2064         if (rounding == ClampRounding) {
2065             ASSERT(elementSize == 1);
2066             d = clampDoubleToByte(d);
2067         }
2068         GPRTemporary scratch(this);
2069         GPRReg scratchReg = scratch.gpr();
2070         m_jit.move(Imm32(toInt32(d)), scratchReg);
2071         value.adopt(scratch);
2072         valueGPR = scratchReg;
2073     } else if (at(valueUse).shouldSpeculateInteger()) {
2074         SpeculateIntegerOperand valueOp(this, valueUse);
2075         GPRTemporary scratch(this);
2076         GPRReg scratchReg = scratch.gpr();
2077         m_jit.move(valueOp.gpr(), scratchReg);
2078         if (rounding == ClampRounding) {
2079             ASSERT(elementSize == 1);
2080             compileClampIntegerToByte(m_jit, scratchReg);
2081         }
2082         value.adopt(scratch);
2083         valueGPR = scratchReg;
2084     } else if (rounding == ClampRounding) {
2085         ASSERT(elementSize == 1);
2086         SpeculateDoubleOperand valueOp(this, valueUse);
2087         GPRTemporary result(this);
2088         FPRTemporary floatScratch(this);
2089         FPRReg fpr = valueOp.fpr();
2090         GPRReg gpr = result.gpr();
2091         compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
2092         value.adopt(result);
2093         valueGPR = gpr;
2094     } else {
2095         SpeculateDoubleOperand valueOp(this, valueUse);
2096         GPRTemporary result(this);
2097         FPRReg fpr = valueOp.fpr();
2098         GPRReg gpr = result.gpr();
2099         MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
2100         m_jit.xorPtr(gpr, gpr);
2101         MacroAssembler::Jump fixed = m_jit.jump();
2102         notNaN.link(&m_jit);
2103
2104         MacroAssembler::Jump failed;
2105         if (signedness == SignedTypedArray)
2106             failed = m_jit.branchTruncateDoubleToInt32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
2107         else
2108             failed = m_jit.branchTruncateDoubleToUint32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
2109         
2110         addSlowPathGenerator(slowPathCall(failed, this, toInt32, gpr, fpr));
2111
2112         fixed.link(&m_jit);
2113         value.adopt(result);
2114         valueGPR = gpr;
2115     }
2116     ASSERT_UNUSED(valueGPR, valueGPR != property);
2117     ASSERT(valueGPR != base);
2118     GPRTemporary storage(this);
2119     GPRReg storageReg = storage.gpr();
2120     ASSERT(valueGPR != storageReg);
2121     m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
2122     MacroAssembler::Jump outOfBounds;
2123     if (speculationRequirements != NoTypedArraySpecCheck)
2124         outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
2125
2126     switch (elementSize) {
2127     case 1:
2128         m_jit.store8(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesOne));
2129         break;
2130     case 2:
2131         m_jit.store16(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesTwo));
2132         break;
2133     case 4:
2134         m_jit.store32(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
2135         break;
2136     default:
2137         ASSERT_NOT_REACHED();
2138     }
2139     if (speculationRequirements != NoTypedArraySpecCheck)
2140         outOfBounds.link(&m_jit);
2141     noResult(m_compileIndex);
2142 }
2143
2144 void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
2145 {
2146     SpeculateCellOperand base(this, node.child1());
2147     SpeculateStrictInt32Operand property(this, node.child2());
2148     StorageOperand storage(this, node.child3());
2149
2150     GPRReg baseReg = base.gpr();
2151     GPRReg propertyReg = property.gpr();
2152     GPRReg storageReg = storage.gpr();
2153     
2154     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
2155         ASSERT_NOT_REACHED();
2156         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2157         noResult(m_compileIndex);
2158         return;
2159     }
2160
2161     FPRTemporary result(this);
2162     FPRReg resultReg = result.fpr();
2163     ASSERT(speculationRequirements != NoTypedArraySpecCheck);
2164     MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
2165     static const double zero = 0;
2166     m_jit.loadDouble(&zero, resultReg);
2167     MacroAssembler::Jump outOfBounds = m_jit.jump();
2168     inBounds.link(&m_jit);
2169     switch (elementSize) {
2170     case 4:
2171         m_jit.loadFloat(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
2172         m_jit.convertFloatToDouble(resultReg, resultReg);
2173         break;
2174     case 8: {
2175         m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2176         MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
2177         static const double NaN = std::numeric_limits<double>::quiet_NaN();
2178         m_jit.loadDouble(&NaN, resultReg);
2179         notNaN.link(&m_jit);
2180         break;
2181     }
2182     default:
2183         ASSERT_NOT_REACHED();
2184     }
2185     outOfBounds.link(&m_jit);
2186     doubleResult(resultReg, m_compileIndex);
2187 }
2188
2189 void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
2190 {
2191     Edge baseUse = node.child1();
2192     Edge valueUse = node.child3();
2193     
2194     SpeculateDoubleOperand valueOp(this, valueUse);
2195     
2196     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
2197         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
2198     
2199     GPRTemporary result(this);
2200     
2201     GPRTemporary storage(this);
2202     GPRReg storageReg = storage.gpr();
2203     
2204     m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
2205     MacroAssembler::Jump outOfBounds;
2206     if (speculationRequirements != NoTypedArraySpecCheck)
2207         outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
2208     
2209     switch (elementSize) {
2210     case 4: {
2211         FPRTemporary scratch(this);
2212         m_jit.moveDouble(valueOp.fpr(), scratch.fpr());
2213         m_jit.convertDoubleToFloat(valueOp.fpr(), scratch.fpr());
2214         m_jit.storeFloat(scratch.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
2215         break;
2216     }
2217     case 8:
2218         m_jit.storeDouble(valueOp.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesEight));
2219         break;
2220     default:
2221         ASSERT_NOT_REACHED();
2222     }
2223     if (speculationRequirements != NoTypedArraySpecCheck)
2224         outOfBounds.link(&m_jit);
2225     noResult(m_compileIndex);
2226 }
2227
2228 void SpeculativeJIT::compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg)
2229 {
2230     // Check that prototype is an object.
2231     m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
2232     speculationCheck(BadType, JSValueRegs(), NoNode, m_jit.branchIfNotObject(scratchReg));
2233     
2234     // Initialize scratchReg with the value being checked.
2235     m_jit.move(valueReg, scratchReg);
2236     
2237     // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
2238     MacroAssembler::Label loop(&m_jit);
2239     m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
2240 #if USE(JSVALUE64)
2241     m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset()), scratchReg);
2242 #else
2243     m_jit.load32(MacroAssembler::Address(scratchReg, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), scratchReg);
2244 #endif
2245     MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
2246 #if USE(JSVALUE64)
2247     m_jit.branchTestPtr(MacroAssembler::Zero, scratchReg, GPRInfo::tagMaskRegister).linkTo(loop, &m_jit);
2248 #else
2249     m_jit.branchTest32(MacroAssembler::NonZero, scratchReg).linkTo(loop, &m_jit);
2250 #endif
2251     
2252     // No match - result is false.
2253 #if USE(JSVALUE64)
2254     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
2255 #else
2256     m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
2257 #endif
2258     MacroAssembler::Jump putResult = m_jit.jump();
2259     
2260     isInstance.link(&m_jit);
2261 #if USE(JSVALUE64)
2262     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), scratchReg);
2263 #else
2264     m_jit.move(MacroAssembler::TrustedImm32(1), scratchReg);
2265 #endif
2266     
2267     putResult.link(&m_jit);
2268 }
2269
2270 void SpeculativeJIT::compileInstanceOf(Node& node)
2271 {
2272     if ((!!(at(node.child1()).prediction() & ~PredictCell)
2273          && !!(m_state.forNode(node.child1()).m_type & ~PredictCell))
2274         || at(node.child1()).adjustedRefCount() == 1) {
2275         // It might not be a cell. Speculate less aggressively.
2276         // Or: it might only be used once (i.e. by us), so we get zero benefit
2277         // from speculating any more aggressively than we absolutely need to.
2278         
2279         JSValueOperand value(this, node.child1());
2280         SpeculateCellOperand prototype(this, node.child3());
2281         GPRTemporary scratch(this);
2282         
2283         GPRReg prototypeReg = prototype.gpr();
2284         GPRReg scratchReg = scratch.gpr();
2285         
2286 #if USE(JSVALUE64)
2287         GPRReg valueReg = value.gpr();
2288         MacroAssembler::Jump isCell = m_jit.branchTestPtr(MacroAssembler::Zero, valueReg, GPRInfo::tagMaskRegister);
2289         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
2290 #else
2291         GPRReg valueTagReg = value.tagGPR();
2292         GPRReg valueReg = value.payloadGPR();
2293         MacroAssembler::Jump isCell = m_jit.branch32(MacroAssembler::Equal, valueTagReg, TrustedImm32(JSValue::CellTag));
2294         m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
2295 #endif
2296
2297         MacroAssembler::Jump done = m_jit.jump();
2298         
2299         isCell.link(&m_jit);
2300         
2301         compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
2302         
2303         done.link(&m_jit);
2304
2305 #if USE(JSVALUE64)
2306         jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
2307 #else
2308         booleanResult(scratchReg, m_compileIndex);
2309 #endif
2310         return;
2311     }
2312     
2313     SpeculateCellOperand value(this, node.child1());
2314     // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
2315     SpeculateCellOperand prototype(this, node.child3());
2316     
2317     GPRTemporary scratch(this);
2318     
2319     GPRReg valueReg = value.gpr();
2320     GPRReg prototypeReg = prototype.gpr();
2321     GPRReg scratchReg = scratch.gpr();
2322     
2323     compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
2324
2325 #if USE(JSVALUE64)
2326     jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
2327 #else
2328     booleanResult(scratchReg, m_compileIndex);
2329 #endif
2330 }
2331
2332 void SpeculativeJIT::compileSoftModulo(Node& node)
2333 {
2334     // In the fast path, the dividend value could be the final result
2335     // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
2336     SpeculateStrictInt32Operand op1(this, node.child1());
2337 #if CPU(X86) || CPU(X86_64)
2338     if (isInt32Constant(node.child2().index())) {
2339         int32_t divisor = valueOfInt32Constant(node.child2().index());
2340         if (divisor) {
2341             GPRReg op1Gpr = op1.gpr();
2342
2343             GPRTemporary eax(this, X86Registers::eax);
2344             GPRTemporary edx(this, X86Registers::edx);
2345             GPRTemporary scratch(this);
2346             GPRReg scratchGPR = scratch.gpr();
2347
2348             GPRReg op1SaveGPR;
2349             if (op1Gpr == X86Registers::eax || op1Gpr == X86Registers::edx) {
2350                 op1SaveGPR = allocate();
2351                 ASSERT(op1Gpr != op1SaveGPR);
2352                 m_jit.move(op1Gpr, op1SaveGPR);
2353             } else
2354                 op1SaveGPR = op1Gpr;
2355             ASSERT(op1SaveGPR != X86Registers::eax);
2356             ASSERT(op1SaveGPR != X86Registers::edx);
2357
2358             m_jit.move(op1Gpr, eax.gpr());
2359             m_jit.move(TrustedImm32(divisor), scratchGPR);
2360             if (divisor == -1)
2361                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1)));
2362             m_jit.assembler().cdq();
2363             m_jit.assembler().idivl_r(scratchGPR);
2364             // Check that we're not about to create negative zero.
2365             // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
2366             JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
2367             speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
2368             numeratorPositive.link(&m_jit);
2369             
2370             if (op1SaveGPR != op1Gpr)
2371                 unlock(op1SaveGPR);
2372
2373             integerResult(edx.gpr(), m_compileIndex);
2374             return;
2375         }
2376     }
2377 #endif
2378
2379     SpeculateIntegerOperand op2(this, node.child2());
2380 #if CPU(X86) || CPU(X86_64)
2381     GPRTemporary eax(this, X86Registers::eax);
2382     GPRTemporary edx(this, X86Registers::edx);
2383     GPRReg op1GPR = op1.gpr();
2384     GPRReg op2GPR = op2.gpr();
2385     
2386     GPRReg op2TempGPR;
2387     GPRReg temp;
2388     GPRReg op1SaveGPR;
2389     
2390     if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
2391         op2TempGPR = allocate();
2392         temp = op2TempGPR;
2393     } else {
2394         op2TempGPR = InvalidGPRReg;
2395         if (op1GPR == X86Registers::eax)
2396             temp = X86Registers::edx;
2397         else
2398             temp = X86Registers::eax;
2399     }
2400     
2401     if (op1GPR == X86Registers::eax || op1GPR == X86Registers::edx) {
2402         op1SaveGPR = allocate();
2403         ASSERT(op1GPR != op1SaveGPR);
2404         m_jit.move(op1GPR, op1SaveGPR);
2405     } else
2406         op1SaveGPR = op1GPR;
2407     
2408     ASSERT(temp != op1GPR);
2409     ASSERT(temp != op2GPR);
2410     ASSERT(op1SaveGPR != X86Registers::eax);
2411     ASSERT(op1SaveGPR != X86Registers::edx);
2412     
2413     m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp);
2414     
2415     JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
2416     
2417     JITCompiler::Jump done;
2418     // FIXME: if the node is not used as number then we can do this more easily.
2419     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
2420     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
2421     
2422     safeDenominator.link(&m_jit);
2423             
2424     if (op2TempGPR != InvalidGPRReg) {
2425         m_jit.move(op2GPR, op2TempGPR);
2426         op2GPR = op2TempGPR;
2427     }
2428             
2429     m_jit.move(op1GPR, eax.gpr());
2430     m_jit.assembler().cdq();
2431     m_jit.assembler().idivl_r(op2GPR);
2432             
2433     if (op2TempGPR != InvalidGPRReg)
2434         unlock(op2TempGPR);
2435
2436     // Check that we're not about to create negative zero.
2437     // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
2438     JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
2439     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
2440     numeratorPositive.link(&m_jit);
2441     
2442     if (op1SaveGPR != op1GPR)
2443         unlock(op1SaveGPR);
2444             
2445     integerResult(edx.gpr(), m_compileIndex);
2446 #else // CPU(X86) || CPU(X86_64) --> so not X86
2447     // Do this the *safest* way possible: call out to a C function that will do the modulo,
2448     // and then attempt to convert back.
2449     GPRReg op1GPR = op1.gpr();
2450     GPRReg op2GPR = op2.gpr();
2451     
2452     FPRResult result(this);
2453     
2454     flushRegisters();
2455     callOperation(operationFModOnInts, result.fpr(), op1GPR, op2GPR);
2456     
2457     FPRTemporary scratch(this);
2458     GPRTemporary intResult(this);
2459     JITCompiler::JumpList failureCases;
2460     m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr());
2461     speculationCheck(Overflow, JSValueRegs(), NoNode, failureCases);
2462     
2463     integerResult(intResult.gpr(), m_compileIndex);
2464 #endif // CPU(X86) || CPU(X86_64)
2465 }
2466
2467 void SpeculativeJIT::compileAdd(Node& node)
2468 {
2469     if (m_jit.graph().addShouldSpeculateInteger(node)) {
2470         if (isNumberConstant(node.child1().index())) {
2471             int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
2472             SpeculateIntegerOperand op2(this, node.child2());
2473             GPRTemporary result(this);
2474
2475             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2476                 m_jit.move(op2.gpr(), result.gpr());
2477                 m_jit.add32(Imm32(imm1), result.gpr());
2478             } else
2479                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
2480
2481             integerResult(result.gpr(), m_compileIndex);
2482             return;
2483         }
2484                 
2485         if (isNumberConstant(node.child2().index())) {
2486             SpeculateIntegerOperand op1(this, node.child1());
2487             int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
2488             GPRTemporary result(this);
2489                 
2490             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2491                 m_jit.move(op1.gpr(), result.gpr());
2492                 m_jit.add32(Imm32(imm2), result.gpr());
2493             } else
2494                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
2495
2496             integerResult(result.gpr(), m_compileIndex);
2497             return;
2498         }
2499                 
2500         SpeculateIntegerOperand op1(this, node.child1());
2501         SpeculateIntegerOperand op2(this, node.child2());
2502         GPRTemporary result(this, op1, op2);
2503
2504         GPRReg gpr1 = op1.gpr();
2505         GPRReg gpr2 = op2.gpr();
2506         GPRReg gprResult = result.gpr();
2507
2508         if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2509             if (gpr1 == gprResult)
2510                 m_jit.add32(gpr2, gprResult);
2511             else {
2512                 m_jit.move(gpr2, gprResult);
2513                 m_jit.add32(gpr1, gprResult);
2514             }
2515         } else {
2516             MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
2517                 
2518             if (gpr1 == gprResult)
2519                 speculationCheck(Overflow, JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
2520             else if (gpr2 == gprResult)
2521                 speculationCheck(Overflow, JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
2522             else
2523                 speculationCheck(Overflow, JSValueRegs(), NoNode, check);
2524         }
2525
2526         integerResult(gprResult, m_compileIndex);
2527         return;
2528     }
2529         
2530     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2531         SpeculateDoubleOperand op1(this, node.child1());
2532         SpeculateDoubleOperand op2(this, node.child2());
2533         FPRTemporary result(this, op1, op2);
2534
2535         FPRReg reg1 = op1.fpr();
2536         FPRReg reg2 = op2.fpr();
2537         m_jit.addDouble(reg1, reg2, result.fpr());
2538
2539         doubleResult(result.fpr(), m_compileIndex);
2540         return;
2541     }
2542
2543     if (node.op() == ValueAdd) {
2544         compileValueAdd(node);
2545         return;
2546     }
2547     
2548     // We don't handle this yet. :-(
2549     terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2550 }
2551
2552 void SpeculativeJIT::compileArithSub(Node& node)
2553 {
2554     if (m_jit.graph().addShouldSpeculateInteger(node)) {
2555         if (isNumberConstant(node.child2().index())) {
2556             SpeculateIntegerOperand op1(this, node.child1());
2557             int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
2558             GPRTemporary result(this);
2559
2560             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2561                 m_jit.move(op1.gpr(), result.gpr());
2562                 m_jit.sub32(Imm32(imm2), result.gpr());
2563             } else {
2564 #if ENABLE(JIT_CONSTANT_BLINDING)
2565                 GPRTemporary scratch(this);
2566                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr(), scratch.gpr()));
2567 #else
2568                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
2569 #endif
2570             }
2571
2572             integerResult(result.gpr(), m_compileIndex);
2573             return;
2574         }
2575             
2576         if (isNumberConstant(node.child1().index())) {
2577             int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
2578             SpeculateIntegerOperand op2(this, node.child2());
2579             GPRTemporary result(this);
2580                 
2581             m_jit.move(Imm32(imm1), result.gpr());
2582             if (nodeCanTruncateInteger(node.arithNodeFlags()))
2583                 m_jit.sub32(op2.gpr(), result.gpr());
2584             else
2585                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
2586                 
2587             integerResult(result.gpr(), m_compileIndex);
2588             return;
2589         }
2590             
2591         SpeculateIntegerOperand op1(this, node.child1());
2592         SpeculateIntegerOperand op2(this, node.child2());
2593         GPRTemporary result(this);
2594
2595         if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2596             m_jit.move(op1.gpr(), result.gpr());
2597             m_jit.sub32(op2.gpr(), result.gpr());
2598         } else
2599             speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
2600
2601         integerResult(result.gpr(), m_compileIndex);
2602         return;
2603     }
2604         
2605     SpeculateDoubleOperand op1(this, node.child1());
2606     SpeculateDoubleOperand op2(this, node.child2());
2607     FPRTemporary result(this, op1);
2608
2609     FPRReg reg1 = op1.fpr();
2610     FPRReg reg2 = op2.fpr();
2611     m_jit.subDouble(reg1, reg2, result.fpr());
2612
2613     doubleResult(result.fpr(), m_compileIndex);
2614 }
2615
2616 void SpeculativeJIT::compileArithNegate(Node& node)
2617 {
2618     if (m_jit.graph().negateShouldSpeculateInteger(node)) {
2619         SpeculateIntegerOperand op1(this, node.child1());
2620         GPRTemporary result(this);
2621
2622         m_jit.move(op1.gpr(), result.gpr());
2623
2624         if (nodeCanTruncateInteger(node.arithNodeFlags()))
2625             m_jit.neg32(result.gpr());
2626         else {
2627             speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
2628             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags()))
2629                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
2630         }
2631
2632         integerResult(result.gpr(), m_compileIndex);
2633         return;
2634     }
2635         
2636     SpeculateDoubleOperand op1(this, node.child1());
2637     FPRTemporary result(this);
2638
2639     m_jit.negateDouble(op1.fpr(), result.fpr());
2640
2641     doubleResult(result.fpr(), m_compileIndex);
2642 }
2643
2644 void SpeculativeJIT::compileArithMul(Node& node)
2645 {
2646     if (m_jit.graph().mulShouldSpeculateInteger(node)) {
2647         SpeculateIntegerOperand op1(this, node.child1());
2648         SpeculateIntegerOperand op2(this, node.child2());
2649         GPRTemporary result(this);
2650
2651         GPRReg reg1 = op1.gpr();
2652         GPRReg reg2 = op2.gpr();
2653
2654         // We can perform truncated multiplications if we get to this point, because if the
2655         // fixup phase could not prove that it would be safe, it would have turned us into
2656         // a double multiplication.
2657         if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2658             m_jit.move(reg1, result.gpr());
2659             m_jit.mul32(reg2, result.gpr());
2660         } else {
2661             speculationCheck(
2662                 Overflow, JSValueRegs(), NoNode,
2663                 m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
2664         }
2665             
2666         // Check for negative zero, if the users of this node care about such things.
2667         if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
2668             MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
2669             speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
2670             speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
2671             resultNonZero.link(&m_jit);
2672         }
2673
2674         integerResult(result.gpr(), m_compileIndex);
2675         return;
2676     }
2677
2678     SpeculateDoubleOperand op1(this, node.child1());
2679     SpeculateDoubleOperand op2(this, node.child2());
2680     FPRTemporary result(this, op1, op2);
2681
2682     FPRReg reg1 = op1.fpr();
2683     FPRReg reg2 = op2.fpr();
2684         
2685     m_jit.mulDouble(reg1, reg2, result.fpr());
2686         
2687     doubleResult(result.fpr(), m_compileIndex);
2688 }
2689
2690 #if CPU(X86) || CPU(X86_64)
2691 void SpeculativeJIT::compileIntegerArithDivForX86(Node& node)
2692 {
2693     SpeculateIntegerOperand op1(this, node.child1());
2694     SpeculateIntegerOperand op2(this, node.child2());
2695     GPRTemporary eax(this, X86Registers::eax);
2696     GPRTemporary edx(this, X86Registers::edx);
2697     GPRReg op1GPR = op1.gpr();
2698     GPRReg op2GPR = op2.gpr();
2699     
2700     GPRReg op2TempGPR;
2701     GPRReg temp;
2702     if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
2703         op2TempGPR = allocate();
2704         temp = op2TempGPR;
2705     } else {
2706         op2TempGPR = InvalidGPRReg;
2707         if (op1GPR == X86Registers::eax)
2708             temp = X86Registers::edx;
2709         else
2710             temp = X86Registers::eax;
2711     }
2712     
2713     ASSERT(temp != op1GPR);
2714     ASSERT(temp != op2GPR);
2715     
2716     m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp);
2717     
2718     JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
2719     
2720     JITCompiler::Jump done;
2721     if (nodeUsedAsNumber(node.arithNodeFlags())) {
2722         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
2723         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
2724     } else {
2725         JITCompiler::Jump zero = m_jit.branchTest32(JITCompiler::Zero, op2GPR);
2726         JITCompiler::Jump notNeg2ToThe31 = m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1));
2727         zero.link(&m_jit);
2728         m_jit.move(TrustedImm32(0), eax.gpr());
2729         done = m_jit.jump();
2730         notNeg2ToThe31.link(&m_jit);
2731     }
2732     
2733     safeDenominator.link(&m_jit);
2734             
2735     // If the user cares about negative zero, then speculate that we're not about
2736     // to produce negative zero.
2737     if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
2738         MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
2739         speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
2740         numeratorNonZero.link(&m_jit);
2741     }
2742     
2743     if (op2TempGPR != InvalidGPRReg) {
2744         m_jit.move(op2GPR, op2TempGPR);
2745         op2GPR = op2TempGPR;
2746     }
2747             
2748     m_jit.move(op1GPR, eax.gpr());
2749     m_jit.assembler().cdq();
2750     m_jit.assembler().idivl_r(op2GPR);
2751             
2752     if (op2TempGPR != InvalidGPRReg)
2753         unlock(op2TempGPR);
2754
2755     // Check that there was no remainder. If there had been, then we'd be obligated to
2756     // produce a double result instead.
2757     if (nodeUsedAsNumber(node.arithNodeFlags()))
2758         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
2759     else
2760         done.link(&m_jit);
2761             
2762     integerResult(eax.gpr(), m_compileIndex);
2763 }
2764 #endif // CPU(X86) || CPU(X86_64)
2765
2766 void SpeculativeJIT::compileArithMod(Node& node)
2767 {
2768     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))
2769         && node.canSpeculateInteger()) {
2770         compileSoftModulo(node);
2771         return;
2772     }
2773         
2774     SpeculateDoubleOperand op1(this, node.child1());
2775     SpeculateDoubleOperand op2(this, node.child2());
2776         
2777     FPRReg op1FPR = op1.fpr();
2778     FPRReg op2FPR = op2.fpr();
2779         
2780     flushRegisters();
2781         
2782     FPRResult result(this);
2783
2784     callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
2785         
2786     doubleResult(result.fpr(), m_compileIndex);
2787 }
2788
2789 // Returns true if the compare is fused with a subsequent branch.
2790 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
2791 {
2792     if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
2793         return true;
2794
2795     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
2796         compileIntegerCompare(node, condition);
2797         return false;
2798     }
2799     
2800     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2801         compileDoubleCompare(node, doubleCondition);
2802         return false;
2803     }
2804     
2805     if (node.op() == CompareEq) {
2806         if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
2807             compileObjectEquality(node, &JSFinalObject::s_info, isFinalObjectPrediction);
2808             return false;
2809         }
2810         
2811         if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
2812             compileObjectEquality(node, &JSArray::s_info, isArrayPrediction);
2813             return false;
2814         }
2815         
2816         if (at(node.child1()).shouldSpeculateFinalObject()
2817             && at(node.child2()).shouldSpeculateFinalObjectOrOther()) {
2818             compileObjectToObjectOrOtherEquality(
2819                 node.child1(), node.child2(), &JSFinalObject::s_info,
2820                 isFinalObjectPrediction);
2821             return false;
2822         }
2823         
2824         if (at(node.child1()).shouldSpeculateFinalObjectOrOther()
2825             && at(node.child2()).shouldSpeculateFinalObject()) {
2826             compileObjectToObjectOrOtherEquality(
2827                 node.child2(), node.child1(), &JSFinalObject::s_info,
2828                 isFinalObjectPrediction);
2829             return false;
2830         }
2831         
2832         if (at(node.child1()).shouldSpeculateArray()
2833             && at(node.child2()).shouldSpeculateArrayOrOther()) {
2834             compileObjectToObjectOrOtherEquality(
2835                 node.child1(), node.child2(), &JSArray::s_info,
2836                 isArrayPrediction);
2837             return false;
2838         }
2839         
2840         if (at(node.child1()).shouldSpeculateArrayOrOther()
2841             && at(node.child2()).shouldSpeculateArray()) {
2842             compileObjectToObjectOrOtherEquality(
2843                 node.child2(), node.child1(), &JSArray::s_info,
2844                 isArrayPrediction);
2845             return false;
2846         }
2847     }
2848     
2849     nonSpeculativeNonPeepholeCompare(node, condition, operation);
2850     return false;
2851 }
2852
2853 bool SpeculativeJIT::compileStrictEqForConstant(Node& node, Edge value, JSValue constant)
2854 {
2855     JSValueOperand op1(this, value);
2856     
2857     unsigned branchIndexInBlock = detectPeepHoleBranch();
2858     if (branchIndexInBlock != UINT_MAX) {
2859         NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2860         Node& branchNode = at(branchNodeIndex);
2861         BlockIndex taken = branchNode.takenBlockIndex();
2862         BlockIndex notTaken = branchNode.notTakenBlockIndex();
2863         MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
2864         
2865         // The branch instruction will branch to the taken block.
2866         // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
2867         if (taken == nextBlock()) {
2868             condition = MacroAssembler::NotEqual;
2869             BlockIndex tmp = taken;
2870             taken = notTaken;
2871             notTaken = tmp;
2872         }
2873
2874 #if USE(JSVALUE64)
2875         branchPtr(condition, op1.gpr(), MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant))), taken);
2876 #else
2877         GPRReg payloadGPR = op1.payloadGPR();
2878         GPRReg tagGPR = op1.tagGPR();
2879         if (condition == MacroAssembler::Equal) {
2880             // Drop down if not equal, go elsewhere if equal.
2881             MacroAssembler::Jump notEqual = m_jit.branch32(MacroAssembler::NotEqual, tagGPR, MacroAssembler::Imm32(constant.tag()));
2882             branch32(MacroAssembler::Equal, payloadGPR, MacroAssembler::Imm32(constant.payload()), taken);
2883             notEqual.link(&m_jit);
2884         } else {
2885             // Drop down if equal, go elsehwere if not equal.
2886             branch32(MacroAssembler::NotEqual, tagGPR, MacroAssembler::Imm32(constant.tag()), taken);
2887             branch32(MacroAssembler::NotEqual, payloadGPR, MacroAssembler::Imm32(constant.payload()), taken);
2888         }
2889 #endif
2890         
2891         jump(notTaken);
2892         
2893         use(node.child1());
2894         use(node.child2());
2895         m_indexInBlock = branchIndexInBlock;
2896         m_compileIndex = branchNodeIndex;
2897         return true;
2898     }
2899     
2900     GPRTemporary result(this);
2901     
2902 #if USE(JSVALUE64)
2903     GPRReg op1GPR = op1.gpr();
2904     GPRReg resultGPR = result.gpr();
2905     m_jit.move(MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(ValueFalse)), resultGPR);
2906     MacroAssembler::Jump notEqual = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant))));
2907     m_jit.or32(MacroAssembler::TrustedImm32(1), resultGPR);
2908     notEqual.link(&m_jit);
2909     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
2910 #else
2911     GPRReg op1PayloadGPR = op1.payloadGPR();
2912     GPRReg op1TagGPR = op1.tagGPR();
2913     GPRReg resultGPR = result.gpr();
2914     m_jit.move(TrustedImm32(0), resultGPR);
2915     MacroAssembler::JumpList notEqual;
2916     notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, MacroAssembler::Imm32(constant.tag())));
2917     notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1PayloadGPR, MacroAssembler::Imm32(constant.payload())));
2918     m_jit.move(TrustedImm32(1), resultGPR);
2919     notEqual.link(&m_jit);
2920     booleanResult(resultGPR, m_compileIndex);
2921 #endif
2922     
2923     return false;
2924 }
2925
2926 bool SpeculativeJIT::compileStrictEq(Node& node)
2927 {
2928     // 1) If either operand is a constant and that constant is not a double, integer,
2929     //    or string, then do a JSValue comparison.
2930     
2931     if (isJSConstant(node.child1().index())) {
2932         JSValue value = valueOfJSConstant(node.child1().index());
2933         if (!value.isNumber() && !value.isString())
2934             return compileStrictEqForConstant(node, node.child2(), value);
2935     }
2936     
2937     if (isJSConstant(node.child2().index())) {
2938         JSValue value = valueOfJSConstant(node.child2().index());
2939         if (!value.isNumber() && !value.isString())
2940             return compileStrictEqForConstant(node, node.child1(), value);
2941     }
2942     
2943     // 2) If the operands are predicted integer, do an integer comparison.
2944     
2945     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
2946         unsigned branchIndexInBlock = detectPeepHoleBranch();
2947         if (branchIndexInBlock != UINT_MAX) {
2948             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2949             compilePeepHoleIntegerBranch(node, branchNodeIndex, MacroAssembler::Equal);
2950             use(node.child1());
2951             use(node.child2());
2952             m_indexInBlock = branchIndexInBlock;
2953             m_compileIndex = branchNodeIndex;
2954             return true;
2955         }
2956         compileIntegerCompare(node, MacroAssembler::Equal);
2957         return false;
2958     }
2959     
2960     // 3) If the operands are predicted double, do a double comparison.
2961     
2962     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2963         unsigned branchIndexInBlock = detectPeepHoleBranch();
2964         if (branchIndexInBlock != UINT_MAX) {
2965             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2966             compilePeepHoleDoubleBranch(node, branchNodeIndex, MacroAssembler::DoubleEqual);
2967             use(node.child1());
2968             use(node.child2());
2969             m_indexInBlock = branchIndexInBlock;
2970             m_compileIndex = branchNodeIndex;
2971             return true;
2972         }
2973         compileDoubleCompare(node, MacroAssembler::DoubleEqual);
2974         return false;
2975     }
2976     
2977     // 4) If the operands are predicted final object or array, then do a final object
2978     //    or array comparison.
2979     
2980     if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
2981         unsigned branchIndexInBlock = detectPeepHoleBranch();
2982         if (branchIndexInBlock != UINT_MAX) {
2983             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2984             compilePeepHoleObjectEquality(node, branchNodeIndex, &JSFinalObject::s_info, isFinalObjectPrediction);
2985             use(node.child1());
2986             use(node.child2());
2987             m_indexInBlock = branchIndexInBlock;
2988             m_compileIndex = branchNodeIndex;
2989             return true;
2990         }
2991         compileObjectEquality(node, &JSFinalObject::s_info, isFinalObjectPrediction);
2992         return false;
2993     }
2994     
2995     if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
2996         unsigned branchIndexInBlock = detectPeepHoleBranch();
2997         if (branchIndexInBlock != UINT_MAX) {
2998             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2999             compilePeepHoleObjectEquality(node, branchNodeIndex, &JSArray::s_info, isArrayPrediction);
3000             use(node.child1());
3001             use(node.child2());
3002             m_indexInBlock = branchIndexInBlock;
3003             m_compileIndex = branchNodeIndex;
3004             return true;
3005         }
3006         compileObjectEquality(node, &JSArray::s_info, isArrayPrediction);
3007         return false;
3008     }
3009     
3010     // 5) Fall back to non-speculative strict equality.
3011     
3012     return nonSpeculativeStrictEq(node);
3013 }
3014
3015 void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
3016 {
3017     if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
3018         terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
3019         return;
3020     }
3021         
3022     SpeculateCellOperand base(this, node.child1());
3023     GPRReg baseReg = base.gpr();
3024     
3025     PredictedType basePrediction = at(node.child2()).prediction();
3026     if (!(basePrediction & PredictInt32) && basePrediction) {
3027         ASSERT_NOT_REACHED();
3028         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
3029         noResult(m_compileIndex);
3030         return;
3031     }
3032     
3033     GPRTemporary storage(this);
3034     GPRReg storageReg = storage.gpr();
3035     if (at(node.child1()).shouldSpeculateArguments()) {
3036         ASSERT_NOT_REACHED();
3037     } else if (at(node.child1()).prediction() == PredictString) {
3038         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
3039             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
3040
3041         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
3042         
3043         // Speculate that we're not accessing a rope
3044         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, storageReg));
3045
3046         m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
3047     } else if (at(node.child1()).shouldSpeculateInt8Array()) {
3048         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int8ArrayDescriptor();
3049         if (!isInt8ArrayPrediction(m_state.forNode(node.child1()).m_type))
3050             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3051         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3052     } else if (at(node.child1()).shouldSpeculateInt16Array()) {
3053         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int16ArrayDescriptor();
3054         if (!isInt16ArrayPrediction(m_state.forNode(node.child1()).m_type))
3055             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3056         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3057     } else if (at(node.child1()).shouldSpeculateInt32Array()) {
3058         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int32ArrayDescriptor();
3059         if (!isInt32ArrayPrediction(m_state.forNode(node.child1()).m_type))
3060             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3061         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3062     } else if (at(node.child1()).shouldSpeculateUint8Array()) {
3063         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ArrayDescriptor();
3064         if (!isUint8ArrayPrediction(m_state.forNode(node.child1()).m_type))
3065             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3066         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3067     } else if (at(node.child1()).shouldSpeculateUint8ClampedArray()) {
3068         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ClampedArrayDescriptor();
3069         if (!isUint8ClampedArrayPrediction(m_state.forNode(node.child1()).m_type))
3070             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3071         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3072     } else if (at(node.child1()).shouldSpeculateUint16Array()) {
3073         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint16ArrayDescriptor();
3074         if (!isUint16ArrayPrediction(m_state.forNode(node.child1()).m_type))
3075             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3076         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3077     } else if (at(node.child1()).shouldSpeculateUint32Array()) {
3078         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint32ArrayDescriptor();
3079         if (!isUint32ArrayPrediction(m_state.forNode(node.child1()).m_type))
3080             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3081         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3082     } else if (at(node.child1()).shouldSpeculateFloat32Array()) {
3083         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float32ArrayDescriptor();
3084         if (!isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type))
3085             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3086         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3087     } else if (at(node.child1()).shouldSpeculateFloat64Array()) {
3088         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float64ArrayDescriptor();
3089         if (!isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type))
3090             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3091         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3092     } else {
3093         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
3094             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
3095         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
3096     }
3097     storageResult(storageReg, m_compileIndex);
3098 }
3099
3100 void SpeculativeJIT::compileGetByValOnArguments(Node& node)
3101 {
3102     SpeculateCellOperand base(this, node.child1());
3103     SpeculateStrictInt32Operand property(this, node.child2());
3104     GPRTemporary result(this);
3105 #if USE(JSVALUE32_64)
3106     GPRTemporary resultTag(this);
3107 #endif
3108     GPRTemporary scratch(this);
3109     
3110     GPRReg baseReg = base.gpr();
3111     GPRReg propertyReg = property.gpr();
3112     GPRReg resultReg = result.gpr();
3113 #if USE(JSVALUE32_64)
3114     GPRReg resultTagReg = resultTag.gpr();
3115 #endif
3116     GPRReg scratchReg = scratch.gpr();
3117     
3118     if (!m_compileOkay)
3119         return;
3120     
3121     if (!isArgumentsPrediction(m_state.forNode(node.child1()).m_type)) {
3122         speculationCheck(
3123             BadType, JSValueSource::unboxedCell(baseReg), node.child1(),
3124             m_jit.branchPtr(
3125                 MacroAssembler::NotEqual,
3126                 MacroAssembler::Address(baseReg, JSCell::classInfoOffset()),
3127                 MacroAssembler::TrustedImmPtr(&Arguments::s_info)));
3128     }
3129     
3130     m_jit.loadPtr(
3131         MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
3132         scratchReg);
3133
3134     // Two really lame checks.
3135     speculationCheck(
3136         Uncountable, JSValueSource(), NoNode,
3137         m_jit.branchPtr(
3138             MacroAssembler::AboveOrEqual, propertyReg,
3139             MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, numArguments))));
3140     speculationCheck(
3141         Uncountable, JSValueSource(), NoNode,
3142         m_jit.branchTestPtr(
3143             MacroAssembler::NonZero,
3144             MacroAssembler::Address(
3145                 scratchReg, OBJECT_OFFSETOF(ArgumentsData, deletedArguments))));
3146     
3147     m_jit.move(propertyReg, resultReg);
3148     m_jit.neg32(resultReg);
3149     m_jit.signExtend32ToPtr(resultReg, resultReg);
3150     m_jit.loadPtr(
3151         MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, registers)),
3152         scratchReg);
3153     
3154 #if USE(JSVALUE32_64)
3155     m_jit.load32(
3156         MacroAssembler::BaseIndex(
3157             scratchReg, resultReg, MacroAssembler::TimesEight,
3158             CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register) +
3159             OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
3160         resultTagReg);
3161     m_jit.load32(
3162         MacroAssembler::BaseIndex(
3163             scratchReg, resultReg, MacroAssembler::TimesEight,
3164             CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register) +
3165             OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
3166         resultReg);
3167     jsValueResult(resultTagReg, resultReg, m_compileIndex);
3168 #else
3169     m_jit.loadPtr(
3170         MacroAssembler::BaseIndex(
3171             scratchReg, resultReg, MacroAssembler::TimesEight,
3172             CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register)),
3173         resultReg);
3174     jsValueResult(resultReg, m_compileIndex);
3175 #endif
3176 }
3177
3178 void SpeculativeJIT::compileGetArgumentsLength(Node& node)
3179 {
3180     SpeculateCellOperand base(this, node.child1());
3181     GPRTemporary result(this, base);
3182     
3183     GPRReg baseReg = base.gpr();
3184     GPRReg resultReg = result.gpr();
3185     
3186     if (!m_compileOkay)
3187         return;
3188     
3189     if (!isArgumentsPrediction(m_state.forNode(node.child1()).m_type)) {
3190         speculationCheck(
3191             BadType, JSValueSource::unboxedCell(baseReg), node.child1(),
3192             m_jit.branchPtr(
3193                 MacroAssembler::NotEqual,
3194                 MacroAssembler::Address(baseReg, JSCell::classInfoOffset()),
3195                 MacroAssembler::TrustedImmPtr(&Arguments::s_info)));
3196     }
3197     
3198     m_jit.loadPtr(
3199         MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
3200         resultReg);
3201
3202     speculationCheck(
3203         Uncountable, JSValueSource(), NoNode,
3204         m_jit.branchTest8(
3205             MacroAssembler::NonZero,
3206             MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, overrodeLength))));
3207     
3208     m_jit.load32(
3209         MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, numArguments)),
3210         resultReg);
3211     integerResult(resultReg, m_compileIndex);
3212 }
3213
3214 void SpeculativeJIT::compileNewFunctionNoCheck(Node& node)
3215 {
3216     GPRResult result(this);
3217     GPRReg resultGPR = result.gpr();
3218     flushRegisters();
3219     callOperation(
3220         operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
3221     cellResult(resultGPR, m_compileIndex);
3222 }
3223
3224 void SpeculativeJIT::compileNewFunctionExpression(Node& node)
3225 {
3226     GPRResult result(this);
3227     GPRReg resultGPR = result.gpr();
3228     flushRegisters();
3229     callOperation(
3230         operationNewFunctionExpression,
3231         resultGPR,
3232         m_jit.codeBlock()->functionExpr(node.functionExprIndex()));
3233     cellResult(resultGPR, m_compileIndex);
3234 }
3235
3236 bool SpeculativeJIT::compileRegExpExec(Node& node)
3237 {
3238     unsigned branchIndexInBlock = detectPeepHoleBranch();
3239     if (branchIndexInBlock == UINT_MAX)
3240         return false;
3241     NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
3242     ASSERT(node.adjustedRefCount() == 1);
3243
3244     Node& branchNode = at(branchNodeIndex);
3245     BlockIndex taken = branchNode.takenBlockIndex();
3246     BlockIndex notTaken = branchNode.notTakenBlockIndex();
3247     
3248     bool invert = false;
3249     if (taken == nextBlock()) {
3250         invert = true;
3251         BlockIndex tmp = taken;
3252         taken = notTaken;
3253         notTaken = tmp;
3254     }
3255
3256     SpeculateCellOperand base(this, node.child1());
3257     SpeculateCellOperand argument(this, node.child2());
3258     GPRReg baseGPR = base.gpr();
3259     GPRReg argumentGPR = argument.gpr();
3260     
3261     flushRegisters();
3262     GPRResult result(this);
3263     callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
3264
3265     branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, result.gpr(), taken);
3266     jump(notTaken);
3267
3268     use(node.child1());
3269     use(node.child2());
3270     m_indexInBlock = branchIndexInBlock;
3271     m_compileIndex = branchNodeIndex;
3272
3273     return true;
3274 }
3275
3276 } } // namespace JSC::DFG
3277
3278 #endif