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