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