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