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