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