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