DFG should not emit unnecessary speculation checks when performing an int32 to double...
[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                 for (int i = 0; i < argumentCountIncludingThis; ++i) {
1044                     ValueRecovery recovery = computeValueRecoveryFor(m_variables[inlineCallFrame->stackOffset + CallFrame::argumentOffsetIncludingThis(i)]);
1045                     // The recovery should refer either to something that has already been
1046                     // stored into the register file at the right place, or to a constant,
1047                     // since the Arguments code isn't smart enough to handle anything else.
1048                     // The exception is the this argument, which we don't really need to be
1049                     // able to recover.
1050 #if DFG_ENABLE(DEBUG_VERBOSE)
1051                     dataLog("\nRecovery for argument %d: ", i);
1052                     recovery.dump(WTF::dataFile());
1053 #endif
1054                     ASSERT(!i || (recovery.isAlreadyInRegisterFile() || recovery.isConstant()));
1055                     inlineCallFrame->arguments[i] = recovery;
1056                 }
1057                 break;
1058             }
1059                 
1060             default:
1061                 break;
1062             }
1063         } else {
1064             
1065 #if DFG_ENABLE(DEBUG_VERBOSE)
1066             dataLog("SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x   ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
1067 #endif
1068 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_NODE)
1069             m_jit.breakpoint();
1070 #endif
1071 #if DFG_ENABLE(XOR_DEBUG_AID)
1072             m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
1073             m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
1074 #endif
1075             checkConsistency();
1076             compile(node);
1077             if (!m_compileOkay) {
1078                 m_compileOkay = true;
1079                 clearGenerationInfo();
1080                 return;
1081             }
1082             
1083 #if DFG_ENABLE(DEBUG_VERBOSE)
1084             if (node.hasResult()) {
1085                 GenerationInfo& info = m_generationInfo[node.virtualRegister()];
1086                 dataLog("-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)node.virtualRegister());
1087                 if (info.registerFormat() != DataFormatNone) {
1088                     if (info.registerFormat() == DataFormatDouble)
1089                         dataLog(", %s", FPRInfo::debugName(info.fpr()));
1090 #if USE(JSVALUE32_64)
1091                     else if (info.registerFormat() & DataFormatJS)
1092                         dataLog(", %s %s", GPRInfo::debugName(info.tagGPR()), GPRInfo::debugName(info.payloadGPR()));
1093 #endif
1094                     else
1095                         dataLog(", %s", GPRInfo::debugName(info.gpr()));
1096                 }
1097                 dataLog("    ");
1098             } else
1099                 dataLog("    ");
1100 #endif
1101         }
1102         
1103 #if DFG_ENABLE(VERBOSE_VALUE_RECOVERIES)
1104         for (size_t i = 0; i < m_arguments.size(); ++i)
1105             computeValueRecoveryFor(argumentToOperand(i)).dump(stderr);
1106         
1107         dataLog(" : ");
1108         
1109         for (int operand = 0; operand < (int)m_variables.size(); ++operand)
1110             computeValueRecoveryFor(operand).dump(stderr);
1111 #endif
1112
1113 #if DFG_ENABLE(DEBUG_VERBOSE)
1114         dataLog("\n");
1115 #endif
1116         
1117         // Make sure that the abstract state is rematerialized for the next node.
1118         m_state.execute(m_indexInBlock);
1119         
1120         if (node.shouldGenerate())
1121             checkConsistency();
1122     }
1123     
1124     // Perform the most basic verification that children have been used correctly.
1125 #if !ASSERT_DISABLED
1126     for (unsigned index = 0; index < m_generationInfo.size(); ++index) {
1127         GenerationInfo& info = m_generationInfo[index];
1128         ASSERT(!info.alive());
1129     }
1130 #endif
1131 }
1132
1133 // If we are making type predictions about our arguments then
1134 // we need to check that they are correct on function entry.
1135 void SpeculativeJIT::checkArgumentTypes()
1136 {
1137     ASSERT(!m_compileIndex);
1138     m_isCheckingArgumentTypes = true;
1139     m_codeOriginForOSR = CodeOrigin(0);
1140
1141     for (size_t i = 0; i < m_arguments.size(); ++i)
1142         m_arguments[i] = ValueSource(ValueInRegisterFile);
1143     for (size_t i = 0; i < m_variables.size(); ++i)
1144         m_variables[i] = ValueSource(ValueInRegisterFile);
1145     
1146     for (int i = 0; i < m_jit.codeBlock()->numParameters(); ++i) {
1147         NodeIndex nodeIndex = m_jit.graph().m_arguments[i];
1148         Node& node = at(nodeIndex);
1149         ASSERT(node.op() == SetArgument);
1150         if (!node.shouldGenerate()) {
1151             // The argument is dead. We don't do any checks for such arguments.
1152             continue;
1153         }
1154         
1155         VariableAccessData* variableAccessData = node.variableAccessData();
1156         VirtualRegister virtualRegister = variableAccessData->local();
1157         PredictedType predictedType = variableAccessData->prediction();
1158
1159         JSValueSource valueSource = JSValueSource(JITCompiler::addressFor(virtualRegister));
1160         
1161 #if USE(JSVALUE64)
1162         if (isInt32Prediction(predictedType))
1163             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
1164         else if (isArrayPrediction(predictedType)) {
1165             GPRTemporary temp(this);
1166             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1167             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1168             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
1169         } else if (isBooleanPrediction(predictedType)) {
1170             GPRTemporary temp(this);
1171             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1172             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), temp.gpr());
1173             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1174         } else if (isInt8ArrayPrediction(predictedType)) {
1175             GPRTemporary temp(this);
1176             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1177             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1178             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_classInfo)));
1179         } else if (isInt16ArrayPrediction(predictedType)) {
1180             GPRTemporary temp(this);
1181             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1182             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1183             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_classInfo)));
1184         } else if (isInt32ArrayPrediction(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(m_jit.globalData()->int32ArrayDescriptor().m_classInfo)));
1189         } else if (isUint8ArrayPrediction(predictedType)) {
1190             GPRTemporary temp(this);
1191             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1192             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1193             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_classInfo)));
1194         } else if (isUint8ClampedArrayPrediction(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()->uint8ClampedArrayDescriptor().m_classInfo)));
1199         } else if (isUint16ArrayPrediction(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()->uint16ArrayDescriptor().m_classInfo)));
1204         } else if (isUint32ArrayPrediction(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()->uint32ArrayDescriptor().m_classInfo)));
1209         } else if (isFloat32ArrayPrediction(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()->float32ArrayDescriptor().m_classInfo)));
1214         } else if (isFloat64ArrayPrediction(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()->float64ArrayDescriptor().m_classInfo)));
1219         }
1220 #else
1221         if (isInt32Prediction(predictedType))
1222             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
1223         else if (isArrayPrediction(predictedType)) {
1224             GPRTemporary temp(this);
1225             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1226             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1227             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1228             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
1229         } else if (isBooleanPrediction(predictedType))
1230             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
1231         else if (isInt8ArrayPrediction(predictedType)) {
1232             GPRTemporary temp(this);
1233             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1234             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1235             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1236             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_classInfo)));
1237         } else if (isInt16ArrayPrediction(predictedType)) {
1238             GPRTemporary temp(this);
1239             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1240             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1241             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1242             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_classInfo)));
1243         } else if (isInt32ArrayPrediction(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(m_jit.globalData()->int32ArrayDescriptor().m_classInfo)));
1249         } else if (isUint8ArrayPrediction(predictedType)) {
1250             GPRTemporary temp(this);
1251             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1252             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1253             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1254             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_classInfo)));
1255         } else if (isUint8ClampedArrayPrediction(predictedType)) {
1256             GPRTemporary temp(this);
1257             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1258             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1259             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1260             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ClampedArrayDescriptor().m_classInfo)));
1261         } else if (isUint16ArrayPrediction(predictedType)) {
1262             GPRTemporary temp(this);
1263             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1264             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1265             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1266             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_classInfo)));
1267         }  else if (isUint32ArrayPrediction(predictedType)) {
1268             GPRTemporary temp(this);
1269             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1270             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1271             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1272             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_classInfo)));
1273         }  else if (isFloat32ArrayPrediction(predictedType)) {
1274             GPRTemporary temp(this);
1275             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1276             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1277             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1278             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_classInfo)));
1279         }   else if (isFloat64ArrayPrediction(predictedType)) {
1280             GPRTemporary temp(this);
1281             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1282             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1283             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1284             speculationCheck(BadType, valueSource, nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr(), JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_classInfo)));
1285         } 
1286 #endif
1287     }
1288     m_isCheckingArgumentTypes = false;
1289 }
1290
1291 bool SpeculativeJIT::compile()
1292 {
1293     checkArgumentTypes();
1294
1295     if (DFG_ENABLE_EDGE_CODE_VERIFICATION)
1296         m_jit.move(TrustedImm32(0), GPRInfo::regT0);
1297
1298     ASSERT(!m_compileIndex);
1299     for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
1300         BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
1301         if (block)
1302             compile(*block);
1303     }
1304     linkBranches();
1305     return true;
1306 }
1307
1308 void SpeculativeJIT::createOSREntries()
1309 {
1310     for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
1311         BasicBlock* block = m_jit.graph().m_blocks[blockIndex].get();
1312         if (!block)
1313             continue;
1314         if (!block->isOSRTarget)
1315             continue;
1316
1317         // Currently we only need to create OSR entry trampolines when using edge code
1318         // verification. But in the future, we'll need this for other things as well (like
1319         // when we have global reg alloc).
1320         // If we don't need OSR entry trampolin
1321         if (!DFG_ENABLE_EDGE_CODE_VERIFICATION) {
1322             m_osrEntryHeads.append(m_blockHeads[blockIndex]);
1323             continue;
1324         }
1325         
1326         m_osrEntryHeads.append(m_jit.label());
1327         m_jit.move(TrustedImm32(blockIndex), GPRInfo::regT0);
1328         m_jit.jump().linkTo(m_blockHeads[blockIndex], &m_jit);
1329     }
1330 }
1331
1332 void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
1333 {
1334     unsigned osrEntryIndex = 0;
1335     for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
1336         BasicBlock* block = m_jit.graph().m_blocks[blockIndex].get();
1337         if (!block)
1338             continue;
1339         if (!block->isOSRTarget)
1340             continue;
1341         m_jit.noticeOSREntry(*block, m_osrEntryHeads[osrEntryIndex++], linkBuffer);
1342     }
1343     ASSERT(osrEntryIndex == m_osrEntryHeads.size());
1344 }
1345
1346 ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
1347 {
1348     switch (valueSource.kind()) {
1349     case SourceIsDead:
1350         return ValueRecovery::constant(jsUndefined());
1351         
1352     case ValueInRegisterFile:
1353         return ValueRecovery::alreadyInRegisterFile();
1354         
1355     case Int32InRegisterFile:
1356         return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
1357
1358     case CellInRegisterFile:
1359         return ValueRecovery::alreadyInRegisterFileAsUnboxedCell();
1360
1361     case BooleanInRegisterFile:
1362         return ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean();
1363         
1364     case DoubleInRegisterFile:
1365         return ValueRecovery::alreadyInRegisterFileAsUnboxedDouble();
1366         
1367     case ArgumentsSource:
1368         return ValueRecovery::argumentsThatWereNotCreated();
1369
1370     case HaveNode: {
1371         Node* nodePtr = &at(valueSource.nodeIndex());
1372
1373         if (nodePtr->isPhantomArguments())
1374             return ValueRecovery::argumentsThatWereNotCreated();
1375         
1376         if (nodePtr->hasConstant())
1377             return ValueRecovery::constant(valueOfJSConstant(valueSource.nodeIndex()));
1378         
1379         if (!nodePtr->shouldGenerate()) {
1380             // It's legitimately dead. As in, nobody will ever use this node, or operand,
1381             // ever. Set it to Undefined to make the GC happy after the OSR.
1382             return ValueRecovery::constant(jsUndefined());
1383         }
1384     
1385         GenerationInfo* infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1386         if (!infoPtr->alive() || infoPtr->nodeIndex() != valueSource.nodeIndex()) {
1387             // Try to see if there is an alternate node that would contain the value we want.
1388             // There are four possibilities:
1389             //
1390             // Int32ToDouble: We can use this in place of the original node, but
1391             //    we'd rather not; so we use it only if it is the only remaining
1392             //    live version.
1393             //
1394             // ValueToInt32: If the only remaining live version of the value is
1395             //    ValueToInt32, then we can use it.
1396             //
1397             // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
1398             //    then the only remaining uses are ones that want a properly formed number
1399             //    rather than a UInt32 intermediate.
1400             //
1401             // The reverse of the above: This node could be a UInt32ToNumber, but its
1402             //    alternative is still alive. This means that the only remaining uses of
1403             //    the number would be fine with a UInt32 intermediate.
1404             //
1405             // DoubleAsInt32: Same as UInt32ToNumber.
1406             //
1407         
1408             bool found = false;
1409         
1410             if (nodePtr->op() == UInt32ToNumber || nodePtr->op() == DoubleAsInt32) {
1411                 NodeIndex nodeIndex = nodePtr->child1().index();
1412                 nodePtr = &at(nodeIndex);
1413                 infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1414                 if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
1415                     found = true;
1416             }
1417         
1418             if (!found) {
1419                 NodeIndex int32ToDoubleIndex = NoNode;
1420                 NodeIndex valueToInt32Index = NoNode;
1421                 NodeIndex uint32ToNumberIndex = NoNode;
1422                 NodeIndex doubleAsInt32Index = NoNode;
1423             
1424                 for (unsigned virtualRegister = 0; virtualRegister < m_generationInfo.size(); ++virtualRegister) {
1425                     GenerationInfo& info = m_generationInfo[virtualRegister];
1426                     if (!info.alive())
1427                         continue;
1428                     if (info.nodeIndex() == NoNode)
1429                         continue;
1430                     Node& node = at(info.nodeIndex());
1431                     if (node.child1Unchecked() != valueSource.nodeIndex())
1432                         continue;
1433                     switch (node.op()) {
1434                     case Int32ToDouble:
1435                         int32ToDoubleIndex = info.nodeIndex();
1436                         break;
1437                     case ValueToInt32:
1438                         valueToInt32Index = info.nodeIndex();
1439                         break;
1440                     case UInt32ToNumber:
1441                         uint32ToNumberIndex = info.nodeIndex();
1442                         break;
1443                     case DoubleAsInt32:
1444                         doubleAsInt32Index = info.nodeIndex();
1445                     default:
1446                         break;
1447                     }
1448                 }
1449             
1450                 NodeIndex nodeIndexToUse;
1451                 if (doubleAsInt32Index != NoNode)
1452                     nodeIndexToUse = doubleAsInt32Index;
1453                 else if (int32ToDoubleIndex != NoNode)
1454                     nodeIndexToUse = int32ToDoubleIndex;
1455                 else if (valueToInt32Index != NoNode)
1456                     nodeIndexToUse = valueToInt32Index;
1457                 else if (uint32ToNumberIndex != NoNode)
1458                     nodeIndexToUse = uint32ToNumberIndex;
1459                 else
1460                     nodeIndexToUse = NoNode;
1461             
1462                 if (nodeIndexToUse != NoNode) {
1463                     nodePtr = &at(nodeIndexToUse);
1464                     infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1465                     ASSERT(infoPtr->alive() && infoPtr->nodeIndex() == nodeIndexToUse);
1466                     found = true;
1467                 }
1468             }
1469         
1470             if (!found)
1471                 return ValueRecovery::constant(jsUndefined());
1472         }
1473     
1474         ASSERT(infoPtr->alive());
1475
1476         if (infoPtr->registerFormat() != DataFormatNone) {
1477             if (infoPtr->registerFormat() == DataFormatDouble)
1478                 return ValueRecovery::inFPR(infoPtr->fpr());
1479 #if USE(JSVALUE32_64)
1480             if (infoPtr->registerFormat() & DataFormatJS)
1481                 return ValueRecovery::inPair(infoPtr->tagGPR(), infoPtr->payloadGPR());
1482 #endif
1483             return ValueRecovery::inGPR(infoPtr->gpr(), infoPtr->registerFormat());
1484         }
1485         if (infoPtr->spillFormat() != DataFormatNone)
1486             return ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(nodePtr->virtualRegister()), infoPtr->spillFormat());
1487     
1488         ASSERT_NOT_REACHED();
1489         return ValueRecovery();
1490     }
1491         
1492     default:
1493         ASSERT_NOT_REACHED();
1494         return ValueRecovery();
1495     }
1496 }
1497
1498 void SpeculativeJIT::compileGetCharCodeAt(Node& node)
1499 {
1500     ASSERT(node.child3() == NoNode);
1501     SpeculateCellOperand string(this, node.child1());
1502     SpeculateStrictInt32Operand index(this, node.child2());
1503     StorageOperand storage(this, node.child3());
1504
1505     GPRReg stringReg = string.gpr();
1506     GPRReg indexReg = index.gpr();
1507     GPRReg storageReg = storage.gpr();
1508     
1509     if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) {
1510         ASSERT(!(at(node.child1()).prediction() & PredictString));
1511         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1512         noResult(m_compileIndex);
1513         return;
1514     }
1515
1516     // unsigned comparison so we can filter out negative indices and indices that are too large
1517     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));
1518
1519     GPRTemporary scratch(this);
1520     GPRReg scratchReg = scratch.gpr();
1521
1522     m_jit.loadPtr(MacroAssembler::Address(stringReg, JSString::offsetOfValue()), scratchReg);
1523
1524     // Load the character into scratchReg
1525     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1526
1527     m_jit.load8(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesOne, 0), scratchReg);
1528     JITCompiler::Jump cont8Bit = m_jit.jump();
1529
1530     is16Bit.link(&m_jit);
1531
1532     m_jit.load16(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesTwo, 0), scratchReg);
1533
1534     cont8Bit.link(&m_jit);
1535
1536     integerResult(scratchReg, m_compileIndex);
1537 }
1538
1539 void SpeculativeJIT::compileGetByValOnString(Node& node)
1540 {
1541     SpeculateCellOperand base(this, node.child1());
1542     SpeculateStrictInt32Operand property(this, node.child2());
1543     StorageOperand storage(this, node.child3());
1544     GPRReg baseReg = base.gpr();
1545     GPRReg propertyReg = property.gpr();
1546     GPRReg storageReg = storage.gpr();
1547
1548     if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) {
1549         ASSERT(!(at(node.child1()).prediction() & PredictString));
1550         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1551         noResult(m_compileIndex);
1552         return;
1553     }
1554
1555     // unsigned comparison so we can filter out negative indices and indices that are too large
1556     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));
1557
1558     GPRTemporary scratch(this);
1559     GPRReg scratchReg = scratch.gpr();
1560
1561     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), scratchReg);
1562
1563     // Load the character into scratchReg
1564     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1565
1566     m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne, 0), scratchReg);
1567     JITCompiler::Jump cont8Bit = m_jit.jump();
1568
1569     is16Bit.link(&m_jit);
1570
1571     m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
1572
1573     // We only support ascii characters
1574     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
1575
1576     // 8 bit string values don't need the isASCII check.
1577     cont8Bit.link(&m_jit);
1578
1579     GPRTemporary smallStrings(this);
1580     GPRReg smallStringsReg = smallStrings.gpr();
1581     m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg);
1582     m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg);
1583     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
1584     cellResult(scratchReg, m_compileIndex);
1585 }
1586
1587 GeneratedOperandType SpeculativeJIT::checkGeneratedTypeForToInt32(NodeIndex nodeIndex)
1588 {
1589 #if DFG_ENABLE(DEBUG_VERBOSE)
1590     dataLog("checkGeneratedTypeForToInt32@%d   ", nodeIndex);
1591 #endif
1592     Node& node = at(nodeIndex);
1593     VirtualRegister virtualRegister = node.virtualRegister();
1594     GenerationInfo& info = m_generationInfo[virtualRegister];
1595
1596     if (info.registerFormat() == DataFormatNone) {
1597         if (node.hasConstant()) {
1598             if (isInt32Constant(nodeIndex))
1599                 return GeneratedOperandInteger;
1600
1601             if (isNumberConstant(nodeIndex))
1602                 return GeneratedOperandDouble;
1603
1604             terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1605             return GeneratedOperandTypeUnknown;
1606         }
1607
1608         if (info.spillFormat() == DataFormatDouble)
1609             return GeneratedOperandDouble;
1610     }
1611
1612     switch (info.registerFormat()) {
1613     case DataFormatBoolean: // This type never occurs.
1614     case DataFormatStorage:
1615         ASSERT_NOT_REACHED();
1616
1617     case DataFormatCell:
1618         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1619         return GeneratedOperandTypeUnknown;
1620
1621     case DataFormatNone:
1622     case DataFormatJSCell:
1623     case DataFormatJS:
1624     case DataFormatJSBoolean:
1625         return GeneratedOperandJSValue;
1626
1627     case DataFormatJSInteger:
1628     case DataFormatInteger:
1629         return GeneratedOperandInteger;
1630
1631     case DataFormatJSDouble:
1632     case DataFormatDouble:
1633         return GeneratedOperandDouble;
1634     }
1635
1636     ASSERT_NOT_REACHED();
1637     return GeneratedOperandTypeUnknown;
1638 }
1639
1640 void SpeculativeJIT::compileValueToInt32(Node& node)
1641 {
1642     if (at(node.child1()).shouldSpeculateInteger()) {
1643         SpeculateIntegerOperand op1(this, node.child1());
1644         GPRTemporary result(this, op1);
1645         m_jit.move(op1.gpr(), result.gpr());
1646         integerResult(result.gpr(), m_compileIndex, op1.format());
1647         return;
1648     }
1649     
1650     if (at(node.child1()).shouldSpeculateNumber()) {
1651         switch (checkGeneratedTypeForToInt32(node.child1().index())) {
1652         case GeneratedOperandInteger: {
1653             SpeculateIntegerOperand op1(this, node.child1());
1654             GPRTemporary result(this, op1);
1655             m_jit.move(op1.gpr(), result.gpr());
1656             integerResult(result.gpr(), m_compileIndex, op1.format());
1657             return;
1658         }
1659         case GeneratedOperandDouble: {
1660             GPRTemporary result(this);
1661             DoubleOperand op1(this, node.child1());
1662             FPRReg fpr = op1.fpr();
1663             GPRReg gpr = result.gpr();
1664             JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
1665             
1666             addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this, toInt32, gpr, fpr));
1667
1668             integerResult(gpr, m_compileIndex);
1669             return;
1670         }
1671         case GeneratedOperandJSValue: {
1672             GPRTemporary result(this);
1673 #if USE(JSVALUE64)
1674             JSValueOperand op1(this, node.child1());
1675
1676             GPRReg gpr = op1.gpr();
1677             GPRReg resultGpr = result.gpr();
1678             FPRTemporary tempFpr(this);
1679             FPRReg fpr = tempFpr.fpr();
1680
1681             JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, gpr, GPRInfo::tagTypeNumberRegister);
1682
1683             if (!isNumberPrediction(m_state.forNode(node.child1()).m_type))
1684                 speculationCheck(BadType, JSValueRegs(gpr), node.child1().index(), m_jit.branchTestPtr(MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
1685
1686             // First, if we get here we have a double encoded as a JSValue
1687             m_jit.move(gpr, resultGpr);
1688             unboxDouble(resultGpr, fpr);
1689
1690             silentSpillAllRegisters(resultGpr);
1691             callOperation(toInt32, resultGpr, fpr);
1692             silentFillAllRegisters(resultGpr);
1693
1694             JITCompiler::Jump converted = m_jit.jump();
1695
1696             isInteger.link(&m_jit);
1697             m_jit.zeroExtend32ToPtr(gpr, resultGpr);
1698
1699             converted.link(&m_jit);
1700 #else
1701             Node& childNode = at(node.child1().index());
1702             VirtualRegister virtualRegister = childNode.virtualRegister();
1703             GenerationInfo& info = m_generationInfo[virtualRegister];
1704
1705             JSValueOperand op1(this, node.child1());
1706
1707             GPRReg payloadGPR = op1.payloadGPR();
1708             GPRReg resultGpr = result.gpr();
1709
1710             if (info.registerFormat() == DataFormatJSInteger)
1711                 m_jit.move(payloadGPR, resultGpr);
1712             else {
1713                 GPRReg tagGPR = op1.tagGPR();
1714                 FPRTemporary tempFpr(this);
1715                 FPRReg fpr = tempFpr.fpr();
1716                 FPRTemporary scratch(this);
1717
1718                 JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
1719
1720                 if (!isNumberPrediction(m_state.forNode(node.child1()).m_type))
1721                     speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), node.child1().index(), m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
1722
1723                 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
1724
1725                 silentSpillAllRegisters(resultGpr);
1726                 callOperation(toInt32, resultGpr, fpr);
1727                 silentFillAllRegisters(resultGpr);
1728
1729                 JITCompiler::Jump converted = m_jit.jump();
1730
1731                 isInteger.link(&m_jit);
1732                 m_jit.move(payloadGPR, resultGpr);
1733
1734                 converted.link(&m_jit);
1735             }
1736 #endif
1737             integerResult(resultGpr, m_compileIndex);
1738             return;
1739         }
1740         case GeneratedOperandTypeUnknown:
1741             ASSERT_NOT_REACHED();
1742             break;
1743         }
1744     }
1745     
1746     if (at(node.child1()).shouldSpeculateBoolean()) {
1747         SpeculateBooleanOperand op1(this, node.child1());
1748         GPRTemporary result(this, op1);
1749         
1750         m_jit.and32(JITCompiler::TrustedImm32(1), op1.gpr());
1751         
1752         integerResult(op1.gpr(), m_compileIndex);
1753         return;
1754     }
1755     
1756     // Do it the safe way.
1757     nonSpeculativeValueToInt32(node);
1758     return;
1759 }
1760
1761 void SpeculativeJIT::compileUInt32ToNumber(Node& node)
1762 {
1763     if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
1764         // We know that this sometimes produces doubles. So produce a double every
1765         // time. This at least allows subsequent code to not have weird conditionals.
1766             
1767         IntegerOperand op1(this, node.child1());
1768         FPRTemporary result(this);
1769             
1770         GPRReg inputGPR = op1.gpr();
1771         FPRReg outputFPR = result.fpr();
1772             
1773         m_jit.convertInt32ToDouble(inputGPR, outputFPR);
1774             
1775         JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
1776         m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), outputFPR);
1777         positive.link(&m_jit);
1778             
1779         doubleResult(outputFPR, m_compileIndex);
1780         return;
1781     }
1782
1783     IntegerOperand op1(this, node.child1());
1784     GPRTemporary result(this, op1);
1785
1786     // Test the operand is positive. This is a very special speculation check - we actually
1787     // use roll-forward speculation here, where if this fails, we jump to the baseline
1788     // instruction that follows us, rather than the one we're executing right now. We have
1789     // to do this because by this point, the original values necessary to compile whatever
1790     // operation the UInt32ToNumber originated from might be dead.
1791     forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)), ValueRecovery::uint32InGPR(op1.gpr()));
1792
1793     m_jit.move(op1.gpr(), result.gpr());
1794     integerResult(result.gpr(), m_compileIndex, op1.format());
1795 }
1796
1797 void SpeculativeJIT::compileDoubleAsInt32(Node& node)
1798 {
1799     SpeculateDoubleOperand op1(this, node.child1());
1800     FPRTemporary scratch(this);
1801     GPRTemporary result(this);
1802     
1803     FPRReg valueFPR = op1.fpr();
1804     FPRReg scratchFPR = scratch.fpr();
1805     GPRReg resultGPR = result.gpr();
1806
1807     JITCompiler::JumpList failureCases;
1808     m_jit.branchConvertDoubleToInt32(valueFPR, resultGPR, failureCases, scratchFPR);
1809     forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, failureCases, ValueRecovery::inFPR(valueFPR));
1810
1811     integerResult(resultGPR, m_compileIndex);
1812 }
1813
1814 void SpeculativeJIT::compileInt32ToDouble(Node& node)
1815 {
1816 #if USE(JSVALUE64)
1817     // On JSVALUE64 we have a way of loading double constants in a more direct manner
1818     // than a int->double conversion. On 32_64, unfortunately, we currently don't have
1819     // any such mechanism - though we could have it, if we just provisioned some memory
1820     // in CodeBlock for the double form of integer constants.
1821     if (at(node.child1()).hasConstant()) {
1822         ASSERT(isInt32Constant(node.child1().index()));
1823         FPRTemporary result(this);
1824         GPRTemporary temp(this);
1825         m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(node.child1().index())))), temp.gpr());
1826         m_jit.movePtrToDouble(temp.gpr(), result.fpr());
1827         doubleResult(result.fpr(), m_compileIndex);
1828         return;
1829     }
1830 #endif
1831     
1832     if (isInt32Prediction(m_state.forNode(node.child1()).m_type)) {
1833         SpeculateIntegerOperand op1(this, node.child1());
1834         FPRTemporary result(this);
1835         m_jit.convertInt32ToDouble(op1.gpr(), result.fpr());
1836         doubleResult(result.fpr(), m_compileIndex);
1837         return;
1838     }
1839     
1840     JSValueOperand op1(this, node.child1());
1841     FPRTemporary result(this);
1842     
1843 #if USE(JSVALUE64)
1844     GPRTemporary temp(this);
1845
1846     GPRReg op1GPR = op1.gpr();
1847     GPRReg tempGPR = temp.gpr();
1848     FPRReg resultFPR = result.fpr();
1849     
1850     JITCompiler::Jump isInteger = m_jit.branchPtr(
1851         MacroAssembler::AboveOrEqual, op1GPR, GPRInfo::tagTypeNumberRegister);
1852     
1853     if (!isNumberPrediction(m_state.forNode(node.child1()).m_type)) {
1854         speculationCheck(
1855             BadType, JSValueRegs(op1GPR), node.child1(),
1856             m_jit.branchTestPtr(MacroAssembler::Zero, op1GPR, GPRInfo::tagTypeNumberRegister));
1857     }
1858     
1859     m_jit.move(op1GPR, tempGPR);
1860     unboxDouble(tempGPR, resultFPR);
1861     JITCompiler::Jump done = m_jit.jump();
1862     
1863     isInteger.link(&m_jit);
1864     m_jit.convertInt32ToDouble(op1GPR, resultFPR);
1865     done.link(&m_jit);
1866 #else
1867     FPRTemporary temp(this);
1868     
1869     GPRReg op1TagGPR = op1.tagGPR();
1870     GPRReg op1PayloadGPR = op1.payloadGPR();
1871     FPRReg tempFPR = temp.fpr();
1872     FPRReg resultFPR = result.fpr();
1873     
1874     JITCompiler::Jump isInteger = m_jit.branch32(
1875         MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
1876     
1877     if (!isNumberPrediction(m_state.forNode(node.child1()).m_type)) {
1878         speculationCheck(
1879             BadType, JSValueRegs(op1TagGPR, op1PayloadGPR), node.child1(),
1880             m_jit.branch32(MacroAssembler::AboveOrEqual, op1TagGPR, TrustedImm32(JSValue::LowestTag)));
1881     }
1882     
1883     unboxDouble(op1TagGPR, op1PayloadGPR, resultFPR, tempFPR);
1884     JITCompiler::Jump done = m_jit.jump();
1885     
1886     isInteger.link(&m_jit);
1887     m_jit.convertInt32ToDouble(op1PayloadGPR, resultFPR);
1888     done.link(&m_jit);
1889 #endif
1890     
1891     doubleResult(resultFPR, m_compileIndex);
1892 }
1893
1894 static double clampDoubleToByte(double d)
1895 {
1896     d += 0.5;
1897     if (!(d > 0))
1898         d = 0;
1899     else if (d > 255)
1900         d = 255;
1901     return d;
1902 }
1903
1904 static void compileClampIntegerToByte(JITCompiler& jit, GPRReg result)
1905 {
1906     MacroAssembler::Jump inBounds = jit.branch32(MacroAssembler::BelowOrEqual, result, JITCompiler::TrustedImm32(0xff));
1907     MacroAssembler::Jump tooBig = jit.branch32(MacroAssembler::GreaterThan, result, JITCompiler::TrustedImm32(0xff));
1908     jit.xorPtr(result, result);
1909     MacroAssembler::Jump clamped = jit.jump();
1910     tooBig.link(&jit);
1911     jit.move(JITCompiler::TrustedImm32(255), result);
1912     clamped.link(&jit);
1913     inBounds.link(&jit);
1914 }
1915
1916 static void compileClampDoubleToByte(JITCompiler& jit, GPRReg result, FPRReg source, FPRReg scratch)
1917 {
1918     // Unordered compare so we pick up NaN
1919     static const double zero = 0;
1920     static const double byteMax = 255;
1921     static const double half = 0.5;
1922     jit.loadDouble(&zero, scratch);
1923     MacroAssembler::Jump tooSmall = jit.branchDouble(MacroAssembler::DoubleLessThanOrEqualOrUnordered, source, scratch);
1924     jit.loadDouble(&byteMax, scratch);
1925     MacroAssembler::Jump tooBig = jit.branchDouble(MacroAssembler::DoubleGreaterThan, source, scratch);
1926     
1927     jit.loadDouble(&half, scratch);
1928     // FIXME: This should probably just use a floating point round!
1929     // https://bugs.webkit.org/show_bug.cgi?id=72054
1930     jit.addDouble(source, scratch);
1931     jit.truncateDoubleToInt32(scratch, result);   
1932     MacroAssembler::Jump truncatedInt = jit.jump();
1933     
1934     tooSmall.link(&jit);
1935     jit.xorPtr(result, result);
1936     MacroAssembler::Jump zeroed = jit.jump();
1937     
1938     tooBig.link(&jit);
1939     jit.move(JITCompiler::TrustedImm32(255), result);
1940     
1941     truncatedInt.link(&jit);
1942     zeroed.link(&jit);
1943
1944 }
1945
1946 void SpeculativeJIT::compileGetTypedArrayLength(const TypedArrayDescriptor& descriptor, Node& node, bool needsSpeculationCheck)
1947 {
1948     SpeculateCellOperand base(this, node.child1());
1949     GPRTemporary result(this);
1950     
1951     GPRReg baseGPR = base.gpr();
1952     GPRReg resultGPR = result.gpr();
1953     
1954     if (needsSpeculationCheck)
1955         speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
1956     
1957     m_jit.load32(MacroAssembler::Address(baseGPR, descriptor.m_lengthOffset), resultGPR);
1958     
1959     integerResult(resultGPR, m_compileIndex);
1960 }
1961
1962 void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness)
1963 {
1964     SpeculateCellOperand base(this, node.child1());
1965     SpeculateStrictInt32Operand property(this, node.child2());
1966     StorageOperand storage(this, node.child3());
1967
1968     GPRReg baseReg = base.gpr();
1969     GPRReg propertyReg = property.gpr();
1970     GPRReg storageReg = storage.gpr();
1971
1972     GPRTemporary result(this);
1973     GPRReg resultReg = result.gpr();
1974
1975     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
1976         ASSERT_NOT_REACHED();
1977         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1978         noResult(m_compileIndex);
1979         return;
1980     }
1981
1982     MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
1983     m_jit.xorPtr(resultReg, resultReg);
1984     MacroAssembler::Jump outOfBounds = m_jit.jump();
1985     inBounds.link(&m_jit);
1986     switch (elementSize) {
1987     case 1:
1988         if (signedness == SignedTypedArray)
1989             m_jit.load8Signed(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
1990         else
1991             m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
1992         break;
1993     case 2:
1994         if (signedness == SignedTypedArray)
1995             m_jit.load16Signed(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
1996         else
1997             m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
1998         break;
1999     case 4:
2000         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
2001         break;
2002     default:
2003         ASSERT_NOT_REACHED();
2004     }
2005     outOfBounds.link(&m_jit);
2006     if (elementSize < 4 || signedness == SignedTypedArray) {
2007         integerResult(resultReg, m_compileIndex);
2008         return;
2009     }
2010     
2011     ASSERT(elementSize == 4 && signedness == UnsignedTypedArray);
2012     if (node.shouldSpeculateInteger()) {
2013         forwardSpeculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultReg, TrustedImm32(0)), ValueRecovery::uint32InGPR(resultReg));
2014         integerResult(resultReg, m_compileIndex);
2015         return;
2016     }
2017     
2018     FPRTemporary fresult(this);
2019     m_jit.convertInt32ToDouble(resultReg, fresult.fpr());
2020     JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, resultReg, TrustedImm32(0));
2021     m_jit.addDouble(JITCompiler::AbsoluteAddress(&AssemblyHelpers::twoToThe32), fresult.fpr());
2022     positive.link(&m_jit);
2023     doubleResult(fresult.fpr(), m_compileIndex);
2024 }
2025
2026 void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness, TypedArrayRounding rounding)
2027 {
2028     Edge baseUse = node.child1();
2029     Edge valueUse = node.child3();
2030     
2031     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
2032         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
2033     GPRTemporary value;
2034     GPRReg valueGPR;
2035     
2036     if (at(valueUse).isConstant()) {
2037         JSValue jsValue = valueOfJSConstant(valueUse.index());
2038         if (!jsValue.isNumber()) {
2039             terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2040             noResult(m_compileIndex);
2041             return;
2042         }
2043         double d = jsValue.asNumber();
2044         if (rounding == ClampRounding) {
2045             ASSERT(elementSize == 1);
2046             d = clampDoubleToByte(d);
2047         }
2048         GPRTemporary scratch(this);
2049         GPRReg scratchReg = scratch.gpr();
2050         m_jit.move(Imm32(toInt32(d)), scratchReg);
2051         value.adopt(scratch);
2052         valueGPR = scratchReg;
2053     } else if (at(valueUse).shouldSpeculateInteger()) {
2054         SpeculateIntegerOperand valueOp(this, valueUse);
2055         GPRTemporary scratch(this);
2056         GPRReg scratchReg = scratch.gpr();
2057         m_jit.move(valueOp.gpr(), scratchReg);
2058         if (rounding == ClampRounding) {
2059             ASSERT(elementSize == 1);
2060             compileClampIntegerToByte(m_jit, scratchReg);
2061         }
2062         value.adopt(scratch);
2063         valueGPR = scratchReg;
2064     } else if (rounding == ClampRounding) {
2065         ASSERT(elementSize == 1);
2066         SpeculateDoubleOperand valueOp(this, valueUse);
2067         GPRTemporary result(this);
2068         FPRTemporary floatScratch(this);
2069         FPRReg fpr = valueOp.fpr();
2070         GPRReg gpr = result.gpr();
2071         compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
2072         value.adopt(result);
2073         valueGPR = gpr;
2074     } else {
2075         SpeculateDoubleOperand valueOp(this, valueUse);
2076         GPRTemporary result(this);
2077         FPRReg fpr = valueOp.fpr();
2078         GPRReg gpr = result.gpr();
2079         MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
2080         m_jit.xorPtr(gpr, gpr);
2081         MacroAssembler::Jump fixed = m_jit.jump();
2082         notNaN.link(&m_jit);
2083
2084         MacroAssembler::Jump failed;
2085         if (signedness == SignedTypedArray)
2086             failed = m_jit.branchTruncateDoubleToInt32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
2087         else
2088             failed = m_jit.branchTruncateDoubleToUint32(fpr, gpr, MacroAssembler::BranchIfTruncateFailed);
2089         
2090         addSlowPathGenerator(slowPathCall(failed, this, toInt32, gpr, fpr));
2091
2092         fixed.link(&m_jit);
2093         value.adopt(result);
2094         valueGPR = gpr;
2095     }
2096     ASSERT_UNUSED(valueGPR, valueGPR != property);
2097     ASSERT(valueGPR != base);
2098     GPRTemporary storage(this);
2099     GPRReg storageReg = storage.gpr();
2100     ASSERT(valueGPR != storageReg);
2101     m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
2102     MacroAssembler::Jump outOfBounds;
2103     if (speculationRequirements != NoTypedArraySpecCheck)
2104         outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
2105
2106     switch (elementSize) {
2107     case 1:
2108         m_jit.store8(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesOne));
2109         break;
2110     case 2:
2111         m_jit.store16(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesTwo));
2112         break;
2113     case 4:
2114         m_jit.store32(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
2115         break;
2116     default:
2117         ASSERT_NOT_REACHED();
2118     }
2119     if (speculationRequirements != NoTypedArraySpecCheck)
2120         outOfBounds.link(&m_jit);
2121     noResult(m_compileIndex);
2122 }
2123
2124 void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
2125 {
2126     SpeculateCellOperand base(this, node.child1());
2127     SpeculateStrictInt32Operand property(this, node.child2());
2128     StorageOperand storage(this, node.child3());
2129
2130     GPRReg baseReg = base.gpr();
2131     GPRReg propertyReg = property.gpr();
2132     GPRReg storageReg = storage.gpr();
2133     
2134     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
2135         ASSERT_NOT_REACHED();
2136         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2137         noResult(m_compileIndex);
2138         return;
2139     }
2140
2141     FPRTemporary result(this);
2142     FPRReg resultReg = result.fpr();
2143     ASSERT(speculationRequirements != NoTypedArraySpecCheck);
2144     MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
2145     static const double zero = 0;
2146     m_jit.loadDouble(&zero, resultReg);
2147     MacroAssembler::Jump outOfBounds = m_jit.jump();
2148     inBounds.link(&m_jit);
2149     switch (elementSize) {
2150     case 4:
2151         m_jit.loadFloat(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
2152         m_jit.convertFloatToDouble(resultReg, resultReg);
2153         break;
2154     case 8: {
2155         m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2156         MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
2157         static const double NaN = std::numeric_limits<double>::quiet_NaN();
2158         m_jit.loadDouble(&NaN, resultReg);
2159         notNaN.link(&m_jit);
2160         break;
2161     }
2162     default:
2163         ASSERT_NOT_REACHED();
2164     }
2165     outOfBounds.link(&m_jit);
2166     doubleResult(resultReg, m_compileIndex);
2167 }
2168
2169 void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
2170 {
2171     Edge baseUse = node.child1();
2172     Edge valueUse = node.child3();
2173     
2174     SpeculateDoubleOperand valueOp(this, valueUse);
2175     
2176     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
2177         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseUse.index(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
2178     
2179     GPRTemporary result(this);
2180     
2181     GPRTemporary storage(this);
2182     GPRReg storageReg = storage.gpr();
2183     
2184     m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
2185     MacroAssembler::Jump outOfBounds;
2186     if (speculationRequirements != NoTypedArraySpecCheck)
2187         outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
2188     
2189     switch (elementSize) {
2190     case 4: {
2191         FPRTemporary scratch(this);
2192         m_jit.moveDouble(valueOp.fpr(), scratch.fpr());
2193         m_jit.convertDoubleToFloat(valueOp.fpr(), scratch.fpr());
2194         m_jit.storeFloat(scratch.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
2195         break;
2196     }
2197     case 8:
2198         m_jit.storeDouble(valueOp.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesEight));
2199         break;
2200     default:
2201         ASSERT_NOT_REACHED();
2202     }
2203     if (speculationRequirements != NoTypedArraySpecCheck)
2204         outOfBounds.link(&m_jit);
2205     noResult(m_compileIndex);
2206 }
2207
2208 void SpeculativeJIT::compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg)
2209 {
2210     // Check that prototype is an object.
2211     m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
2212     speculationCheck(BadType, JSValueRegs(), NoNode, m_jit.branchIfNotObject(scratchReg));
2213     
2214     // Initialize scratchReg with the value being checked.
2215     m_jit.move(valueReg, scratchReg);
2216     
2217     // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
2218     MacroAssembler::Label loop(&m_jit);
2219     m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
2220 #if USE(JSVALUE64)
2221     m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset()), scratchReg);
2222 #else
2223     m_jit.load32(MacroAssembler::Address(scratchReg, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), scratchReg);
2224 #endif
2225     MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
2226 #if USE(JSVALUE64)
2227     m_jit.branchTestPtr(MacroAssembler::Zero, scratchReg, GPRInfo::tagMaskRegister).linkTo(loop, &m_jit);
2228 #else
2229     m_jit.branchTest32(MacroAssembler::NonZero, scratchReg).linkTo(loop, &m_jit);
2230 #endif
2231     
2232     // No match - result is false.
2233 #if USE(JSVALUE64)
2234     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
2235 #else
2236     m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
2237 #endif
2238     MacroAssembler::Jump putResult = m_jit.jump();
2239     
2240     isInstance.link(&m_jit);
2241 #if USE(JSVALUE64)
2242     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), scratchReg);
2243 #else
2244     m_jit.move(MacroAssembler::TrustedImm32(1), scratchReg);
2245 #endif
2246     
2247     putResult.link(&m_jit);
2248 }
2249
2250 void SpeculativeJIT::compileInstanceOf(Node& node)
2251 {
2252     if ((!!(at(node.child1()).prediction() & ~PredictCell)
2253          && !!(m_state.forNode(node.child1()).m_type & ~PredictCell))
2254         || at(node.child1()).adjustedRefCount() == 1) {
2255         // It might not be a cell. Speculate less aggressively.
2256         // Or: it might only be used once (i.e. by us), so we get zero benefit
2257         // from speculating any more aggressively than we absolutely need to.
2258         
2259         JSValueOperand value(this, node.child1());
2260         SpeculateCellOperand prototype(this, node.child3());
2261         GPRTemporary scratch(this);
2262         
2263         GPRReg prototypeReg = prototype.gpr();
2264         GPRReg scratchReg = scratch.gpr();
2265         
2266 #if USE(JSVALUE64)
2267         GPRReg valueReg = value.gpr();
2268         MacroAssembler::Jump isCell = m_jit.branchTestPtr(MacroAssembler::Zero, valueReg, GPRInfo::tagMaskRegister);
2269         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
2270 #else
2271         GPRReg valueTagReg = value.tagGPR();
2272         GPRReg valueReg = value.payloadGPR();
2273         MacroAssembler::Jump isCell = m_jit.branch32(MacroAssembler::Equal, valueTagReg, TrustedImm32(JSValue::CellTag));
2274         m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
2275 #endif
2276
2277         MacroAssembler::Jump done = m_jit.jump();
2278         
2279         isCell.link(&m_jit);
2280         
2281         compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
2282         
2283         done.link(&m_jit);
2284
2285 #if USE(JSVALUE64)
2286         jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
2287 #else
2288         booleanResult(scratchReg, m_compileIndex);
2289 #endif
2290         return;
2291     }
2292     
2293     SpeculateCellOperand value(this, node.child1());
2294     // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
2295     SpeculateCellOperand prototype(this, node.child3());
2296     
2297     GPRTemporary scratch(this);
2298     
2299     GPRReg valueReg = value.gpr();
2300     GPRReg prototypeReg = prototype.gpr();
2301     GPRReg scratchReg = scratch.gpr();
2302     
2303     compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
2304
2305 #if USE(JSVALUE64)
2306     jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
2307 #else
2308     booleanResult(scratchReg, m_compileIndex);
2309 #endif
2310 }
2311
2312 void SpeculativeJIT::compileSoftModulo(Node& node)
2313 {
2314     // In the fast path, the dividend value could be the final result
2315     // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
2316     SpeculateStrictInt32Operand op1(this, node.child1());
2317 #if CPU(X86) || CPU(X86_64)
2318     if (isInt32Constant(node.child2().index())) {
2319         int32_t divisor = valueOfInt32Constant(node.child2().index());
2320         if (divisor) {
2321             GPRReg op1Gpr = op1.gpr();
2322
2323             GPRTemporary eax(this, X86Registers::eax);
2324             GPRTemporary edx(this, X86Registers::edx);
2325             GPRTemporary scratch(this);
2326             GPRReg scratchGPR = scratch.gpr();
2327
2328             GPRReg op1SaveGPR;
2329             if (op1Gpr == X86Registers::eax || op1Gpr == X86Registers::edx) {
2330                 op1SaveGPR = allocate();
2331                 ASSERT(op1Gpr != op1SaveGPR);
2332                 m_jit.move(op1Gpr, op1SaveGPR);
2333             } else
2334                 op1SaveGPR = op1Gpr;
2335             ASSERT(op1SaveGPR != X86Registers::eax);
2336             ASSERT(op1SaveGPR != X86Registers::edx);
2337
2338             m_jit.move(op1Gpr, eax.gpr());
2339             m_jit.move(TrustedImm32(divisor), scratchGPR);
2340             if (divisor == -1)
2341                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, eax.gpr(), TrustedImm32(-2147483647-1)));
2342             m_jit.assembler().cdq();
2343             m_jit.assembler().idivl_r(scratchGPR);
2344             // Check that we're not about to create negative zero.
2345             // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
2346             JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
2347             speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
2348             numeratorPositive.link(&m_jit);
2349             
2350             if (op1SaveGPR != op1Gpr)
2351                 unlock(op1SaveGPR);
2352
2353             integerResult(edx.gpr(), m_compileIndex);
2354             return;
2355         }
2356     }
2357 #endif
2358
2359     SpeculateIntegerOperand op2(this, node.child2());
2360 #if CPU(X86) || CPU(X86_64)
2361     GPRTemporary eax(this, X86Registers::eax);
2362     GPRTemporary edx(this, X86Registers::edx);
2363     GPRReg op1GPR = op1.gpr();
2364     GPRReg op2GPR = op2.gpr();
2365     
2366     GPRReg op2TempGPR;
2367     GPRReg temp;
2368     GPRReg op1SaveGPR;
2369     
2370     if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
2371         op2TempGPR = allocate();
2372         temp = op2TempGPR;
2373     } else {
2374         op2TempGPR = InvalidGPRReg;
2375         if (op1GPR == X86Registers::eax)
2376             temp = X86Registers::edx;
2377         else
2378             temp = X86Registers::eax;
2379     }
2380     
2381     if (op1GPR == X86Registers::eax || op1GPR == X86Registers::edx) {
2382         op1SaveGPR = allocate();
2383         ASSERT(op1GPR != op1SaveGPR);
2384         m_jit.move(op1GPR, op1SaveGPR);
2385     } else
2386         op1SaveGPR = op1GPR;
2387     
2388     ASSERT(temp != op1GPR);
2389     ASSERT(temp != op2GPR);
2390     ASSERT(op1SaveGPR != X86Registers::eax);
2391     ASSERT(op1SaveGPR != X86Registers::edx);
2392     
2393     m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp);
2394     
2395     JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
2396     
2397     JITCompiler::Jump done;
2398     // FIXME: if the node is not used as number then we can do this more easily.
2399     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
2400     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
2401     
2402     safeDenominator.link(&m_jit);
2403             
2404     if (op2TempGPR != InvalidGPRReg) {
2405         m_jit.move(op2GPR, op2TempGPR);
2406         op2GPR = op2TempGPR;
2407     }
2408             
2409     m_jit.move(op1GPR, eax.gpr());
2410     m_jit.assembler().cdq();
2411     m_jit.assembler().idivl_r(op2GPR);
2412             
2413     if (op2TempGPR != InvalidGPRReg)
2414         unlock(op2TempGPR);
2415
2416     // Check that we're not about to create negative zero.
2417     // FIXME: if the node use doesn't care about neg zero, we can do this more easily.
2418     JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1SaveGPR, TrustedImm32(0));
2419     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, edx.gpr()));
2420     numeratorPositive.link(&m_jit);
2421     
2422     if (op1SaveGPR != op1GPR)
2423         unlock(op1SaveGPR);
2424             
2425     integerResult(edx.gpr(), m_compileIndex);
2426 #else // CPU(X86) || CPU(X86_64) --> so not X86
2427     // Do this the *safest* way possible: call out to a C function that will do the modulo,
2428     // and then attempt to convert back.
2429     GPRReg op1GPR = op1.gpr();
2430     GPRReg op2GPR = op2.gpr();
2431     
2432     FPRResult result(this);
2433     
2434     flushRegisters();
2435     callOperation(operationFModOnInts, result.fpr(), op1GPR, op2GPR);
2436     
2437     FPRTemporary scratch(this);
2438     GPRTemporary intResult(this);
2439     JITCompiler::JumpList failureCases;
2440     m_jit.branchConvertDoubleToInt32(result.fpr(), intResult.gpr(), failureCases, scratch.fpr());
2441     speculationCheck(Overflow, JSValueRegs(), NoNode, failureCases);
2442     
2443     integerResult(intResult.gpr(), m_compileIndex);
2444 #endif // CPU(X86) || CPU(X86_64)
2445 }
2446
2447 void SpeculativeJIT::compileAdd(Node& node)
2448 {
2449     if (m_jit.graph().addShouldSpeculateInteger(node)) {
2450         if (isNumberConstant(node.child1().index())) {
2451             int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
2452             SpeculateIntegerOperand op2(this, node.child2());
2453             GPRTemporary result(this);
2454
2455             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2456                 m_jit.move(op2.gpr(), result.gpr());
2457                 m_jit.add32(Imm32(imm1), result.gpr());
2458             } else
2459                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
2460
2461             integerResult(result.gpr(), m_compileIndex);
2462             return;
2463         }
2464                 
2465         if (isNumberConstant(node.child2().index())) {
2466             SpeculateIntegerOperand op1(this, node.child1());
2467             int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
2468             GPRTemporary result(this);
2469                 
2470             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2471                 m_jit.move(op1.gpr(), result.gpr());
2472                 m_jit.add32(Imm32(imm2), result.gpr());
2473             } else
2474                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
2475
2476             integerResult(result.gpr(), m_compileIndex);
2477             return;
2478         }
2479                 
2480         SpeculateIntegerOperand op1(this, node.child1());
2481         SpeculateIntegerOperand op2(this, node.child2());
2482         GPRTemporary result(this, op1, op2);
2483
2484         GPRReg gpr1 = op1.gpr();
2485         GPRReg gpr2 = op2.gpr();
2486         GPRReg gprResult = result.gpr();
2487
2488         if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2489             if (gpr1 == gprResult)
2490                 m_jit.add32(gpr2, gprResult);
2491             else {
2492                 m_jit.move(gpr2, gprResult);
2493                 m_jit.add32(gpr1, gprResult);
2494             }
2495         } else {
2496             MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
2497                 
2498             if (gpr1 == gprResult)
2499                 speculationCheck(Overflow, JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
2500             else if (gpr2 == gprResult)
2501                 speculationCheck(Overflow, JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
2502             else
2503                 speculationCheck(Overflow, JSValueRegs(), NoNode, check);
2504         }
2505
2506         integerResult(gprResult, m_compileIndex);
2507         return;
2508     }
2509         
2510     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2511         SpeculateDoubleOperand op1(this, node.child1());
2512         SpeculateDoubleOperand op2(this, node.child2());
2513         FPRTemporary result(this, op1, op2);
2514
2515         FPRReg reg1 = op1.fpr();
2516         FPRReg reg2 = op2.fpr();
2517         m_jit.addDouble(reg1, reg2, result.fpr());
2518
2519         doubleResult(result.fpr(), m_compileIndex);
2520         return;
2521     }
2522
2523     if (node.op() == ValueAdd) {
2524         compileValueAdd(node);
2525         return;
2526     }
2527     
2528     // We don't handle this yet. :-(
2529     terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2530 }
2531
2532 void SpeculativeJIT::compileArithSub(Node& node)
2533 {
2534     if (m_jit.graph().addShouldSpeculateInteger(node)) {
2535         if (isNumberConstant(node.child2().index())) {
2536             SpeculateIntegerOperand op1(this, node.child1());
2537             int32_t imm2 = valueOfNumberConstantAsInt32(node.child2().index());
2538             GPRTemporary result(this);
2539
2540             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2541                 m_jit.move(op1.gpr(), result.gpr());
2542                 m_jit.sub32(Imm32(imm2), result.gpr());
2543             } else {
2544 #if ENABLE(JIT_CONSTANT_BLINDING)
2545                 GPRTemporary scratch(this);
2546                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr(), scratch.gpr()));
2547 #else
2548                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
2549 #endif
2550             }
2551
2552             integerResult(result.gpr(), m_compileIndex);
2553             return;
2554         }
2555             
2556         if (isNumberConstant(node.child1().index())) {
2557             int32_t imm1 = valueOfNumberConstantAsInt32(node.child1().index());
2558             SpeculateIntegerOperand op2(this, node.child2());
2559             GPRTemporary result(this);
2560                 
2561             m_jit.move(Imm32(imm1), result.gpr());
2562             if (nodeCanTruncateInteger(node.arithNodeFlags()))
2563                 m_jit.sub32(op2.gpr(), result.gpr());
2564             else
2565                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op2.gpr(), result.gpr()));
2566                 
2567             integerResult(result.gpr(), m_compileIndex);
2568             return;
2569         }
2570             
2571         SpeculateIntegerOperand op1(this, node.child1());
2572         SpeculateIntegerOperand op2(this, node.child2());
2573         GPRTemporary result(this);
2574
2575         if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2576             m_jit.move(op1.gpr(), result.gpr());
2577             m_jit.sub32(op2.gpr(), result.gpr());
2578         } else
2579             speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
2580
2581         integerResult(result.gpr(), m_compileIndex);
2582         return;
2583     }
2584         
2585     SpeculateDoubleOperand op1(this, node.child1());
2586     SpeculateDoubleOperand op2(this, node.child2());
2587     FPRTemporary result(this, op1);
2588
2589     FPRReg reg1 = op1.fpr();
2590     FPRReg reg2 = op2.fpr();
2591     m_jit.subDouble(reg1, reg2, result.fpr());
2592
2593     doubleResult(result.fpr(), m_compileIndex);
2594 }
2595
2596 void SpeculativeJIT::compileArithNegate(Node& node)
2597 {
2598     if (m_jit.graph().negateShouldSpeculateInteger(node)) {
2599         SpeculateIntegerOperand op1(this, node.child1());
2600         GPRTemporary result(this);
2601
2602         m_jit.move(op1.gpr(), result.gpr());
2603
2604         if (nodeCanTruncateInteger(node.arithNodeFlags()))
2605             m_jit.neg32(result.gpr());
2606         else {
2607             speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchNeg32(MacroAssembler::Overflow, result.gpr()));
2608             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags()))
2609                 speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, result.gpr()));
2610         }
2611
2612         integerResult(result.gpr(), m_compileIndex);
2613         return;
2614     }
2615         
2616     SpeculateDoubleOperand op1(this, node.child1());
2617     FPRTemporary result(this);
2618
2619     m_jit.negateDouble(op1.fpr(), result.fpr());
2620
2621     doubleResult(result.fpr(), m_compileIndex);
2622 }
2623
2624 void SpeculativeJIT::compileArithMul(Node& node)
2625 {
2626     if (m_jit.graph().mulShouldSpeculateInteger(node)) {
2627         SpeculateIntegerOperand op1(this, node.child1());
2628         SpeculateIntegerOperand op2(this, node.child2());
2629         GPRTemporary result(this);
2630
2631         GPRReg reg1 = op1.gpr();
2632         GPRReg reg2 = op2.gpr();
2633
2634         // We can perform truncated multiplications if we get to this point, because if the
2635         // fixup phase could not prove that it would be safe, it would have turned us into
2636         // a double multiplication.
2637         if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2638             m_jit.move(reg1, result.gpr());
2639             m_jit.mul32(reg2, result.gpr());
2640         } else {
2641             speculationCheck(
2642                 Overflow, JSValueRegs(), NoNode,
2643                 m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
2644         }
2645             
2646         // Check for negative zero, if the users of this node care about such things.
2647         if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
2648             MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
2649             speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
2650             speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
2651             resultNonZero.link(&m_jit);
2652         }
2653
2654         integerResult(result.gpr(), m_compileIndex);
2655         return;
2656     }
2657
2658     SpeculateDoubleOperand op1(this, node.child1());
2659     SpeculateDoubleOperand op2(this, node.child2());
2660     FPRTemporary result(this, op1, op2);
2661
2662     FPRReg reg1 = op1.fpr();
2663     FPRReg reg2 = op2.fpr();
2664         
2665     m_jit.mulDouble(reg1, reg2, result.fpr());
2666         
2667     doubleResult(result.fpr(), m_compileIndex);
2668 }
2669
2670 #if CPU(X86) || CPU(X86_64)
2671 void SpeculativeJIT::compileIntegerArithDivForX86(Node& node)
2672 {
2673     SpeculateIntegerOperand op1(this, node.child1());
2674     SpeculateIntegerOperand op2(this, node.child2());
2675     GPRTemporary eax(this, X86Registers::eax);
2676     GPRTemporary edx(this, X86Registers::edx);
2677     GPRReg op1GPR = op1.gpr();
2678     GPRReg op2GPR = op2.gpr();
2679     
2680     GPRReg op2TempGPR;
2681     GPRReg temp;
2682     if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
2683         op2TempGPR = allocate();
2684         temp = op2TempGPR;
2685     } else {
2686         op2TempGPR = InvalidGPRReg;
2687         if (op1GPR == X86Registers::eax)
2688             temp = X86Registers::edx;
2689         else
2690             temp = X86Registers::eax;
2691     }
2692     
2693     ASSERT(temp != op1GPR);
2694     ASSERT(temp != op2GPR);
2695     
2696     m_jit.add32(JITCompiler::TrustedImm32(1), op2GPR, temp);
2697     
2698     JITCompiler::Jump safeDenominator = m_jit.branch32(JITCompiler::Above, temp, JITCompiler::TrustedImm32(1));
2699     
2700     JITCompiler::Jump done;
2701     if (nodeUsedAsNumber(node.arithNodeFlags())) {
2702         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
2703         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1)));
2704     } else {
2705         JITCompiler::Jump zero = m_jit.branchTest32(JITCompiler::Zero, op2GPR);
2706         JITCompiler::Jump notNeg2ToThe31 = m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1));
2707         zero.link(&m_jit);
2708         m_jit.move(TrustedImm32(0), eax.gpr());
2709         done = m_jit.jump();
2710         notNeg2ToThe31.link(&m_jit);
2711     }
2712     
2713     safeDenominator.link(&m_jit);
2714             
2715     // If the user cares about negative zero, then speculate that we're not about
2716     // to produce negative zero.
2717     if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
2718         MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
2719         speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
2720         numeratorNonZero.link(&m_jit);
2721     }
2722     
2723     if (op2TempGPR != InvalidGPRReg) {
2724         m_jit.move(op2GPR, op2TempGPR);
2725         op2GPR = op2TempGPR;
2726     }
2727             
2728     m_jit.move(op1GPR, eax.gpr());
2729     m_jit.assembler().cdq();
2730     m_jit.assembler().idivl_r(op2GPR);
2731             
2732     if (op2TempGPR != InvalidGPRReg)
2733         unlock(op2TempGPR);
2734
2735     // Check that there was no remainder. If there had been, then we'd be obligated to
2736     // produce a double result instead.
2737     if (nodeUsedAsNumber(node.arithNodeFlags()))
2738         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
2739     else
2740         done.link(&m_jit);
2741             
2742     integerResult(eax.gpr(), m_compileIndex);
2743 }
2744 #endif // CPU(X86) || CPU(X86_64)
2745
2746 void SpeculativeJIT::compileArithMod(Node& node)
2747 {
2748     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))
2749         && node.canSpeculateInteger()) {
2750         compileSoftModulo(node);
2751         return;
2752     }
2753         
2754     SpeculateDoubleOperand op1(this, node.child1());
2755     SpeculateDoubleOperand op2(this, node.child2());
2756         
2757     FPRReg op1FPR = op1.fpr();
2758     FPRReg op2FPR = op2.fpr();
2759         
2760     flushRegisters();
2761         
2762     FPRResult result(this);
2763
2764     callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
2765         
2766     doubleResult(result.fpr(), m_compileIndex);
2767 }
2768
2769 // Returns true if the compare is fused with a subsequent branch.
2770 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
2771 {
2772     if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
2773         return true;
2774
2775     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
2776         compileIntegerCompare(node, condition);
2777         return false;
2778     }
2779     
2780     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2781         compileDoubleCompare(node, doubleCondition);
2782         return false;
2783     }
2784     
2785     if (node.op() == CompareEq) {
2786         if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
2787             compileObjectEquality(node, &JSFinalObject::s_info, isFinalObjectPrediction);
2788             return false;
2789         }
2790         
2791         if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
2792             compileObjectEquality(node, &JSArray::s_info, isArrayPrediction);
2793             return false;
2794         }
2795         
2796         if (at(node.child1()).shouldSpeculateFinalObject()
2797             && at(node.child2()).shouldSpeculateFinalObjectOrOther()) {
2798             compileObjectToObjectOrOtherEquality(
2799                 node.child1(), node.child2(), &JSFinalObject::s_info,
2800                 isFinalObjectPrediction);
2801             return false;
2802         }
2803         
2804         if (at(node.child1()).shouldSpeculateFinalObjectOrOther()
2805             && at(node.child2()).shouldSpeculateFinalObject()) {
2806             compileObjectToObjectOrOtherEquality(
2807                 node.child2(), node.child1(), &JSFinalObject::s_info,
2808                 isFinalObjectPrediction);
2809             return false;
2810         }
2811         
2812         if (at(node.child1()).shouldSpeculateArray()
2813             && at(node.child2()).shouldSpeculateArrayOrOther()) {
2814             compileObjectToObjectOrOtherEquality(
2815                 node.child1(), node.child2(), &JSArray::s_info,
2816                 isArrayPrediction);
2817             return false;
2818         }
2819         
2820         if (at(node.child1()).shouldSpeculateArrayOrOther()
2821             && at(node.child2()).shouldSpeculateArray()) {
2822             compileObjectToObjectOrOtherEquality(
2823                 node.child2(), node.child1(), &JSArray::s_info,
2824                 isArrayPrediction);
2825             return false;
2826         }
2827     }
2828     
2829     nonSpeculativeNonPeepholeCompare(node, condition, operation);
2830     return false;
2831 }
2832
2833 bool SpeculativeJIT::compileStrictEqForConstant(Node& node, Edge value, JSValue constant)
2834 {
2835     JSValueOperand op1(this, value);
2836     
2837     unsigned branchIndexInBlock = detectPeepHoleBranch();
2838     if (branchIndexInBlock != UINT_MAX) {
2839         NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2840         Node& branchNode = at(branchNodeIndex);
2841         BlockIndex taken = branchNode.takenBlockIndex();
2842         BlockIndex notTaken = branchNode.notTakenBlockIndex();
2843         MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
2844         
2845         // The branch instruction will branch to the taken block.
2846         // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
2847         if (taken == nextBlock()) {
2848             condition = MacroAssembler::NotEqual;
2849             BlockIndex tmp = taken;
2850             taken = notTaken;
2851             notTaken = tmp;
2852         }
2853
2854 #if USE(JSVALUE64)
2855         branchPtr(condition, op1.gpr(), MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant))), taken);
2856 #else
2857         GPRReg payloadGPR = op1.payloadGPR();
2858         GPRReg tagGPR = op1.tagGPR();
2859         if (condition == MacroAssembler::Equal) {
2860             // Drop down if not equal, go elsewhere if equal.
2861             MacroAssembler::Jump notEqual = m_jit.branch32(MacroAssembler::NotEqual, tagGPR, MacroAssembler::Imm32(constant.tag()));
2862             branch32(MacroAssembler::Equal, payloadGPR, MacroAssembler::Imm32(constant.payload()), taken);
2863             notEqual.link(&m_jit);
2864         } else {
2865             // Drop down if equal, go elsehwere if not equal.
2866             branch32(MacroAssembler::NotEqual, tagGPR, MacroAssembler::Imm32(constant.tag()), taken);
2867             branch32(MacroAssembler::NotEqual, payloadGPR, MacroAssembler::Imm32(constant.payload()), taken);
2868         }
2869 #endif
2870         
2871         jump(notTaken);
2872         
2873         use(node.child1());
2874         use(node.child2());
2875         m_indexInBlock = branchIndexInBlock;
2876         m_compileIndex = branchNodeIndex;
2877         return true;
2878     }
2879     
2880     GPRTemporary result(this);
2881     
2882 #if USE(JSVALUE64)
2883     GPRReg op1GPR = op1.gpr();
2884     GPRReg resultGPR = result.gpr();
2885     m_jit.move(MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(ValueFalse)), resultGPR);
2886     MacroAssembler::Jump notEqual = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant))));
2887     m_jit.or32(MacroAssembler::TrustedImm32(1), resultGPR);
2888     notEqual.link(&m_jit);
2889     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
2890 #else
2891     GPRReg op1PayloadGPR = op1.payloadGPR();
2892     GPRReg op1TagGPR = op1.tagGPR();
2893     GPRReg resultGPR = result.gpr();
2894     m_jit.move(TrustedImm32(0), resultGPR);
2895     MacroAssembler::JumpList notEqual;
2896     notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, MacroAssembler::Imm32(constant.tag())));
2897     notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1PayloadGPR, MacroAssembler::Imm32(constant.payload())));
2898     m_jit.move(TrustedImm32(1), resultGPR);
2899     notEqual.link(&m_jit);
2900     booleanResult(resultGPR, m_compileIndex);
2901 #endif
2902     
2903     return false;
2904 }
2905
2906 bool SpeculativeJIT::compileStrictEq(Node& node)
2907 {
2908     // 1) If either operand is a constant and that constant is not a double, integer,
2909     //    or string, then do a JSValue comparison.
2910     
2911     if (isJSConstant(node.child1().index())) {
2912         JSValue value = valueOfJSConstant(node.child1().index());
2913         if (!value.isNumber() && !value.isString())
2914             return compileStrictEqForConstant(node, node.child2(), value);
2915     }
2916     
2917     if (isJSConstant(node.child2().index())) {
2918         JSValue value = valueOfJSConstant(node.child2().index());
2919         if (!value.isNumber() && !value.isString())
2920             return compileStrictEqForConstant(node, node.child1(), value);
2921     }
2922     
2923     // 2) If the operands are predicted integer, do an integer comparison.
2924     
2925     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
2926         unsigned branchIndexInBlock = detectPeepHoleBranch();
2927         if (branchIndexInBlock != UINT_MAX) {
2928             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2929             compilePeepHoleIntegerBranch(node, branchNodeIndex, MacroAssembler::Equal);
2930             use(node.child1());
2931             use(node.child2());
2932             m_indexInBlock = branchIndexInBlock;
2933             m_compileIndex = branchNodeIndex;
2934             return true;
2935         }
2936         compileIntegerCompare(node, MacroAssembler::Equal);
2937         return false;
2938     }
2939     
2940     // 3) If the operands are predicted double, do a double comparison.
2941     
2942     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2943         unsigned branchIndexInBlock = detectPeepHoleBranch();
2944         if (branchIndexInBlock != UINT_MAX) {
2945             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2946             compilePeepHoleDoubleBranch(node, branchNodeIndex, MacroAssembler::DoubleEqual);
2947             use(node.child1());
2948             use(node.child2());
2949             m_indexInBlock = branchIndexInBlock;
2950             m_compileIndex = branchNodeIndex;
2951             return true;
2952         }
2953         compileDoubleCompare(node, MacroAssembler::DoubleEqual);
2954         return false;
2955     }
2956     
2957     // 4) If the operands are predicted final object or array, then do a final object
2958     //    or array comparison.
2959     
2960     if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
2961         unsigned branchIndexInBlock = detectPeepHoleBranch();
2962         if (branchIndexInBlock != UINT_MAX) {
2963             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2964             compilePeepHoleObjectEquality(node, branchNodeIndex, &JSFinalObject::s_info, isFinalObjectPrediction);
2965             use(node.child1());
2966             use(node.child2());
2967             m_indexInBlock = branchIndexInBlock;
2968             m_compileIndex = branchNodeIndex;
2969             return true;
2970         }
2971         compileObjectEquality(node, &JSFinalObject::s_info, isFinalObjectPrediction);
2972         return false;
2973     }
2974     
2975     if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
2976         unsigned branchIndexInBlock = detectPeepHoleBranch();
2977         if (branchIndexInBlock != UINT_MAX) {
2978             NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
2979             compilePeepHoleObjectEquality(node, branchNodeIndex, &JSArray::s_info, isArrayPrediction);
2980             use(node.child1());
2981             use(node.child2());
2982             m_indexInBlock = branchIndexInBlock;
2983             m_compileIndex = branchNodeIndex;
2984             return true;
2985         }
2986         compileObjectEquality(node, &JSArray::s_info, isArrayPrediction);
2987         return false;
2988     }
2989     
2990     // 5) Fall back to non-speculative strict equality.
2991     
2992     return nonSpeculativeStrictEq(node);
2993 }
2994
2995 void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
2996 {
2997     if (!node.prediction() || !at(node.child1()).prediction() || !at(node.child2()).prediction()) {
2998         terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), NoNode);
2999         return;
3000     }
3001         
3002     SpeculateCellOperand base(this, node.child1());
3003     GPRReg baseReg = base.gpr();
3004     
3005     PredictedType basePrediction = at(node.child2()).prediction();
3006     if (!(basePrediction & PredictInt32) && basePrediction) {
3007         ASSERT_NOT_REACHED();
3008         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
3009         noResult(m_compileIndex);
3010         return;
3011     }
3012     
3013     GPRTemporary storage(this);
3014     GPRReg storageReg = storage.gpr();
3015     if (at(node.child1()).shouldSpeculateArguments()) {
3016         ASSERT_NOT_REACHED();
3017     } else if (at(node.child1()).prediction() == PredictString) {
3018         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
3019             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSString::s_info)));
3020
3021         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
3022         
3023         // Speculate that we're not accessing a rope
3024         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, storageReg));
3025
3026         m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
3027     } else if (at(node.child1()).shouldSpeculateInt8Array()) {
3028         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int8ArrayDescriptor();
3029         if (!isInt8ArrayPrediction(m_state.forNode(node.child1()).m_type))
3030             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3031         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3032     } else if (at(node.child1()).shouldSpeculateInt16Array()) {
3033         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int16ArrayDescriptor();
3034         if (!isInt16ArrayPrediction(m_state.forNode(node.child1()).m_type))
3035             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3036         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3037     } else if (at(node.child1()).shouldSpeculateInt32Array()) {
3038         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int32ArrayDescriptor();
3039         if (!isInt32ArrayPrediction(m_state.forNode(node.child1()).m_type))
3040             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3041         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3042     } else if (at(node.child1()).shouldSpeculateUint8Array()) {
3043         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ArrayDescriptor();
3044         if (!isUint8ArrayPrediction(m_state.forNode(node.child1()).m_type))
3045             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3046         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3047     } else if (at(node.child1()).shouldSpeculateUint8ClampedArray()) {
3048         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ClampedArrayDescriptor();
3049         if (!isUint8ClampedArrayPrediction(m_state.forNode(node.child1()).m_type))
3050             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3051         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3052     } else if (at(node.child1()).shouldSpeculateUint16Array()) {
3053         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint16ArrayDescriptor();
3054         if (!isUint16ArrayPrediction(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()).shouldSpeculateUint32Array()) {
3058         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint32ArrayDescriptor();
3059         if (!isUint32ArrayPrediction(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()).shouldSpeculateFloat32Array()) {
3063         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float32ArrayDescriptor();
3064         if (!isFloat32ArrayPrediction(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()).shouldSpeculateFloat64Array()) {
3068         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float64ArrayDescriptor();
3069         if (!isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type))
3070             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(descriptor.m_classInfo)));
3071         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
3072     } else {
3073         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
3074             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg, JSCell::classInfoOffset()), MacroAssembler::TrustedImmPtr(&JSArray::s_info)));
3075         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
3076     }
3077     storageResult(storageReg, m_compileIndex);
3078 }
3079
3080 void SpeculativeJIT::compileGetByValOnArguments(Node& node)
3081 {
3082     SpeculateCellOperand base(this, node.child1());
3083     SpeculateStrictInt32Operand property(this, node.child2());
3084     GPRTemporary result(this);
3085 #if USE(JSVALUE32_64)
3086     GPRTemporary resultTag(this);
3087 #endif
3088     GPRTemporary scratch(this);
3089     
3090     GPRReg baseReg = base.gpr();
3091     GPRReg propertyReg = property.gpr();
3092     GPRReg resultReg = result.gpr();
3093 #if USE(JSVALUE32_64)
3094     GPRReg resultTagReg = resultTag.gpr();
3095 #endif
3096     GPRReg scratchReg = scratch.gpr();
3097     
3098     if (!m_compileOkay)
3099         return;
3100     
3101     if (!isArgumentsPrediction(m_state.forNode(node.child1()).m_type)) {
3102         speculationCheck(
3103             BadType, JSValueSource::unboxedCell(baseReg), node.child1(),
3104             m_jit.branchPtr(
3105                 MacroAssembler::NotEqual,
3106                 MacroAssembler::Address(baseReg, JSCell::classInfoOffset()),
3107                 MacroAssembler::TrustedImmPtr(&Arguments::s_info)));
3108     }
3109     
3110     m_jit.loadPtr(
3111         MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
3112         scratchReg);
3113
3114     // Two really lame checks.
3115     speculationCheck(
3116         Uncountable, JSValueSource(), NoNode,
3117         m_jit.branchPtr(
3118             MacroAssembler::AboveOrEqual, propertyReg,
3119             MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, numArguments))));
3120     speculationCheck(
3121         Uncountable, JSValueSource(), NoNode,
3122         m_jit.branchTestPtr(
3123             MacroAssembler::NonZero,
3124             MacroAssembler::Address(
3125                 scratchReg, OBJECT_OFFSETOF(ArgumentsData, deletedArguments))));
3126     
3127     m_jit.move(propertyReg, resultReg);
3128     m_jit.neg32(resultReg);
3129     m_jit.signExtend32ToPtr(resultReg, resultReg);
3130     m_jit.loadPtr(
3131         MacroAssembler::Address(scratchReg, OBJECT_OFFSETOF(ArgumentsData, registers)),
3132         scratchReg);
3133     
3134 #if USE(JSVALUE32_64)
3135     m_jit.load32(
3136         MacroAssembler::BaseIndex(
3137             scratchReg, resultReg, MacroAssembler::TimesEight,
3138             CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register) +
3139             OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
3140         resultTagReg);
3141     m_jit.load32(
3142         MacroAssembler::BaseIndex(
3143             scratchReg, resultReg, MacroAssembler::TimesEight,
3144             CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register) +
3145             OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
3146         resultReg);
3147     jsValueResult(resultTagReg, resultReg, m_compileIndex);
3148 #else
3149     m_jit.loadPtr(
3150         MacroAssembler::BaseIndex(
3151             scratchReg, resultReg, MacroAssembler::TimesEight,
3152             CallFrame::thisArgumentOffset() * sizeof(Register) - sizeof(Register)),
3153         resultReg);
3154     jsValueResult(resultReg, m_compileIndex);
3155 #endif
3156 }
3157
3158 void SpeculativeJIT::compileGetArgumentsLength(Node& node)
3159 {
3160     SpeculateCellOperand base(this, node.child1());
3161     GPRTemporary result(this, base);
3162     
3163     GPRReg baseReg = base.gpr();
3164     GPRReg resultReg = result.gpr();
3165     
3166     if (!m_compileOkay)
3167         return;
3168     
3169     if (!isArgumentsPrediction(m_state.forNode(node.child1()).m_type)) {
3170         speculationCheck(
3171             BadType, JSValueSource::unboxedCell(baseReg), node.child1(),
3172             m_jit.branchPtr(
3173                 MacroAssembler::NotEqual,
3174                 MacroAssembler::Address(baseReg, JSCell::classInfoOffset()),
3175                 MacroAssembler::TrustedImmPtr(&Arguments::s_info)));
3176     }
3177     
3178     m_jit.loadPtr(
3179         MacroAssembler::Address(baseReg, Arguments::offsetOfData()),
3180         resultReg);
3181
3182     speculationCheck(
3183         Uncountable, JSValueSource(), NoNode,
3184         m_jit.branchTest8(
3185             MacroAssembler::NonZero,
3186             MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, overrodeLength))));
3187     
3188     m_jit.load32(
3189         MacroAssembler::Address(resultReg, OBJECT_OFFSETOF(ArgumentsData, numArguments)),
3190         resultReg);
3191     integerResult(resultReg, m_compileIndex);
3192 }
3193
3194 void SpeculativeJIT::compileNewFunctionNoCheck(Node& node)
3195 {
3196     GPRResult result(this);
3197     GPRReg resultGPR = result.gpr();
3198     flushRegisters();
3199     callOperation(
3200         operationNewFunction, resultGPR, m_jit.codeBlock()->functionDecl(node.functionDeclIndex()));
3201     cellResult(resultGPR, m_compileIndex);
3202 }
3203
3204 void SpeculativeJIT::compileNewFunctionExpression(Node& node)
3205 {
3206     GPRResult result(this);
3207     GPRReg resultGPR = result.gpr();
3208     flushRegisters();
3209     callOperation(
3210         operationNewFunctionExpression,
3211         resultGPR,
3212         m_jit.codeBlock()->functionExpr(node.functionExprIndex()));
3213     cellResult(resultGPR, m_compileIndex);
3214 }
3215
3216 bool SpeculativeJIT::compileRegExpExec(Node& node)
3217 {
3218     unsigned branchIndexInBlock = detectPeepHoleBranch();
3219     if (branchIndexInBlock == UINT_MAX)
3220         return false;
3221     NodeIndex branchNodeIndex = m_jit.graph().m_blocks[m_block]->at(branchIndexInBlock);
3222     ASSERT(node.adjustedRefCount() == 1);
3223
3224     Node& branchNode = at(branchNodeIndex);
3225     BlockIndex taken = branchNode.takenBlockIndex();
3226     BlockIndex notTaken = branchNode.notTakenBlockIndex();
3227     
3228     bool invert = false;
3229     if (taken == nextBlock()) {
3230         invert = true;
3231         BlockIndex tmp = taken;
3232         taken = notTaken;
3233         notTaken = tmp;
3234     }
3235
3236     SpeculateCellOperand base(this, node.child1());
3237     SpeculateCellOperand argument(this, node.child2());
3238     GPRReg baseGPR = base.gpr();
3239     GPRReg argumentGPR = argument.gpr();
3240     
3241     flushRegisters();
3242     GPRResult result(this);
3243     callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
3244
3245     branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, result.gpr(), taken);
3246     jump(notTaken);
3247
3248     use(node.child1());
3249     use(node.child2());
3250     m_indexInBlock = branchIndexInBlock;
3251     m_compileIndex = branchNodeIndex;
3252
3253     return true;
3254 }
3255
3256 } } // namespace JSC::DFG
3257
3258 #endif