DFG should know exactly why recompilation was triggered
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGSpeculativeJIT.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "JSByteArray.h"
32 #include "LinkBuffer.h"
33
34 namespace JSC { namespace DFG {
35
36 // On Windows we need to wrap fmod; on other platforms we can call it directly.
37 // On ARMv7 we assert that all function pointers have to low bit set (point to thumb code).
38 #if CALLING_CONVENTION_IS_STDCALL || CPU(ARM_THUMB2)
39 static double DFG_OPERATION fmodAsDFGOperation(double x, double y)
40 {
41     return fmod(x, y);
42 }
43 #else
44 #define fmodAsDFGOperation fmod
45 #endif
46
47 const double SpeculativeJIT::twoToThe32 = (double)0x100000000ull;
48
49 void SpeculativeJIT::clearGenerationInfo()
50 {
51     for (unsigned i = 0; i < m_generationInfo.size(); ++i)
52         m_generationInfo[i] = GenerationInfo();
53     m_gprs = RegisterBank<GPRInfo>();
54     m_fprs = RegisterBank<FPRInfo>();
55 }
56
57 GPRReg SpeculativeJIT::fillStorage(NodeIndex nodeIndex)
58 {
59     Node& node = m_jit.graph()[nodeIndex];
60     VirtualRegister virtualRegister = node.virtualRegister();
61     GenerationInfo& info = m_generationInfo[virtualRegister];
62     
63     switch (info.registerFormat()) {
64     case DataFormatNone: {
65         GPRReg gpr = allocate();
66         ASSERT(info.spillFormat() == DataFormatStorage);
67         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
68         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
69         info.fillStorage(gpr);
70         return gpr;
71     }
72         
73     case DataFormatStorage: {
74         GPRReg gpr = info.gpr();
75         m_gprs.lock(gpr);
76         return gpr;
77     }
78         
79     default:
80         ASSERT_NOT_REACHED();
81     }
82     
83     return InvalidGPRReg;
84 }
85
86 void SpeculativeJIT::useChildren(Node& node)
87 {
88     if (node.op & NodeHasVarArgs) {
89         for (unsigned childIdx = node.firstChild(); childIdx < node.firstChild() + node.numChildren(); childIdx++)
90             use(m_jit.graph().m_varArgChildren[childIdx]);
91     } else {
92         NodeIndex child1 = node.child1();
93         if (child1 == NoNode) {
94             ASSERT(node.child2() == NoNode && node.child3() == NoNode);
95             return;
96         }
97         use(child1);
98         
99         NodeIndex child2 = node.child2();
100         if (child2 == NoNode) {
101             ASSERT(node.child3() == NoNode);
102             return;
103         }
104         use(child2);
105         
106         NodeIndex child3 = node.child3();
107         if (child3 == NoNode)
108             return;
109         use(child3);
110     }
111 }
112
113 bool SpeculativeJIT::isStrictInt32(NodeIndex nodeIndex)
114 {
115     if (isInt32Constant(nodeIndex))
116         return true;
117     
118     Node& node = m_jit.graph()[nodeIndex];
119     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
120     
121     return info.registerFormat() == DataFormatInteger;
122 }
123
124 bool SpeculativeJIT::isKnownInteger(NodeIndex nodeIndex)
125 {
126     if (isInt32Constant(nodeIndex))
127         return true;
128
129     Node& node = m_jit.graph()[nodeIndex];
130     
131     if (node.hasInt32Result())
132         return true;
133     
134     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
135
136     return info.isJSInteger();
137 }
138
139 bool SpeculativeJIT::isKnownNumeric(NodeIndex nodeIndex)
140 {
141     if (isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex))
142         return true;
143
144     Node& node = m_jit.graph()[nodeIndex];
145     
146     if (node.hasNumberResult())
147         return true;
148     
149     GenerationInfo& info = m_generationInfo[node.virtualRegister()];
150
151     return info.isJSInteger() || info.isJSDouble();
152 }
153
154 bool SpeculativeJIT::isKnownCell(NodeIndex nodeIndex)
155 {
156     return m_generationInfo[m_jit.graph()[nodeIndex].virtualRegister()].isJSCell();
157 }
158
159 bool SpeculativeJIT::isKnownNotCell(NodeIndex nodeIndex)
160 {
161     Node& node = m_jit.graph()[nodeIndex];
162     VirtualRegister virtualRegister = node.virtualRegister();
163     GenerationInfo& info = m_generationInfo[virtualRegister];
164     if (node.hasConstant() && !valueOfJSConstant(nodeIndex).isCell())
165         return true;
166     return !(info.isJSCell() || info.isUnknownJS());
167 }
168
169 bool SpeculativeJIT::isKnownNotInteger(NodeIndex nodeIndex)
170 {
171     Node& node = m_jit.graph()[nodeIndex];
172     VirtualRegister virtualRegister = node.virtualRegister();
173     GenerationInfo& info = m_generationInfo[virtualRegister];
174     
175     return info.isJSDouble() || info.isJSCell() || info.isJSBoolean()
176         || (node.hasConstant() && !valueOfJSConstant(nodeIndex).isInt32());
177 }
178
179 bool SpeculativeJIT::isKnownNotNumber(NodeIndex nodeIndex)
180 {
181     Node& node = m_jit.graph()[nodeIndex];
182     VirtualRegister virtualRegister = node.virtualRegister();
183     GenerationInfo& info = m_generationInfo[virtualRegister];
184     
185     return (!info.isJSDouble() && !info.isJSInteger() && !info.isUnknownJS())
186         || (node.hasConstant() && !isNumberConstant(nodeIndex));
187 }
188
189 bool SpeculativeJIT::isKnownBoolean(NodeIndex nodeIndex)
190 {
191     Node& node = m_jit.graph()[nodeIndex];
192     if (node.hasBooleanResult())
193         return true;
194     
195     if (isBooleanConstant(nodeIndex))
196         return true;
197     
198     VirtualRegister virtualRegister = node.virtualRegister();
199     GenerationInfo& info = m_generationInfo[virtualRegister];
200     
201     return info.isJSBoolean();
202 }
203
204 void SpeculativeJIT::writeBarrier(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2, WriteBarrierUseKind useKind)
205 {
206     UNUSED_PARAM(jit);
207     UNUSED_PARAM(owner);
208     UNUSED_PARAM(scratch1);
209     UNUSED_PARAM(scratch2);
210     UNUSED_PARAM(useKind);
211     ASSERT(owner != scratch1);
212     ASSERT(owner != scratch2);
213     ASSERT(scratch1 != scratch2);
214
215 #if ENABLE(WRITE_BARRIER_PROFILING)
216     JITCompiler::emitCount(jit, WriteBarrierCounters::jitCounterFor(useKind));
217 #endif
218     markCellCard(jit, owner, scratch1, scratch2);
219 }
220
221 void SpeculativeJIT::markCellCard(MacroAssembler& jit, GPRReg owner, GPRReg scratch1, GPRReg scratch2)
222 {
223     UNUSED_PARAM(jit);
224     UNUSED_PARAM(owner);
225     UNUSED_PARAM(scratch1);
226     UNUSED_PARAM(scratch2);
227     
228 #if ENABLE(GGC)
229     jit.move(owner, scratch1);
230     jit.andPtr(TrustedImm32(static_cast<int32_t>(MarkedBlock::blockMask)), scratch1);
231     jit.move(owner, scratch2);
232     // consume additional 8 bits as we're using an approximate filter
233     jit.rshift32(TrustedImm32(MarkedBlock::atomShift + 8), scratch2);
234     jit.andPtr(TrustedImm32(MarkedBlock::atomMask >> 8), scratch2);
235     MacroAssembler::Jump filter = jit.branchTest8(MacroAssembler::Zero, MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfMarks()));
236     jit.move(owner, scratch2);
237     jit.rshift32(TrustedImm32(MarkedBlock::cardShift), scratch2);
238     jit.andPtr(TrustedImm32(MarkedBlock::cardMask), scratch2);
239     jit.store8(TrustedImm32(1), MacroAssembler::BaseIndex(scratch1, scratch2, MacroAssembler::TimesOne, MarkedBlock::offsetOfCards()));
240     filter.link(&jit);
241 #endif
242 }
243
244 void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
245 {
246     UNUSED_PARAM(ownerGPR);
247     UNUSED_PARAM(valueGPR);
248     UNUSED_PARAM(scratch1);
249     UNUSED_PARAM(scratch2);
250     UNUSED_PARAM(useKind);
251
252     if (isKnownNotCell(valueIndex))
253         return;
254
255 #if ENABLE(WRITE_BARRIER_PROFILING)
256     JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
257 #endif
258
259 #if ENABLE(GGC)
260     GPRTemporary temp1;
261     GPRTemporary temp2;
262     if (scratch1 == InvalidGPRReg) {
263         GPRTemporary scratchGPR(this);
264         temp1.adopt(scratchGPR);
265         scratch1 = temp1.gpr();
266     }
267     if (scratch2 == InvalidGPRReg) {
268         GPRTemporary scratchGPR(this);
269         temp2.adopt(scratchGPR);
270         scratch2 = temp2.gpr();
271     }
272     
273     JITCompiler::Jump rhsNotCell;
274     bool hadCellCheck = false;
275     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
276         hadCellCheck = true;
277         rhsNotCell = m_jit.branchIfNotCell(valueGPR);
278     }
279
280     markCellCard(m_jit, ownerGPR, scratch1, scratch2);
281
282     if (hadCellCheck)
283         rhsNotCell.link(&m_jit);
284 #endif
285 }
286
287 void SpeculativeJIT::writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUseKind useKind, GPRReg scratch1, GPRReg scratch2)
288 {
289     UNUSED_PARAM(ownerGPR);
290     UNUSED_PARAM(value);
291     UNUSED_PARAM(scratch1);
292     UNUSED_PARAM(scratch2);
293     UNUSED_PARAM(useKind);
294     
295     if (Heap::isMarked(value))
296         return;
297
298 #if ENABLE(WRITE_BARRIER_PROFILING)
299     JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
300 #endif
301
302 #if ENABLE(GGC)
303     GPRTemporary temp1;
304     GPRTemporary temp2;
305     if (scratch1 == InvalidGPRReg) {
306         GPRTemporary scratchGPR(this);
307         temp1.adopt(scratchGPR);
308         scratch1 = temp1.gpr();
309     }
310     if (scratch2 == InvalidGPRReg) {
311         GPRTemporary scratchGPR(this);
312         temp2.adopt(scratchGPR);
313         scratch2 = temp2.gpr();
314     }
315
316     markCellCard(m_jit, ownerGPR, scratch1, scratch2);
317 #endif
318 }
319
320 void SpeculativeJIT::writeBarrier(JSCell* owner, GPRReg valueGPR, NodeIndex valueIndex, WriteBarrierUseKind useKind, GPRReg scratch)
321 {
322     UNUSED_PARAM(owner);
323     UNUSED_PARAM(valueGPR);
324     UNUSED_PARAM(scratch);
325     UNUSED_PARAM(useKind);
326
327     if (isKnownNotCell(valueIndex))
328         return;
329
330 #if ENABLE(WRITE_BARRIER_PROFILING)
331     JITCompiler::emitCount(m_jit, WriteBarrierCounters::jitCounterFor(useKind));
332 #endif
333
334 #if ENABLE(GGC)
335     JITCompiler::Jump rhsNotCell;
336     bool hadCellCheck = false;
337     if (!isKnownCell(valueIndex) && !isCellPrediction(m_jit.getPrediction(valueIndex))) {
338         hadCellCheck = true;
339         rhsNotCell = m_jit.branchIfNotCell(valueGPR);
340     }
341     
342     GPRTemporary temp;
343     if (scratch == InvalidGPRReg) {
344         GPRTemporary scratchGPR(this);
345         temp.adopt(scratchGPR);
346         scratch = temp.gpr();
347     }
348
349     uint8_t* cardAddress = Heap::addressOfCardFor(owner);
350     m_jit.move(JITCompiler::TrustedImmPtr(cardAddress), scratch);
351     m_jit.store8(JITCompiler::TrustedImm32(1), JITCompiler::Address(scratch));
352
353     if (hadCellCheck)
354         rhsNotCell.link(&m_jit);
355 #endif
356 }
357
358 bool SpeculativeJIT::nonSpeculativeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
359 {
360     NodeIndex branchNodeIndex = detectPeepHoleBranch();
361     if (branchNodeIndex != NoNode) {
362         ASSERT(node.adjustedRefCount() == 1);
363         
364         nonSpeculativePeepholeBranch(node, branchNodeIndex, cond, helperFunction);
365     
366         m_compileIndex = branchNodeIndex;
367         
368         return true;
369     }
370     
371     nonSpeculativeNonPeepholeCompare(node, cond, helperFunction);
372     
373     return false;
374 }
375
376 bool SpeculativeJIT::nonSpeculativeStrictEq(Node& node, bool invert)
377 {
378     if (!invert && (isKnownNumeric(node.child1()) || isKnownNumeric(node.child2())))
379         return nonSpeculativeCompare(node, MacroAssembler::Equal, operationCompareStrictEq);
380     
381     NodeIndex branchNodeIndex = detectPeepHoleBranch();
382     if (branchNodeIndex != NoNode) {
383         ASSERT(node.adjustedRefCount() == 1);
384         
385         nonSpeculativePeepholeStrictEq(node, branchNodeIndex, invert);
386     
387         m_compileIndex = branchNodeIndex;
388         
389         return true;
390     }
391     
392     nonSpeculativeNonPeepholeStrictEq(node, invert);
393     
394     return false;
395 }
396
397 #ifndef NDEBUG
398 static const char* dataFormatString(DataFormat format)
399 {
400     // These values correspond to the DataFormat enum.
401     const char* strings[] = {
402         "[  ]",
403         "[ i]",
404         "[ d]",
405         "[ c]",
406         "Err!",
407         "Err!",
408         "Err!",
409         "Err!",
410         "[J ]",
411         "[Ji]",
412         "[Jd]",
413         "[Jc]",
414         "Err!",
415         "Err!",
416         "Err!",
417         "Err!",
418     };
419     return strings[format];
420 }
421
422 void SpeculativeJIT::dump(const char* label)
423 {
424     if (label)
425         fprintf(stderr, "<%s>\n", label);
426
427     fprintf(stderr, "  gprs:\n");
428     m_gprs.dump();
429     fprintf(stderr, "  fprs:\n");
430     m_fprs.dump();
431     fprintf(stderr, "  VirtualRegisters:\n");
432     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
433         GenerationInfo& info = m_generationInfo[i];
434         if (info.alive())
435             fprintf(stderr, "    % 3d:%s%s", i, dataFormatString(info.registerFormat()), dataFormatString(info.spillFormat()));
436         else
437             fprintf(stderr, "    % 3d:[__][__]", i);
438         if (info.registerFormat() == DataFormatDouble)
439             fprintf(stderr, ":fpr%d\n", info.fpr());
440         else if (info.registerFormat() != DataFormatNone
441 #if USE(JSVALUE32_64)
442             && !(info.registerFormat() & DataFormatJS)
443 #endif
444             ) {
445             ASSERT(info.gpr() != InvalidGPRReg);
446             fprintf(stderr, ":%s\n", GPRInfo::debugName(info.gpr()));
447         } else
448             fprintf(stderr, "\n");
449     }
450     if (label)
451         fprintf(stderr, "</%s>\n", label);
452 }
453 #endif
454
455
456 #if DFG_ENABLE(CONSISTENCY_CHECK)
457 void SpeculativeJIT::checkConsistency()
458 {
459     bool failed = false;
460
461     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
462         if (iter.isLocked()) {
463             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: gpr %s is locked.\n", iter.debugName());
464             failed = true;
465         }
466     }
467     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
468         if (iter.isLocked()) {
469             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: fpr %s is locked.\n", iter.debugName());
470             failed = true;
471         }
472     }
473
474     for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
475         VirtualRegister virtualRegister = (VirtualRegister)i;
476         GenerationInfo& info = m_generationInfo[virtualRegister];
477         if (!info.alive())
478             continue;
479         switch (info.registerFormat()) {
480         case DataFormatNone:
481             break;
482         case DataFormatJS:
483         case DataFormatJSInteger:
484         case DataFormatJSDouble:
485         case DataFormatJSCell:
486         case DataFormatJSBoolean:
487 #if USE(JSVALUE32_64)
488             break;
489 #endif
490         case DataFormatInteger:
491         case DataFormatCell:
492         case DataFormatBoolean:
493         case DataFormatStorage: {
494             GPRReg gpr = info.gpr();
495             ASSERT(gpr != InvalidGPRReg);
496             if (m_gprs.name(gpr) != virtualRegister) {
497                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (gpr %s).\n", virtualRegister, GPRInfo::debugName(gpr));
498                 failed = true;
499             }
500             break;
501         }
502         case DataFormatDouble: {
503             FPRReg fpr = info.fpr();
504             ASSERT(fpr != InvalidFPRReg);
505             if (m_fprs.name(fpr) != virtualRegister) {
506                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (fpr %s).\n", virtualRegister, FPRInfo::debugName(fpr));
507                 failed = true;
508             }
509             break;
510         }
511         }
512     }
513
514     for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
515         VirtualRegister virtualRegister = iter.name();
516         if (virtualRegister == InvalidVirtualRegister)
517             continue;
518
519         GenerationInfo& info = m_generationInfo[virtualRegister];
520 #if USE(JSVALUE64)
521         if (iter.regID() != info.gpr()) {
522             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
523             failed = true;
524         }
525 #else
526         if (!(info.registerFormat() & DataFormatJS)) {
527             if (iter.regID() != info.gpr()) {
528                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
529                 failed = true;
530             }
531         } else {
532             if (iter.regID() != info.tagGPR() && iter.regID() != info.payloadGPR()) {
533                 fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
534                 failed = true;
535             }
536         }
537 #endif
538     }
539
540     for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
541         VirtualRegister virtualRegister = iter.name();
542         if (virtualRegister == InvalidVirtualRegister)
543             continue;
544
545         GenerationInfo& info = m_generationInfo[virtualRegister];
546         if (iter.regID() != info.fpr()) {
547             fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for fpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
548             failed = true;
549         }
550     }
551
552     if (failed) {
553         dump();
554         CRASH();
555     }
556 }
557 #endif
558
559 GPRTemporary::GPRTemporary()
560     : m_jit(0)
561     , m_gpr(InvalidGPRReg)
562 {
563 }
564
565 GPRTemporary::GPRTemporary(SpeculativeJIT* jit)
566     : m_jit(jit)
567     , m_gpr(InvalidGPRReg)
568 {
569 #if CPU(X86)
570     // we currenty lazily allocate the reg, as the number of regs on X86 is limited.
571 #else
572     m_gpr = m_jit->allocate();
573 #endif
574 }
575
576 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, GPRReg specific)
577     : m_jit(jit)
578     , m_gpr(InvalidGPRReg)
579 {
580     m_gpr = m_jit->allocate(specific);
581 }
582
583 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateIntegerOperand& op1)
584     : m_jit(jit)
585     , m_gpr(InvalidGPRReg)
586 {
587     if (m_jit->canReuse(op1.index()))
588         m_gpr = m_jit->reuse(op1.gpr());
589     else
590         m_gpr = m_jit->allocate();
591 }
592
593 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateIntegerOperand& op1, SpeculateIntegerOperand& op2)
594     : m_jit(jit)
595     , m_gpr(InvalidGPRReg)
596 {
597     if (m_jit->canReuse(op1.index()))
598         m_gpr = m_jit->reuse(op1.gpr());
599     else if (m_jit->canReuse(op2.index()))
600         m_gpr = m_jit->reuse(op2.gpr());
601     else
602         m_gpr = m_jit->allocate();
603 }
604
605 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateStrictInt32Operand& op1)
606     : m_jit(jit)
607     , m_gpr(InvalidGPRReg)
608 {
609     if (m_jit->canReuse(op1.index()))
610         m_gpr = m_jit->reuse(op1.gpr());
611     else
612         m_gpr = m_jit->allocate();
613 }
614
615 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, IntegerOperand& op1)
616     : m_jit(jit)
617     , m_gpr(InvalidGPRReg)
618 {
619     if (m_jit->canReuse(op1.index()))
620         m_gpr = m_jit->reuse(op1.gpr());
621     else
622         m_gpr = m_jit->allocate();
623 }
624
625 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, IntegerOperand& op1, IntegerOperand& op2)
626     : m_jit(jit)
627     , m_gpr(InvalidGPRReg)
628 {
629     if (m_jit->canReuse(op1.index()))
630         m_gpr = m_jit->reuse(op1.gpr());
631     else if (m_jit->canReuse(op2.index()))
632         m_gpr = m_jit->reuse(op2.gpr());
633     else
634         m_gpr = m_jit->allocate();
635 }
636
637 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateCellOperand& op1)
638     : m_jit(jit)
639     , m_gpr(InvalidGPRReg)
640 {
641     if (m_jit->canReuse(op1.index()))
642         m_gpr = m_jit->reuse(op1.gpr());
643     else
644         m_gpr = m_jit->allocate();
645 }
646
647 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, SpeculateBooleanOperand& op1)
648     : m_jit(jit)
649     , m_gpr(InvalidGPRReg)
650 {
651     if (m_jit->canReuse(op1.index()))
652         m_gpr = m_jit->reuse(op1.gpr());
653     else
654         m_gpr = m_jit->allocate();
655 }
656
657 #if USE(JSVALUE64)
658 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
659     : m_jit(jit)
660     , m_gpr(InvalidGPRReg)
661 {
662     if (m_jit->canReuse(op1.index()))
663         m_gpr = m_jit->reuse(op1.gpr());
664     else
665         m_gpr = m_jit->allocate();
666 }
667 #else
668 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1, bool tag)
669     : m_jit(jit)
670     , m_gpr(InvalidGPRReg)
671 {
672     if (!op1.isDouble() && m_jit->canReuse(op1.index()))
673         m_gpr = m_jit->reuse(tag ? op1.tagGPR() : op1.payloadGPR());
674     else
675         m_gpr = m_jit->allocate();
676 }
677 #endif
678
679 GPRTemporary::GPRTemporary(SpeculativeJIT* jit, StorageOperand& op1)
680     : m_jit(jit)
681     , m_gpr(InvalidGPRReg)
682 {
683     if (m_jit->canReuse(op1.index()))
684         m_gpr = m_jit->reuse(op1.gpr());
685     else
686         m_gpr = m_jit->allocate();
687 }
688
689 void GPRTemporary::adopt(GPRTemporary& other)
690 {
691     ASSERT(!m_jit);
692     ASSERT(m_gpr == InvalidGPRReg);
693     ASSERT(other.m_jit);
694     ASSERT(other.m_gpr != InvalidGPRReg);
695     m_jit = other.m_jit;
696     m_gpr = other.m_gpr;
697     other.m_jit = 0;
698     other.m_gpr = InvalidGPRReg;
699 }
700
701 FPRTemporary::FPRTemporary(SpeculativeJIT* jit)
702     : m_jit(jit)
703     , m_fpr(InvalidFPRReg)
704 {
705     m_fpr = m_jit->fprAllocate();
706 }
707
708 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, DoubleOperand& op1)
709     : m_jit(jit)
710     , m_fpr(InvalidFPRReg)
711 {
712     if (m_jit->canReuse(op1.index()))
713         m_fpr = m_jit->reuse(op1.fpr());
714     else
715         m_fpr = m_jit->fprAllocate();
716 }
717
718 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, DoubleOperand& op1, DoubleOperand& op2)
719     : m_jit(jit)
720     , m_fpr(InvalidFPRReg)
721 {
722     if (m_jit->canReuse(op1.index()))
723         m_fpr = m_jit->reuse(op1.fpr());
724     else if (m_jit->canReuse(op2.index()))
725         m_fpr = m_jit->reuse(op2.fpr());
726     else
727         m_fpr = m_jit->fprAllocate();
728 }
729
730 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, SpeculateDoubleOperand& op1)
731     : m_jit(jit)
732     , m_fpr(InvalidFPRReg)
733 {
734     if (m_jit->canReuse(op1.index()))
735         m_fpr = m_jit->reuse(op1.fpr());
736     else
737         m_fpr = m_jit->fprAllocate();
738 }
739
740 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, SpeculateDoubleOperand& op1, SpeculateDoubleOperand& op2)
741     : m_jit(jit)
742     , m_fpr(InvalidFPRReg)
743 {
744     if (m_jit->canReuse(op1.index()))
745         m_fpr = m_jit->reuse(op1.fpr());
746     else if (m_jit->canReuse(op2.index()))
747         m_fpr = m_jit->reuse(op2.fpr());
748     else
749         m_fpr = m_jit->fprAllocate();
750 }
751
752 #if USE(JSVALUE32_64)
753 FPRTemporary::FPRTemporary(SpeculativeJIT* jit, JSValueOperand& op1)
754     : m_jit(jit)
755     , m_fpr(InvalidFPRReg)
756 {
757     if (op1.isDouble() && m_jit->canReuse(op1.index()))
758         m_fpr = m_jit->reuse(op1.fpr());
759     else
760         m_fpr = m_jit->fprAllocate();
761 }
762 #endif
763
764 #ifndef NDEBUG
765 void ValueSource::dump(FILE* out) const
766 {
767     switch (kind()) {
768     case SourceNotSet:
769         fprintf(out, "NotSet");
770         break;
771     case ValueInRegisterFile:
772         fprintf(out, "InRegFile");
773         break;
774     case Int32InRegisterFile:
775         fprintf(out, "Int32");
776         break;
777     case CellInRegisterFile:
778         fprintf(out, "Cell");
779         break;
780     case BooleanInRegisterFile:
781         fprintf(out, "Bool");
782         break;
783     case HaveNode:
784         fprintf(out, "Node(%d)", m_nodeIndex);
785         break;
786     }
787 }
788 #endif
789
790 void SpeculativeJIT::compilePeepHoleDoubleBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition condition)
791 {
792     Node& branchNode = at(branchNodeIndex);
793     BlockIndex taken = branchNode.takenBlockIndex();
794     BlockIndex notTaken = branchNode.notTakenBlockIndex();
795     
796     SpeculateDoubleOperand op1(this, node.child1());
797     SpeculateDoubleOperand op2(this, node.child2());
798     
799     addBranch(m_jit.branchDouble(condition, op1.fpr(), op2.fpr()), taken);
800     
801     if (notTaken != (m_block + 1))
802         addBranch(m_jit.jump(), notTaken);
803 }
804
805 void SpeculativeJIT::compilePeepHoleObjectEquality(Node& node, NodeIndex branchNodeIndex, void* vptr, PredictionChecker predictionCheck)
806 {
807     Node& branchNode = at(branchNodeIndex);
808     BlockIndex taken = branchNode.takenBlockIndex();
809     BlockIndex notTaken = branchNode.notTakenBlockIndex();
810
811     MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
812     
813     if (taken == (m_block + 1)) {
814         condition = MacroAssembler::NotEqual;
815         BlockIndex tmp = taken;
816         taken = notTaken;
817         notTaken = tmp;
818     }
819
820     SpeculateCellOperand op1(this, node.child1());
821     SpeculateCellOperand op2(this, node.child2());
822     
823     GPRReg op1GPR = op1.gpr();
824     GPRReg op2GPR = op2.gpr();
825     
826     if (!predictionCheck(m_state.forNode(node.child1()).m_type))
827         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
828     if (!predictionCheck(m_state.forNode(node.child2()).m_type))
829         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
830     
831     addBranch(m_jit.branchPtr(condition, op1GPR, op2GPR), taken);
832     if (notTaken != (m_block + 1))
833         addBranch(m_jit.jump(), notTaken);
834 }
835
836 void SpeculativeJIT::compilePeepHoleIntegerBranch(Node& node, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition condition)
837 {
838     Node& branchNode = at(branchNodeIndex);
839     BlockIndex taken = branchNode.takenBlockIndex();
840     BlockIndex notTaken = branchNode.notTakenBlockIndex();
841
842     // The branch instruction will branch to the taken block.
843     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
844     if (taken == (m_block + 1)) {
845         condition = JITCompiler::invert(condition);
846         BlockIndex tmp = taken;
847         taken = notTaken;
848         notTaken = tmp;
849     }
850
851     if (isInt32Constant(node.child1())) {
852         int32_t imm = valueOfInt32Constant(node.child1());
853         SpeculateIntegerOperand op2(this, node.child2());
854         addBranch(m_jit.branch32(condition, JITCompiler::Imm32(imm), op2.gpr()), taken);
855     } else if (isInt32Constant(node.child2())) {
856         SpeculateIntegerOperand op1(this, node.child1());
857         int32_t imm = valueOfInt32Constant(node.child2());
858         addBranch(m_jit.branch32(condition, op1.gpr(), JITCompiler::Imm32(imm)), taken);
859     } else {
860         SpeculateIntegerOperand op1(this, node.child1());
861         SpeculateIntegerOperand op2(this, node.child2());
862         addBranch(m_jit.branch32(condition, op1.gpr(), op2.gpr()), taken);
863     }
864
865     // Check for fall through, otherwise we need to jump.
866     if (notTaken != (m_block + 1))
867         addBranch(m_jit.jump(), notTaken);
868 }
869
870 // Returns true if the compare is fused with a subsequent branch.
871 bool SpeculativeJIT::compilePeepHoleBranch(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
872 {
873     // Fused compare & branch.
874     NodeIndex branchNodeIndex = detectPeepHoleBranch();
875     if (branchNodeIndex != NoNode) {
876         // detectPeepHoleBranch currently only permits the branch to be the very next node,
877         // so can be no intervening nodes to also reference the compare. 
878         ASSERT(node.adjustedRefCount() == 1);
879
880         if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
881             compilePeepHoleIntegerBranch(node, branchNodeIndex, condition);
882             use(node.child1());
883             use(node.child2());
884         } else if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
885             compilePeepHoleDoubleBranch(node, branchNodeIndex, doubleCondition);
886             use(node.child1());
887             use(node.child2());
888         } else if (node.op == CompareEq && Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
889             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
890             use(node.child1());
891             use(node.child2());
892         } else if (node.op == CompareEq && Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
893             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
894             use(node.child1());
895             use(node.child2());
896         } else
897             nonSpeculativePeepholeBranch(node, branchNodeIndex, condition, operation);
898
899         m_compileIndex = branchNodeIndex;
900         return true;
901     }
902     return false;
903 }
904
905 void SpeculativeJIT::compileMovHint(Node& node)
906 {
907     ASSERT(node.op == SetLocal);
908     
909     setNodeIndexForOperand(node.child1(), node.local());
910     m_lastSetOperand = node.local();
911 }
912
913 void SpeculativeJIT::compile(BasicBlock& block)
914 {
915     ASSERT(m_compileOkay);
916     ASSERT(m_compileIndex == block.begin);
917     
918     if (!block.isReachable) {
919         m_compileIndex = block.end;
920         return;
921     }
922
923     m_blockHeads[m_block] = m_jit.label();
924 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_BLOCK)
925     m_jit.breakpoint();
926 #endif
927
928     ASSERT(m_arguments.size() == block.variablesAtHead.numberOfArguments());
929     for (size_t i = 0; i < m_arguments.size(); ++i) {
930         NodeIndex nodeIndex = block.variablesAtHead.argument(i);
931         if (nodeIndex == NoNode)
932             m_arguments[i] = ValueSource(ValueInRegisterFile);
933         else
934             m_arguments[i] = ValueSource::forPrediction(at(nodeIndex).variableAccessData()->prediction());
935     }
936     
937     m_state.reset();
938     m_state.beginBasicBlock(&block);
939     
940     ASSERT(m_variables.size() == block.variablesAtHead.numberOfLocals());
941     for (size_t i = 0; i < m_variables.size(); ++i) {
942         NodeIndex nodeIndex = block.variablesAtHead.local(i);
943         if (nodeIndex == NoNode)
944             m_variables[i] = ValueSource(ValueInRegisterFile);
945         else
946             m_variables[i] = ValueSource::forPrediction(at(nodeIndex).variableAccessData()->prediction());
947     }
948     
949     m_lastSetOperand = std::numeric_limits<int>::max();
950     m_codeOriginForOSR = CodeOrigin();
951
952     for (; m_compileIndex < block.end; ++m_compileIndex) {
953         Node& node = at(m_compileIndex);
954         m_codeOriginForOSR = node.codeOrigin;
955         if (!node.shouldGenerate()) {
956 #if DFG_ENABLE(DEBUG_VERBOSE)
957             fprintf(stderr, "SpeculativeJIT skipping Node @%d (bc#%u) at JIT offset 0x%x     ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
958 #endif
959             switch (node.op) {
960             case SetLocal:
961                 compileMovHint(node);
962                 break;
963
964             case InlineStart: {
965                 InlineCallFrame* inlineCallFrame = node.codeOrigin.inlineCallFrame;
966                 int argumentCountIncludingThis = inlineCallFrame->arguments.size();
967                 for (int i = 0; i < argumentCountIncludingThis; ++i) {
968                     ValueRecovery recovery = computeValueRecoveryFor(m_variables[inlineCallFrame->stackOffset + CallFrame::argumentOffsetIncludingThis(i)]);
969                     // The recovery cannot point to registers, since the call frame reification isn't
970                     // as smart as OSR, so it can't handle that. The exception is the this argument,
971                     // which we don't really need to be able to recover.
972                     ASSERT(!i || !recovery.isInRegisters());
973                     inlineCallFrame->arguments[i] = recovery;
974                 }
975                 break;
976             }
977                 
978             default:
979                 break;
980             }
981         } else {
982             
983 #if DFG_ENABLE(DEBUG_VERBOSE)
984             fprintf(stderr, "SpeculativeJIT generating Node @%d (bc#%u) at JIT offset 0x%x   ", (int)m_compileIndex, node.codeOrigin.bytecodeIndex, m_jit.debugOffset());
985 #endif
986 #if DFG_ENABLE(JIT_BREAK_ON_EVERY_NODE)
987             m_jit.breakpoint();
988 #endif
989 #if DFG_ENABLE(XOR_DEBUG_AID)
990             m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
991             m_jit.xorPtr(JITCompiler::TrustedImm32(m_compileIndex), GPRInfo::regT0);
992 #endif
993             checkConsistency();
994             compile(node);
995             if (!m_compileOkay) {
996                 m_compileOkay = true;
997                 m_compileIndex = block.end;
998                 clearGenerationInfo();
999                 return;
1000             }
1001             
1002 #if DFG_ENABLE(DEBUG_VERBOSE)
1003             if (node.hasResult()) {
1004                 GenerationInfo& info = m_generationInfo[node.virtualRegister()];
1005                 fprintf(stderr, "-> %s, vr#%d", dataFormatToString(info.registerFormat()), (int)node.virtualRegister());
1006                 if (info.registerFormat() != DataFormatNone) {
1007                     if (info.registerFormat() == DataFormatDouble)
1008                         fprintf(stderr, ", %s", FPRInfo::debugName(info.fpr()));
1009 #if USE(JSVALUE32_64)
1010                     else if (info.registerFormat() & DataFormatJS)
1011                         fprintf(stderr, ", %s %s", GPRInfo::debugName(info.tagGPR()), GPRInfo::debugName(info.payloadGPR()));
1012 #endif
1013                     else
1014                         fprintf(stderr, ", %s", GPRInfo::debugName(info.gpr()));
1015                 }
1016                 fprintf(stderr, "    ");
1017             } else
1018                 fprintf(stderr, "    ");
1019 #endif
1020         }
1021         
1022 #if DFG_ENABLE(VERBOSE_VALUE_RECOVERIES)
1023         for (size_t i = 0; i < m_arguments.size(); ++i)
1024             computeValueRecoveryFor(argumentToOperand(i)).dump(stderr);
1025         
1026         fprintf(stderr, " : ");
1027         
1028         for (int operand = 0; operand < (int)m_variables.size(); ++operand)
1029             computeValueRecoveryFor(operand).dump(stderr);
1030 #endif
1031
1032 #if DFG_ENABLE(DEBUG_VERBOSE)
1033         fprintf(stderr, "\n");
1034 #endif
1035         
1036         // Make sure that the abstract state is rematerialized for the next node.
1037         m_state.execute(m_compileIndex);
1038         
1039         if (node.shouldGenerate())
1040             checkConsistency();
1041     }
1042 }
1043
1044 // If we are making type predictions about our arguments then
1045 // we need to check that they are correct on function entry.
1046 void SpeculativeJIT::checkArgumentTypes()
1047 {
1048     ASSERT(!m_compileIndex);
1049     m_codeOriginForOSR = CodeOrigin(0);
1050
1051     for (size_t i = 0; i < m_arguments.size(); ++i)
1052         m_arguments[i] = ValueSource(ValueInRegisterFile);
1053     for (size_t i = 0; i < m_variables.size(); ++i)
1054         m_variables[i] = ValueSource(ValueInRegisterFile);
1055     
1056     for (int i = 0; i < m_jit.codeBlock()->m_numParameters; ++i) {
1057         VariableAccessData* variableAccessData = at(m_jit.graph().m_arguments[i]).variableAccessData();
1058         VirtualRegister virtualRegister = variableAccessData->local();
1059         PredictedType predictedType = variableAccessData->prediction();
1060 #if USE(JSVALUE64)
1061         if (isInt32Prediction(predictedType))
1062             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::Below, JITCompiler::addressFor(virtualRegister), GPRInfo::tagTypeNumberRegister));
1063         else if (isArrayPrediction(predictedType)) {
1064             GPRTemporary temp(this);
1065             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1066             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1067             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1068         } else if (isByteArrayPrediction(predictedType)) {
1069             GPRTemporary temp(this);
1070             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1071             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1072             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
1073         } else if (isBooleanPrediction(predictedType)) {
1074             GPRTemporary temp(this);
1075             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1076             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), temp.gpr());
1077             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1078         } else if (isInt8ArrayPrediction(predictedType)) {
1079             GPRTemporary temp(this);
1080             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1081             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1082             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_vptr)));
1083         } else if (isInt16ArrayPrediction(predictedType)) {
1084             GPRTemporary temp(this);
1085             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1086             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1087             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_vptr)));
1088         } else if (isInt32ArrayPrediction(predictedType)) {
1089             GPRTemporary temp(this);
1090             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1091             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1092             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_vptr)));
1093         } else if (isUint8ArrayPrediction(predictedType)) {
1094             GPRTemporary temp(this);
1095             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1096             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1097             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_vptr)));
1098         } else if (isUint16ArrayPrediction(predictedType)) {
1099             GPRTemporary temp(this);
1100             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1101             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1102             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_vptr)));
1103         } else if (isUint32ArrayPrediction(predictedType)) {
1104             GPRTemporary temp(this);
1105             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1106             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1107             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_vptr)));
1108         } else if (isFloat32ArrayPrediction(predictedType)) {
1109             GPRTemporary temp(this);
1110             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1111             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1112             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_vptr)));
1113         } else if (isFloat64ArrayPrediction(predictedType)) {
1114             GPRTemporary temp(this);
1115             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), temp.gpr());
1116             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::NonZero, temp.gpr(), GPRInfo::tagMaskRegister));
1117             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_vptr)));
1118         }
1119 #else
1120         if (isInt32Prediction(predictedType))
1121             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
1122         else if (isArrayPrediction(predictedType)) {
1123             GPRTemporary temp(this);
1124             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1125             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1126             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1127             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1128         } else if (isByteArrayPrediction(predictedType)) {
1129             GPRTemporary temp(this);
1130             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1131             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1132             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1133             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
1134         } else if (isBooleanPrediction(predictedType))
1135             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
1136         else if (isInt8ArrayPrediction(predictedType)) {
1137             GPRTemporary temp(this);
1138             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1139             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1140             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1141             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int8ArrayDescriptor().m_vptr)));
1142         } else if (isInt16ArrayPrediction(predictedType)) {
1143             GPRTemporary temp(this);
1144             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1145             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1146             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1147             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int16ArrayDescriptor().m_vptr)));
1148         } else if (isInt32ArrayPrediction(predictedType)) {
1149             GPRTemporary temp(this);
1150             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1151             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1152             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1153             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->int32ArrayDescriptor().m_vptr)));
1154         } else if (isUint8ArrayPrediction(predictedType)) {
1155             GPRTemporary temp(this);
1156             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1157             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1158             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1159             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint8ArrayDescriptor().m_vptr)));
1160         } else if (isUint16ArrayPrediction(predictedType)) {
1161             GPRTemporary temp(this);
1162             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1163             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1164             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1165             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint16ArrayDescriptor().m_vptr)));
1166         }  else if (isUint32ArrayPrediction(predictedType)) {
1167             GPRTemporary temp(this);
1168             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1169             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1170             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1171             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->uint32ArrayDescriptor().m_vptr)));
1172         }  else if (isFloat32ArrayPrediction(predictedType)) {
1173             GPRTemporary temp(this);
1174             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1175             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1176             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1177             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float32ArrayDescriptor().m_vptr)));
1178         }   else if (isFloat64ArrayPrediction(predictedType)) {
1179             GPRTemporary temp(this);
1180             m_jit.load32(JITCompiler::tagFor(virtualRegister), temp.gpr());
1181             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::NotEqual, temp.gpr(), TrustedImm32(JSValue::CellTag)));
1182             m_jit.load32(JITCompiler::payloadFor(virtualRegister), temp.gpr());
1183             speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(temp.gpr()), MacroAssembler::TrustedImmPtr(m_jit.globalData()->float64ArrayDescriptor().m_vptr)));
1184         } 
1185 #endif
1186     }
1187 }
1188
1189 bool SpeculativeJIT::compile()
1190 {
1191     checkArgumentTypes();
1192
1193     ASSERT(!m_compileIndex);
1194     for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block)
1195         compile(*m_jit.graph().m_blocks[m_block]);
1196     linkBranches();
1197     return true;
1198 }
1199
1200 void SpeculativeJIT::linkOSREntries(LinkBuffer& linkBuffer)
1201 {
1202     for (BlockIndex blockIndex = 0; blockIndex < m_jit.graph().m_blocks.size(); ++blockIndex) {
1203         BasicBlock& block = *m_jit.graph().m_blocks[blockIndex];
1204         if (block.isOSRTarget)
1205             m_jit.noticeOSREntry(block, m_blockHeads[blockIndex], linkBuffer);
1206     }
1207 }
1208
1209 ValueRecovery SpeculativeJIT::computeValueRecoveryFor(const ValueSource& valueSource)
1210 {
1211     switch (valueSource.kind()) {
1212     case ValueInRegisterFile:
1213         return ValueRecovery::alreadyInRegisterFile();
1214         
1215     case Int32InRegisterFile:
1216         return ValueRecovery::alreadyInRegisterFileAsUnboxedInt32();
1217
1218     case CellInRegisterFile:
1219         return ValueRecovery::alreadyInRegisterFileAsUnboxedCell();
1220
1221     case BooleanInRegisterFile:
1222         return ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean();
1223
1224     case HaveNode: {
1225         if (m_jit.isConstant(valueSource.nodeIndex()))
1226             return ValueRecovery::constant(m_jit.valueOfJSConstant(valueSource.nodeIndex()));
1227     
1228         Node* nodePtr = &at(valueSource.nodeIndex());
1229         if (!nodePtr->shouldGenerate()) {
1230             // It's legitimately dead. As in, nobody will ever use this node, or operand,
1231             // ever. Set it to Undefined to make the GC happy after the OSR.
1232             return ValueRecovery::constant(jsUndefined());
1233         }
1234     
1235         GenerationInfo* infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1236         if (!infoPtr->alive() || infoPtr->nodeIndex() != valueSource.nodeIndex()) {
1237             // Try to see if there is an alternate node that would contain the value we want.
1238             // There are four possibilities:
1239             //
1240             // ValueToNumber: If the only live version of the value is a ValueToNumber node
1241             //    then it means that all remaining uses of the value would have performed a
1242             //    ValueToNumber conversion anyway. Thus, we can substitute ValueToNumber.
1243             //
1244             // ValueToInt32: Likewise, if the only remaining live version of the value is
1245             //    ValueToInt32, then we can use it. But if there is both a ValueToInt32
1246             //    and a ValueToNumber, then we better go with ValueToNumber because it
1247             //    means that some remaining uses would have converted to number while
1248             //    others would have converted to Int32.
1249             //
1250             // UInt32ToNumber: If the only live version of the value is a UInt32ToNumber
1251             //    then the only remaining uses are ones that want a properly formed number
1252             //    rather than a UInt32 intermediate.
1253             //
1254             // The reverse of the above: This node could be a UInt32ToNumber, but its
1255             //    alternative is still alive. This means that the only remaining uses of
1256             //    the number would be fine with a UInt32 intermediate.
1257         
1258             bool found = false;
1259         
1260             if (nodePtr->op == UInt32ToNumber) {
1261                 NodeIndex nodeIndex = nodePtr->child1();
1262                 nodePtr = &at(nodeIndex);
1263                 infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1264                 if (infoPtr->alive() && infoPtr->nodeIndex() == nodeIndex)
1265                     found = true;
1266             }
1267         
1268             if (!found) {
1269                 NodeIndex valueToNumberIndex = NoNode;
1270                 NodeIndex valueToInt32Index = NoNode;
1271                 NodeIndex uint32ToNumberIndex = NoNode;
1272             
1273                 for (unsigned virtualRegister = 0; virtualRegister < m_generationInfo.size(); ++virtualRegister) {
1274                     GenerationInfo& info = m_generationInfo[virtualRegister];
1275                     if (!info.alive())
1276                         continue;
1277                     if (info.nodeIndex() == NoNode)
1278                         continue;
1279                     Node& node = at(info.nodeIndex());
1280                     if (node.child1Unchecked() != valueSource.nodeIndex())
1281                         continue;
1282                     switch (node.op) {
1283                     case ValueToNumber:
1284                     case ValueToDouble:
1285                         valueToNumberIndex = info.nodeIndex();
1286                         break;
1287                     case ValueToInt32:
1288                         valueToInt32Index = info.nodeIndex();
1289                         break;
1290                     case UInt32ToNumber:
1291                         uint32ToNumberIndex = info.nodeIndex();
1292                         break;
1293                     default:
1294                         break;
1295                     }
1296                 }
1297             
1298                 NodeIndex nodeIndexToUse;
1299                 if (valueToNumberIndex != NoNode)
1300                     nodeIndexToUse = valueToNumberIndex;
1301                 else if (valueToInt32Index != NoNode)
1302                     nodeIndexToUse = valueToInt32Index;
1303                 else if (uint32ToNumberIndex != NoNode)
1304                     nodeIndexToUse = uint32ToNumberIndex;
1305                 else
1306                     nodeIndexToUse = NoNode;
1307             
1308                 if (nodeIndexToUse != NoNode) {
1309                     nodePtr = &at(nodeIndexToUse);
1310                     infoPtr = &m_generationInfo[nodePtr->virtualRegister()];
1311                     ASSERT(infoPtr->alive() && infoPtr->nodeIndex() == nodeIndexToUse);
1312                     found = true;
1313                 }
1314             }
1315         
1316             if (!found)
1317                 return ValueRecovery::constant(jsUndefined());
1318         }
1319     
1320         ASSERT(infoPtr->alive());
1321
1322         if (infoPtr->registerFormat() != DataFormatNone) {
1323             if (infoPtr->registerFormat() == DataFormatDouble)
1324                 return ValueRecovery::inFPR(infoPtr->fpr());
1325 #if USE(JSVALUE32_64)
1326             if (infoPtr->registerFormat() & DataFormatJS)
1327                 return ValueRecovery::inPair(infoPtr->tagGPR(), infoPtr->payloadGPR());
1328 #endif
1329             return ValueRecovery::inGPR(infoPtr->gpr(), infoPtr->registerFormat());
1330         }
1331         if (infoPtr->spillFormat() != DataFormatNone)
1332             return ValueRecovery::displacedInRegisterFile(static_cast<VirtualRegister>(nodePtr->virtualRegister()), infoPtr->spillFormat());
1333     
1334         ASSERT_NOT_REACHED();
1335         return ValueRecovery();
1336     }
1337         
1338     default:
1339         ASSERT_NOT_REACHED();
1340         return ValueRecovery();
1341     }
1342 }
1343
1344 void SpeculativeJIT::compileGetCharCodeAt(Node& node)
1345 {
1346     ASSERT(node.child3() == NoNode);
1347     SpeculateCellOperand string(this, node.child1());
1348     SpeculateStrictInt32Operand index(this, node.child2());
1349     StorageOperand storage(this, node.child3());
1350
1351     GPRReg stringReg = string.gpr();
1352     GPRReg indexReg = index.gpr();
1353     GPRReg storageReg = storage.gpr();
1354     
1355     if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) {
1356         ASSERT(!(at(node.child1()).prediction() & PredictString));
1357         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1358         noResult(m_compileIndex);
1359         return;
1360     }
1361
1362     // unsigned comparison so we can filter out negative indices and indices that are too large
1363     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, indexReg, MacroAssembler::Address(stringReg, JSString::offsetOfLength())));
1364
1365     GPRTemporary scratch(this);
1366     GPRReg scratchReg = scratch.gpr();
1367
1368     m_jit.loadPtr(MacroAssembler::Address(stringReg, JSString::offsetOfValue()), scratchReg);
1369
1370     // Load the character into scratchReg
1371     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1372
1373     m_jit.load8(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesOne, 0), scratchReg);
1374     JITCompiler::Jump cont8Bit = m_jit.jump();
1375
1376     is16Bit.link(&m_jit);
1377
1378     m_jit.load16(MacroAssembler::BaseIndex(storageReg, indexReg, MacroAssembler::TimesTwo, 0), scratchReg);
1379
1380     cont8Bit.link(&m_jit);
1381
1382     integerResult(scratchReg, m_compileIndex);
1383 }
1384
1385 void SpeculativeJIT::compileGetByValOnString(Node& node)
1386 {
1387     SpeculateCellOperand base(this, node.child1());
1388     SpeculateStrictInt32Operand property(this, node.child2());
1389     StorageOperand storage(this, node.child3());
1390     GPRReg baseReg = base.gpr();
1391     GPRReg propertyReg = property.gpr();
1392     GPRReg storageReg = storage.gpr();
1393
1394     if (!isStringPrediction(m_state.forNode(node.child1()).m_type)) {
1395         ASSERT(!(at(node.child1()).prediction() & PredictString));
1396         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1397         noResult(m_compileIndex);
1398         return;
1399     }
1400
1401     // unsigned comparison so we can filter out negative indices and indices that are too large
1402     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSString::offsetOfLength())));
1403
1404     GPRTemporary scratch(this);
1405     GPRReg scratchReg = scratch.gpr();
1406
1407     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), scratchReg);
1408
1409     // Load the character into scratchReg
1410     JITCompiler::Jump is16Bit = m_jit.branchTest32(MacroAssembler::Zero, MacroAssembler::Address(scratchReg, StringImpl::flagsOffset()), TrustedImm32(StringImpl::flagIs8Bit()));
1411
1412     m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne, 0), scratchReg);
1413     JITCompiler::Jump cont8Bit = m_jit.jump();
1414
1415     is16Bit.link(&m_jit);
1416
1417     m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
1418
1419     // We only support ascii characters
1420     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
1421
1422     // 8 bit string values don't need the isASCII check.
1423     cont8Bit.link(&m_jit);
1424
1425     GPRTemporary smallStrings(this);
1426     GPRReg smallStringsReg = smallStrings.gpr();
1427     m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalData()->smallStrings.singleCharacterStrings()), smallStringsReg);
1428     m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg);
1429     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, scratchReg));
1430     cellResult(scratchReg, m_compileIndex);
1431 }
1432
1433 void SpeculativeJIT::compileValueToInt32(Node& node)
1434 {
1435     if (at(node.child1()).shouldNotSpeculateInteger()) {
1436         if (at(node.child1()).shouldSpeculateDouble()) {
1437             SpeculateDoubleOperand op1(this, node.child1());
1438             GPRTemporary result(this);
1439             FPRReg fpr = op1.fpr();
1440             GPRReg gpr = result.gpr();
1441             JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
1442             
1443             silentSpillAllRegisters(gpr);
1444             callOperation(toInt32, gpr, fpr);
1445             silentFillAllRegisters(gpr);
1446             
1447             truncatedToInteger.link(&m_jit);
1448             integerResult(gpr, m_compileIndex);
1449             return;
1450         }
1451         // Do it the safe way.
1452         nonSpeculativeValueToInt32(node);
1453         return;
1454     }
1455     
1456     SpeculateIntegerOperand op1(this, node.child1());
1457     GPRTemporary result(this, op1);
1458     m_jit.move(op1.gpr(), result.gpr());
1459     integerResult(result.gpr(), m_compileIndex, op1.format());
1460 }
1461
1462 static void compileClampDoubleToByte(JITCompiler& jit, GPRReg result, FPRReg source, FPRReg scratch)
1463 {
1464     // Unordered compare so we pick up NaN
1465     static const double zero = 0;
1466     static const double byteMax = 255;
1467     static const double half = 0.5;
1468     jit.loadDouble(&zero, scratch);
1469     MacroAssembler::Jump tooSmall = jit.branchDouble(MacroAssembler::DoubleLessThanOrEqualOrUnordered, source, scratch);
1470     jit.loadDouble(&byteMax, scratch);
1471     MacroAssembler::Jump tooBig = jit.branchDouble(MacroAssembler::DoubleGreaterThan, source, scratch);
1472     
1473     jit.loadDouble(&half, scratch);
1474     // FIXME: This should probably just use a floating point round!
1475     // https://bugs.webkit.org/show_bug.cgi?id=72054
1476     jit.addDouble(source, scratch);
1477     jit.truncateDoubleToInt32(scratch, result);   
1478     MacroAssembler::Jump truncatedInt = jit.jump();
1479     
1480     tooSmall.link(&jit);
1481     jit.xorPtr(result, result);
1482     MacroAssembler::Jump zeroed = jit.jump();
1483     
1484     tooBig.link(&jit);
1485     jit.move(JITCompiler::TrustedImm32(255), result);
1486     
1487     truncatedInt.link(&jit);
1488     zeroed.link(&jit);
1489
1490 }
1491
1492 void SpeculativeJIT::compilePutByValForByteArray(GPRReg base, GPRReg property, Node& node)
1493 {
1494     NodeIndex baseIndex = node.child1();
1495     NodeIndex valueIndex = node.child3();
1496     
1497     if (!isByteArrayPrediction(m_state.forNode(baseIndex).m_type))
1498         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
1499     GPRTemporary value;
1500     GPRReg valueGPR;
1501
1502     if (at(valueIndex).isConstant()) {
1503         JSValue jsValue = valueOfJSConstant(valueIndex);
1504         if (!jsValue.isNumber()) {
1505             terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1506             noResult(m_compileIndex);
1507             return;
1508         }
1509         double d = jsValue.asNumber();
1510         d += 0.5;
1511         if (!(d > 0))
1512             d = 0;
1513         else if (d > 255)
1514             d = 255;
1515         GPRTemporary scratch(this);
1516         GPRReg scratchReg = scratch.gpr();
1517         m_jit.move(Imm32((int)d), scratchReg);
1518         value.adopt(scratch);
1519         valueGPR = scratchReg;
1520     } else if (!at(valueIndex).shouldNotSpeculateInteger()) {
1521         SpeculateIntegerOperand valueOp(this, valueIndex);
1522         GPRTemporary scratch(this);
1523         GPRReg scratchReg = scratch.gpr();
1524         m_jit.move(valueOp.gpr(), scratchReg);
1525         MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::BelowOrEqual, scratchReg, TrustedImm32(0xff));
1526         MacroAssembler::Jump tooBig = m_jit.branch32(MacroAssembler::GreaterThan, scratchReg, TrustedImm32(0xff));
1527         m_jit.xorPtr(scratchReg, scratchReg);
1528         MacroAssembler::Jump clamped = m_jit.jump();
1529         tooBig.link(&m_jit);
1530         m_jit.move(TrustedImm32(255), scratchReg);
1531         clamped.link(&m_jit);
1532         inBounds.link(&m_jit);
1533         value.adopt(scratch);
1534         valueGPR = scratchReg;
1535     } else {
1536         SpeculateDoubleOperand valueOp(this, valueIndex);
1537         GPRTemporary result(this);
1538         FPRTemporary floatScratch(this);
1539         FPRReg fpr = valueOp.fpr();
1540         GPRReg gpr = result.gpr();
1541         compileClampDoubleToByte(m_jit, gpr, fpr, floatScratch.fpr());
1542         value.adopt(result);
1543         valueGPR = gpr;
1544     }
1545     ASSERT_UNUSED(valueGPR, valueGPR != property);
1546     ASSERT(valueGPR != base);
1547     GPRTemporary storage(this);
1548     GPRReg storageReg = storage.gpr();
1549     ASSERT(valueGPR != storageReg);
1550     m_jit.loadPtr(MacroAssembler::Address(base, JSByteArray::offsetOfStorage()), storageReg);
1551     MacroAssembler::Jump outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(storageReg, ByteArray::offsetOfSize()));
1552     m_jit.store8(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesOne, ByteArray::offsetOfData()));
1553     outOfBounds.link(&m_jit);
1554     noResult(m_compileIndex);
1555 }
1556
1557 void SpeculativeJIT::compileGetByValOnByteArray(Node& node)
1558 {
1559     SpeculateCellOperand base(this, node.child1());
1560     SpeculateStrictInt32Operand property(this, node.child2());
1561
1562     GPRReg baseReg = base.gpr();
1563     GPRReg propertyReg = property.gpr();
1564
1565     if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type)) {
1566         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1567         noResult(m_compileIndex);
1568         return;
1569     }
1570
1571     // Load the character into scratchReg
1572     GPRTemporary storage(this);
1573     GPRReg storageReg = storage.gpr();
1574     m_jit.loadPtr(MacroAssembler::Address(baseReg, JSByteArray::offsetOfStorage()), storageReg);
1575     
1576     // unsigned comparison so we can filter out negative indices and indices that are too large
1577     speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ByteArray::offsetOfSize())));
1578
1579     m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne, ByteArray::offsetOfData()), storageReg);
1580     integerResult(storageReg, m_compileIndex);
1581 }
1582
1583 void SpeculativeJIT::compileGetTypedArrayLength(const TypedArrayDescriptor& descriptor, Node& node, bool needsSpeculationCheck)
1584 {
1585     SpeculateCellOperand base(this, node.child1());
1586     GPRTemporary result(this);
1587     
1588     GPRReg baseGPR = base.gpr();
1589     GPRReg resultGPR = result.gpr();
1590     
1591     if (needsSpeculationCheck)
1592         speculationCheck(BadType, JSValueSource::unboxedCell(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
1593     
1594     m_jit.load32(MacroAssembler::Address(baseGPR, descriptor.m_lengthOffset), resultGPR);
1595     
1596     integerResult(resultGPR, m_compileIndex);
1597 }
1598
1599 void SpeculativeJIT::compileGetByValOnIntTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness)
1600 {
1601     SpeculateCellOperand base(this, node.child1());
1602     SpeculateStrictInt32Operand property(this, node.child2());
1603     StorageOperand storage(this, node.child3());
1604
1605     GPRReg baseReg = base.gpr();
1606     GPRReg propertyReg = property.gpr();
1607     GPRReg storageReg = storage.gpr();
1608
1609     GPRTemporary result(this);
1610     GPRReg resultReg = result.gpr();
1611
1612     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
1613         ASSERT_NOT_REACHED();
1614         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1615         noResult(m_compileIndex);
1616         return;
1617     }
1618
1619     MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
1620     m_jit.xorPtr(resultReg, resultReg);
1621     MacroAssembler::Jump outOfBounds = m_jit.jump();
1622     inBounds.link(&m_jit);
1623     switch (elementSize) {
1624     case 1:
1625         m_jit.load8(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesOne), resultReg);
1626         break;
1627     case 2:
1628         m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo), resultReg);
1629         break;
1630     case 4:
1631         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
1632         break;
1633     default:
1634         ASSERT_NOT_REACHED();
1635     }
1636     outOfBounds.link(&m_jit);
1637     if (elementSize < 4 || signedness == SignedTypedArray)
1638         integerResult(resultReg, m_compileIndex);
1639     else {
1640         FPRTemporary fresult(this);
1641         m_jit.convertInt32ToDouble(resultReg, fresult.fpr());
1642         JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, resultReg, TrustedImm32(0));
1643         m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), fresult.fpr());
1644         positive.link(&m_jit);
1645         doubleResult(fresult.fpr(), m_compileIndex);
1646     }
1647 }
1648
1649 void SpeculativeJIT::compilePutByValForIntTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements, TypedArraySignedness signedness)
1650 {
1651     NodeIndex baseIndex = node.child1();
1652     NodeIndex valueIndex = node.child3();
1653     
1654     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
1655         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
1656     GPRTemporary value;
1657     GPRReg valueGPR;
1658     
1659     if (at(valueIndex).isConstant()) {
1660         JSValue jsValue = valueOfJSConstant(valueIndex);
1661         if (!jsValue.isNumber()) {
1662             terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1663             noResult(m_compileIndex);
1664             return;
1665         }
1666         double d = jsValue.asNumber();
1667         GPRTemporary scratch(this);
1668         GPRReg scratchReg = scratch.gpr();
1669         m_jit.move(Imm32((int)d), scratchReg);
1670         value.adopt(scratch);
1671         valueGPR = scratchReg;
1672     } else if (!at(valueIndex).shouldNotSpeculateInteger()) {
1673         SpeculateIntegerOperand valueOp(this, valueIndex);
1674         GPRTemporary scratch(this);
1675         GPRReg scratchReg = scratch.gpr();
1676         m_jit.move(valueOp.gpr(), scratchReg);
1677         value.adopt(scratch);
1678         valueGPR = scratchReg;
1679     } else {
1680         SpeculateDoubleOperand valueOp(this, valueIndex);
1681         GPRTemporary result(this);
1682         FPRReg fpr = valueOp.fpr();
1683         GPRReg gpr = result.gpr();
1684         MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, fpr, fpr);
1685         m_jit.xorPtr(gpr, gpr);
1686         MacroAssembler::Jump fixed = m_jit.jump();
1687         notNaN.link(&m_jit);
1688     
1689         if (signedness == SignedTypedArray)
1690             m_jit.truncateDoubleToInt32(fpr, gpr);
1691         else
1692             m_jit.truncateDoubleToUint32(fpr, gpr);
1693         fixed.link(&m_jit);
1694         value.adopt(result);
1695         valueGPR = gpr;
1696     }
1697     ASSERT_UNUSED(valueGPR, valueGPR != property);
1698     ASSERT(valueGPR != base);
1699     GPRTemporary storage(this);
1700     GPRReg storageReg = storage.gpr();
1701     ASSERT(valueGPR != storageReg);
1702     m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
1703     MacroAssembler::Jump outOfBounds;
1704     if (speculationRequirements != NoTypedArraySpecCheck)
1705         outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
1706
1707     switch (elementSize) {
1708     case 1:
1709         m_jit.store8(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesOne));
1710         break;
1711     case 2:
1712         m_jit.store16(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesTwo));
1713         break;
1714     case 4:
1715         m_jit.store32(value.gpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
1716         break;
1717     default:
1718         ASSERT_NOT_REACHED();
1719     }
1720     if (speculationRequirements != NoTypedArraySpecCheck)
1721         outOfBounds.link(&m_jit);
1722     noResult(m_compileIndex);
1723 }
1724
1725 void SpeculativeJIT::compileGetByValOnFloatTypedArray(const TypedArrayDescriptor& descriptor, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
1726 {
1727     SpeculateCellOperand base(this, node.child1());
1728     SpeculateStrictInt32Operand property(this, node.child2());
1729     StorageOperand storage(this, node.child3());
1730
1731     GPRReg baseReg = base.gpr();
1732     GPRReg propertyReg = property.gpr();
1733     GPRReg storageReg = storage.gpr();
1734     
1735     if (speculationRequirements != NoTypedArrayTypeSpecCheck) {
1736         ASSERT_NOT_REACHED();
1737         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
1738         noResult(m_compileIndex);
1739         return;
1740     }
1741
1742     FPRTemporary result(this);
1743     FPRReg resultReg = result.fpr();
1744     ASSERT(speculationRequirements != NoTypedArraySpecCheck);
1745     MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, descriptor.m_lengthOffset));
1746     static const double zero = 0;
1747     m_jit.loadDouble(&zero, resultReg);
1748     MacroAssembler::Jump outOfBounds = m_jit.jump();
1749     inBounds.link(&m_jit);
1750     switch (elementSize) {
1751     case 4:
1752         m_jit.loadFloat(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesFour), resultReg);
1753         m_jit.convertFloatToDouble(resultReg, resultReg);
1754         break;
1755     case 8: {
1756         m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
1757         MacroAssembler::Jump notNaN = m_jit.branchDouble(MacroAssembler::DoubleEqual, resultReg, resultReg);
1758         static const double NaN = std::numeric_limits<double>::quiet_NaN();
1759         m_jit.loadDouble(&NaN, resultReg);
1760         notNaN.link(&m_jit);
1761         break;
1762     }
1763     default:
1764         ASSERT_NOT_REACHED();
1765     }
1766     outOfBounds.link(&m_jit);
1767     doubleResult(resultReg, m_compileIndex);
1768 }
1769
1770 void SpeculativeJIT::compilePutByValForFloatTypedArray(const TypedArrayDescriptor& descriptor, GPRReg base, GPRReg property, Node& node, size_t elementSize, TypedArraySpeculationRequirements speculationRequirements)
1771 {
1772     NodeIndex baseIndex = node.child1();
1773     NodeIndex valueIndex = node.child3();
1774     
1775     SpeculateDoubleOperand valueOp(this, valueIndex);
1776     
1777     if (speculationRequirements != NoTypedArrayTypeSpecCheck)
1778         speculationCheck(BadType, JSValueSource::unboxedCell(base), baseIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(base), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
1779     
1780     GPRTemporary result(this);
1781     
1782     GPRTemporary storage(this);
1783     GPRReg storageReg = storage.gpr();
1784     
1785     m_jit.loadPtr(MacroAssembler::Address(base, descriptor.m_storageOffset), storageReg);
1786     MacroAssembler::Jump outOfBounds;
1787     if (speculationRequirements != NoTypedArraySpecCheck)
1788         outOfBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, property, MacroAssembler::Address(base, descriptor.m_lengthOffset));
1789     
1790     switch (elementSize) {
1791     case 4: {
1792         FPRTemporary scratch(this);
1793         m_jit.moveDouble(valueOp.fpr(), scratch.fpr());
1794         m_jit.convertDoubleToFloat(valueOp.fpr(), scratch.fpr());
1795         m_jit.storeFloat(scratch.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesFour));
1796         break;
1797     }
1798     case 8:
1799         m_jit.storeDouble(valueOp.fpr(), MacroAssembler::BaseIndex(storageReg, property, MacroAssembler::TimesEight));
1800         break;
1801     default:
1802         ASSERT_NOT_REACHED();
1803     }
1804     if (speculationRequirements != NoTypedArraySpecCheck)
1805         outOfBounds.link(&m_jit);
1806     noResult(m_compileIndex);
1807 }
1808
1809 void SpeculativeJIT::compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchReg)
1810 {
1811     // Check that prototype is an object.
1812     m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
1813     speculationCheck(BadType, JSValueRegs(), NoNode, m_jit.branchIfNotObject(scratchReg));
1814     
1815     // Initialize scratchReg with the value being checked.
1816     m_jit.move(valueReg, scratchReg);
1817     
1818     // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
1819     MacroAssembler::Label loop(&m_jit);
1820     m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
1821 #if USE(JSVALUE64)
1822     m_jit.loadPtr(MacroAssembler::Address(scratchReg, Structure::prototypeOffset()), scratchReg);
1823 #else
1824     m_jit.load32(MacroAssembler::Address(scratchReg, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), scratchReg);
1825 #endif
1826     MacroAssembler::Jump isInstance = m_jit.branchPtr(MacroAssembler::Equal, scratchReg, prototypeReg);
1827 #if USE(JSVALUE64)
1828     m_jit.branchTestPtr(MacroAssembler::Zero, scratchReg, GPRInfo::tagMaskRegister).linkTo(loop, &m_jit);
1829 #else
1830     m_jit.branchTest32(MacroAssembler::NonZero, scratchReg).linkTo(loop, &m_jit);
1831 #endif
1832     
1833     // No match - result is false.
1834 #if USE(JSVALUE64)
1835     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
1836 #else
1837     m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
1838 #endif
1839     MacroAssembler::Jump putResult = m_jit.jump();
1840     
1841     isInstance.link(&m_jit);
1842 #if USE(JSVALUE64)
1843     m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(true))), scratchReg);
1844 #else
1845     m_jit.move(MacroAssembler::TrustedImm32(1), scratchReg);
1846 #endif
1847     
1848     putResult.link(&m_jit);
1849 }
1850
1851 void SpeculativeJIT::compileInstanceOf(Node& node)
1852 {
1853     if (!!(at(node.child1()).prediction() & ~PredictCell) && !!(m_state.forNode(node.child1()).m_type & ~PredictCell)) {
1854         // It might not be a cell. Speculate less aggressively.
1855         
1856         JSValueOperand value(this, node.child1());
1857         SpeculateCellOperand prototype(this, node.child3());
1858         GPRTemporary scratch(this);
1859         
1860         GPRReg prototypeReg = prototype.gpr();
1861         GPRReg scratchReg = scratch.gpr();
1862         
1863 #if USE(JSVALUE64)
1864         GPRReg valueReg = value.gpr();
1865         MacroAssembler::Jump isCell = m_jit.branchTestPtr(MacroAssembler::Zero, valueReg, GPRInfo::tagMaskRegister);
1866         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsBoolean(false))), scratchReg);
1867 #else
1868         GPRReg valueTagReg = value.tagGPR();
1869         GPRReg valueReg = value.payloadGPR();
1870         MacroAssembler::Jump isCell = m_jit.branch32(MacroAssembler::Equal, valueTagReg, TrustedImm32(JSValue::CellTag));
1871         m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
1872 #endif
1873
1874         MacroAssembler::Jump done = m_jit.jump();
1875         
1876         isCell.link(&m_jit);
1877         
1878         compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
1879         
1880         done.link(&m_jit);
1881
1882 #if USE(JSVALUE64)
1883         jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
1884 #else
1885         booleanResult(scratchReg, m_compileIndex);
1886 #endif
1887         return;
1888     }
1889     
1890     SpeculateCellOperand value(this, node.child1());
1891     // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
1892     SpeculateCellOperand prototype(this, node.child3());
1893     
1894     GPRTemporary scratch(this);
1895     
1896     GPRReg valueReg = value.gpr();
1897     GPRReg prototypeReg = prototype.gpr();
1898     GPRReg scratchReg = scratch.gpr();
1899     
1900     compileInstanceOfForObject(node, valueReg, prototypeReg, scratchReg);
1901
1902 #if USE(JSVALUE64)
1903     jsValueResult(scratchReg, m_compileIndex, DataFormatJSBoolean);
1904 #else
1905     booleanResult(scratchReg, m_compileIndex);
1906 #endif
1907 }
1908
1909 static bool isPowerOfTwo(int32_t num)
1910 {
1911     return num && !(num & (num - 1));
1912 }
1913
1914 void SpeculativeJIT::compileSoftModulo(Node& node)
1915 {
1916     bool shouldGeneratePowerOfTwoCheck = true;
1917
1918     // In the fast path, the dividend value could be the final result
1919     // (in case of |dividend| < |divisor|), so we speculate it as strict int32.
1920     SpeculateStrictInt32Operand op1(this, node.child1());
1921     GPRReg op1Gpr = op1.gpr();
1922
1923     if (isInt32Constant(node.child2())) {
1924         int32_t divisor = valueOfInt32Constant(node.child2());
1925         if (divisor < 0)
1926             divisor = -divisor;
1927
1928         if (isPowerOfTwo(divisor)) {
1929             GPRTemporary result(this);
1930             GPRReg resultGPR = result.gpr();
1931             m_jit.move(op1Gpr, resultGPR);
1932             JITCompiler::Jump positiveDividend = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1Gpr, TrustedImm32(0));
1933             m_jit.neg32(resultGPR);
1934             m_jit.and32(TrustedImm32(divisor - 1), resultGPR);
1935             m_jit.neg32(resultGPR);
1936             JITCompiler::Jump done = m_jit.jump();
1937
1938             positiveDividend.link(&m_jit);
1939             m_jit.and32(TrustedImm32(divisor - 1), resultGPR);
1940
1941             done.link(&m_jit);
1942             integerResult(resultGPR, m_compileIndex);
1943             return;
1944         }
1945 #if CPU(X86) || CPU(X86_64)
1946         if (divisor) {
1947             GPRTemporary eax(this, X86Registers::eax);
1948             GPRTemporary edx(this, X86Registers::edx);
1949             GPRTemporary scratch(this);
1950             GPRReg scratchGPR = scratch.gpr();
1951
1952             m_jit.move(op1Gpr, eax.gpr());
1953             m_jit.move(TrustedImm32(divisor), scratchGPR);
1954             m_jit.assembler().cdq();
1955             m_jit.assembler().idivl_r(scratchGPR);
1956             integerResult(edx.gpr(), m_compileIndex);
1957             return;
1958         }
1959 #endif
1960         // Fallback to non-constant case but avoid unnecessary checks.
1961         shouldGeneratePowerOfTwoCheck = false;
1962     }
1963
1964     SpeculateIntegerOperand op2(this, node.child2());
1965     GPRReg op2Gpr = op2.gpr();
1966
1967     speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2Gpr));
1968
1969 #if CPU(X86) || CPU(X86_64)
1970     GPRTemporary eax(this, X86Registers::eax);
1971     GPRTemporary edx(this, X86Registers::edx);
1972     GPRReg temp2 = InvalidGPRReg;
1973     if (op2Gpr == X86Registers::eax || op2Gpr == X86Registers::edx) {
1974         temp2 = allocate();
1975         m_jit.move(op2Gpr, temp2);
1976         op2Gpr = temp2;
1977     }
1978     GPRReg resultGPR = edx.gpr();
1979     GPRReg scratchGPR = eax.gpr();
1980 #else
1981     GPRTemporary result(this);
1982     GPRTemporary scratch(this);
1983     GPRTemporary scratch3(this);
1984     GPRReg scratchGPR3 = scratch3.gpr();
1985     GPRReg resultGPR = result.gpr();
1986     GPRReg scratchGPR = scratch.gpr();
1987 #endif
1988
1989     GPRTemporary scratch2(this);
1990     GPRReg scratchGPR2 = scratch2.gpr();
1991     JITCompiler::JumpList exitBranch;
1992
1993     // resultGPR is to hold the ABS value of the dividend before final result is produced
1994     m_jit.move(op1Gpr, resultGPR);
1995     // scratchGPR2 is to hold the ABS value of the divisor
1996     m_jit.move(op2Gpr, scratchGPR2);
1997
1998     // Check for negative result remainder
1999     // According to ECMA-262, the sign of the result equals the sign of the dividend
2000     JITCompiler::Jump positiveDividend = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op1Gpr, TrustedImm32(0));
2001     m_jit.neg32(resultGPR);
2002     m_jit.move(TrustedImm32(1), scratchGPR);
2003     JITCompiler::Jump saveCondition = m_jit.jump();
2004
2005     positiveDividend.link(&m_jit);
2006     m_jit.move(TrustedImm32(0), scratchGPR);
2007
2008     // Save the condition for negative remainder
2009     saveCondition.link(&m_jit);
2010     m_jit.push(scratchGPR);
2011
2012     JITCompiler::Jump positiveDivisor = m_jit.branch32(JITCompiler::GreaterThanOrEqual, op2Gpr, TrustedImm32(0));
2013     m_jit.neg32(scratchGPR2);
2014
2015     positiveDivisor.link(&m_jit);
2016     exitBranch.append(m_jit.branch32(JITCompiler::LessThan, resultGPR, scratchGPR2));
2017
2018     // Power of two fast case
2019     if (shouldGeneratePowerOfTwoCheck) {
2020         m_jit.move(scratchGPR2, scratchGPR);
2021         m_jit.sub32(TrustedImm32(1), scratchGPR);
2022         JITCompiler::Jump notPowerOfTwo = m_jit.branchTest32(JITCompiler::NonZero, scratchGPR, scratchGPR2);
2023         m_jit.and32(scratchGPR, resultGPR);
2024         exitBranch.append(m_jit.jump());
2025
2026         notPowerOfTwo.link(&m_jit);
2027     }
2028
2029 #if CPU(X86) || CPU(X86_64)
2030     m_jit.move(resultGPR, eax.gpr());
2031     m_jit.assembler().cdq();
2032     m_jit.assembler().idivl_r(scratchGPR2);
2033 #elif CPU(ARM_THUMB2)
2034     m_jit.countLeadingZeros32(scratchGPR2, scratchGPR);
2035     m_jit.countLeadingZeros32(resultGPR, scratchGPR3);
2036     m_jit.sub32(scratchGPR3, scratchGPR);
2037
2038     JITCompiler::Jump useFullTable = m_jit.branch32(JITCompiler::Equal, scratchGPR, TrustedImm32(31));
2039
2040     m_jit.neg32(scratchGPR);
2041     m_jit.add32(TrustedImm32(31), scratchGPR);
2042
2043     int elementSizeByShift = -1;
2044     elementSizeByShift = 3;
2045     m_jit.relativeTableJump(scratchGPR, elementSizeByShift);
2046
2047     useFullTable.link(&m_jit);
2048     // Modulo table
2049     for (int i = 31; i > 0; --i) {
2050         ShiftTypeAndAmount shift(SRType_LSL, i);
2051         m_jit.assembler().sub_S(scratchGPR, resultGPR, scratchGPR2, shift);
2052         m_jit.assembler().it(ARMv7Assembler::ConditionCS);
2053         m_jit.assembler().mov(resultGPR, scratchGPR);
2054     }
2055
2056     JITCompiler::Jump lower = m_jit.branch32(JITCompiler::Below, resultGPR, scratchGPR2);
2057     m_jit.sub32(scratchGPR2, resultGPR);
2058     lower.link(&m_jit);
2059 #endif // CPU(X86) || CPU(X86_64)
2060
2061     exitBranch.link(&m_jit);
2062
2063     // Check for negative remainder
2064     m_jit.pop(scratchGPR);
2065     JITCompiler::Jump positiveResult = m_jit.branch32(JITCompiler::Equal, scratchGPR, TrustedImm32(0));
2066     m_jit.neg32(resultGPR);
2067     positiveResult.link(&m_jit);
2068
2069     integerResult(resultGPR, m_compileIndex);
2070
2071 #if CPU(X86) || CPU(X86_64)
2072     if (temp2 != InvalidGPRReg)
2073         unlock(temp2);
2074 #endif
2075 }
2076
2077 void SpeculativeJIT::compileArithMul(Node& node)
2078 {
2079     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) {
2080         SpeculateIntegerOperand op1(this, node.child1());
2081         SpeculateIntegerOperand op2(this, node.child2());
2082         GPRTemporary result(this);
2083
2084         GPRReg reg1 = op1.gpr();
2085         GPRReg reg2 = op2.gpr();
2086
2087         // What is unfortunate is that we cannot take advantage of nodeCanTruncateInteger()
2088         // here. A multiply on integers performed in the double domain and then truncated to
2089         // an integer will give a different result than a multiply performed in the integer
2090         // domain and then truncated, if the integer domain result would have resulted in
2091         // something bigger than what a 32-bit integer can hold. JavaScript mandates that
2092         // the semantics are always as if the multiply had been performed in the double
2093         // domain.
2094             
2095         speculationCheck(Overflow, JSValueRegs(), NoNode, m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
2096             
2097         // Check for negative zero, if the users of this node care about such things.
2098         if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
2099             MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
2100             speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
2101             speculationCheck(NegativeZero, JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
2102             resultNonZero.link(&m_jit);
2103         }
2104
2105         integerResult(result.gpr(), m_compileIndex);
2106         return;
2107     }
2108
2109     SpeculateDoubleOperand op1(this, node.child1());
2110     SpeculateDoubleOperand op2(this, node.child2());
2111     FPRTemporary result(this, op1, op2);
2112
2113     FPRReg reg1 = op1.fpr();
2114     FPRReg reg2 = op2.fpr();
2115         
2116     m_jit.mulDouble(reg1, reg2, result.fpr());
2117         
2118     doubleResult(result.fpr(), m_compileIndex);
2119 }
2120
2121 void SpeculativeJIT::compileArithMod(Node& node)
2122 {
2123     if (!at(node.child1()).shouldNotSpeculateInteger() && !at(node.child2()).shouldNotSpeculateInteger()
2124         && node.canSpeculateInteger()) {
2125         compileSoftModulo(node);
2126         return;
2127     }
2128         
2129     SpeculateDoubleOperand op1(this, node.child1());
2130     SpeculateDoubleOperand op2(this, node.child2());
2131         
2132     FPRReg op1FPR = op1.fpr();
2133     FPRReg op2FPR = op2.fpr();
2134         
2135     flushRegisters();
2136         
2137     FPRResult result(this);
2138
2139     callOperation(fmodAsDFGOperation, result.fpr(), op1FPR, op2FPR);
2140         
2141     doubleResult(result.fpr(), m_compileIndex);
2142 }
2143
2144 // Returns true if the compare is fused with a subsequent branch.
2145 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
2146 {
2147     if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
2148         return true;
2149
2150     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())))
2151         compileIntegerCompare(node, condition);
2152     else if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2())))
2153         compileDoubleCompare(node, doubleCondition);
2154     else if (node.op == CompareEq && Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2())))
2155         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
2156     else if (node.op == CompareEq && Node::shouldSpeculateArray(at(node.child1()), at(node.child2())))
2157         compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
2158     else
2159         nonSpeculativeNonPeepholeCompare(node, condition, operation);
2160     
2161     return false;
2162 }
2163
2164 bool SpeculativeJIT::compileStrictEqForConstant(Node& node, NodeIndex value, JSValue constant)
2165 {
2166     JSValueOperand op1(this, value);
2167     
2168     NodeIndex branchNodeIndex = detectPeepHoleBranch();
2169     if (branchNodeIndex != NoNode) {
2170         Node& branchNode = at(branchNodeIndex);
2171         BlockIndex taken = branchNode.takenBlockIndex();
2172         BlockIndex notTaken = branchNode.notTakenBlockIndex();
2173         MacroAssembler::RelationalCondition condition = MacroAssembler::Equal;
2174         
2175         // The branch instruction will branch to the taken block.
2176         // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
2177         if (taken == (m_block + 1)) {
2178             condition = MacroAssembler::NotEqual;
2179             BlockIndex tmp = taken;
2180             taken = notTaken;
2181             notTaken = tmp;
2182         }
2183
2184 #if USE(JSVALUE64)
2185         addBranch(m_jit.branchPtr(condition, op1.gpr(), MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant)))), taken);
2186 #else
2187         GPRReg payloadGPR = op1.payloadGPR();
2188         GPRReg tagGPR = op1.tagGPR();
2189         if (condition == MacroAssembler::Equal) {
2190             // Drop down if not equal, go elsewhere if equal.
2191             MacroAssembler::Jump notEqual = m_jit.branch32(MacroAssembler::NotEqual, tagGPR, MacroAssembler::Imm32(constant.tag()));
2192             addBranch(m_jit.branch32(MacroAssembler::Equal, payloadGPR, MacroAssembler::Imm32(constant.payload())), taken);
2193             notEqual.link(&m_jit);
2194         } else {
2195             // Drop down if equal, go elsehwere if not equal.
2196             addBranch(m_jit.branch32(MacroAssembler::NotEqual, tagGPR, MacroAssembler::Imm32(constant.tag())), taken);
2197             addBranch(m_jit.branch32(MacroAssembler::NotEqual, payloadGPR, MacroAssembler::Imm32(constant.payload())), taken);
2198         }
2199 #endif
2200         
2201         if (notTaken != (m_block + 1))
2202             addBranch(m_jit.jump(), notTaken);
2203         
2204         use(node.child1());
2205         use(node.child2());
2206         m_compileIndex = branchNodeIndex;
2207         return true;
2208     }
2209     
2210     GPRTemporary result(this);
2211     
2212 #if USE(JSVALUE64)
2213     GPRReg op1GPR = op1.gpr();
2214     GPRReg resultGPR = result.gpr();
2215     m_jit.move(MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(ValueFalse)), resultGPR);
2216     MacroAssembler::Jump notEqual = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, MacroAssembler::TrustedImmPtr(bitwise_cast<void*>(JSValue::encode(constant))));
2217     m_jit.or32(MacroAssembler::Imm32(1), resultGPR);
2218     notEqual.link(&m_jit);
2219     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
2220 #else
2221     GPRReg op1PayloadGPR = op1.payloadGPR();
2222     GPRReg op1TagGPR = op1.tagGPR();
2223     GPRReg resultGPR = result.gpr();
2224     m_jit.move(Imm32(0), resultGPR);
2225     MacroAssembler::JumpList notEqual;
2226     notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, MacroAssembler::Imm32(constant.tag())));
2227     notEqual.append(m_jit.branch32(MacroAssembler::NotEqual, op1PayloadGPR, MacroAssembler::Imm32(constant.payload())));
2228     m_jit.move(Imm32(1), resultGPR);
2229     notEqual.link(&m_jit);
2230     booleanResult(resultGPR, m_compileIndex);
2231 #endif
2232     
2233     return false;
2234 }
2235
2236 bool SpeculativeJIT::compileStrictEq(Node& node)
2237 {
2238     // 1) If either operand is a constant and that constant is not a double, integer,
2239     //    or string, then do a JSValue comparison.
2240     
2241     if (isJSConstant(node.child1())) {
2242         JSValue value = valueOfJSConstant(node.child1());
2243         if (!value.isNumber() && !value.isString())
2244             return compileStrictEqForConstant(node, node.child2(), value);
2245     }
2246     
2247     if (isJSConstant(node.child2())) {
2248         JSValue value = valueOfJSConstant(node.child2());
2249         if (!value.isNumber() && !value.isString())
2250             return compileStrictEqForConstant(node, node.child1(), value);
2251     }
2252     
2253     // 2) If the operands are predicted integer, do an integer comparison.
2254     
2255     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
2256         NodeIndex branchNodeIndex = detectPeepHoleBranch();
2257         if (branchNodeIndex != NoNode) {
2258             compilePeepHoleIntegerBranch(node, branchNodeIndex, MacroAssembler::Equal);
2259             use(node.child1());
2260             use(node.child2());
2261             m_compileIndex = branchNodeIndex;
2262             return true;
2263         }
2264         compileIntegerCompare(node, MacroAssembler::Equal);
2265         return false;
2266     }
2267     
2268     // 3) If the operands are predicted double, do a double comparison.
2269     
2270     if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2271         NodeIndex branchNodeIndex = detectPeepHoleBranch();
2272         if (branchNodeIndex != NoNode) {
2273             compilePeepHoleDoubleBranch(node, branchNodeIndex, MacroAssembler::DoubleEqual);
2274             use(node.child1());
2275             use(node.child2());
2276             m_compileIndex = branchNodeIndex;
2277             return true;
2278         }
2279         compileDoubleCompare(node, MacroAssembler::DoubleEqual);
2280         return false;
2281     }
2282     
2283     // 4) If the operands are predicted final object or array, then do a final object
2284     //    or array comparison.
2285     
2286     if (Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2()))) {
2287         NodeIndex branchNodeIndex = detectPeepHoleBranch();
2288         if (branchNodeIndex != NoNode) {
2289             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
2290             use(node.child1());
2291             use(node.child2());
2292             m_compileIndex = branchNodeIndex;
2293             return true;
2294         }
2295         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
2296         return false;
2297     }
2298     
2299     if (Node::shouldSpeculateArray(at(node.child1()), at(node.child2()))) {
2300         NodeIndex branchNodeIndex = detectPeepHoleBranch();
2301         if (branchNodeIndex != NoNode) {
2302             compilePeepHoleObjectEquality(node, branchNodeIndex, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
2303             use(node.child1());
2304             use(node.child2());
2305             m_compileIndex = branchNodeIndex;
2306             return true;
2307         }
2308         compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
2309         return false;
2310     }
2311     
2312     // 5) Fall back to non-speculative strict equality.
2313     
2314     return nonSpeculativeStrictEq(node);
2315 }
2316
2317 void SpeculativeJIT::compileGetIndexedPropertyStorage(Node& node)
2318 {
2319     SpeculateCellOperand base(this, node.child1());
2320     GPRReg baseReg = base.gpr();
2321     
2322     PredictedType basePrediction = at(node.child2()).prediction();
2323     if (!(basePrediction & PredictInt32) && basePrediction) {
2324         ASSERT_NOT_REACHED();
2325         terminateSpeculativeExecution(Uncountable, JSValueRegs(), NoNode);
2326         noResult(m_compileIndex);
2327         return;
2328     }
2329     
2330     GPRTemporary storage(this);
2331     GPRReg storageReg = storage.gpr();
2332     if (at(node.child1()).prediction() == PredictString) {
2333         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
2334             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
2335
2336         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSString::offsetOfValue()), storageReg);
2337         
2338         // Speculate that we're not accessing a rope
2339         speculationCheck(Uncountable, JSValueRegs(), NoNode, m_jit.branchTest32(MacroAssembler::Zero, storageReg));
2340
2341         m_jit.loadPtr(MacroAssembler::Address(storageReg, StringImpl::dataOffset()), storageReg);
2342     } else if (at(node.child1()).shouldSpeculateByteArray()) {
2343         if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
2344             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
2345         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSByteArray::offsetOfStorage()), storageReg);
2346     } else if (at(node.child1()).shouldSpeculateInt8Array()) {
2347         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int8ArrayDescriptor();
2348         if (!isInt8ArrayPrediction(m_state.forNode(node.child1()).m_type))
2349             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2350         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2351     } else if (at(node.child1()).shouldSpeculateInt16Array()) {
2352         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int16ArrayDescriptor();
2353         if (!isInt16ArrayPrediction(m_state.forNode(node.child1()).m_type))
2354             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2355         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2356     } else if (at(node.child1()).shouldSpeculateInt32Array()) {
2357         const TypedArrayDescriptor& descriptor = m_jit.globalData()->int32ArrayDescriptor();
2358         if (!isInt32ArrayPrediction(m_state.forNode(node.child1()).m_type))
2359             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2360         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2361     } else if (at(node.child1()).shouldSpeculateUint8Array()) {
2362         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint8ArrayDescriptor();
2363         if (!isUint8ArrayPrediction(m_state.forNode(node.child1()).m_type))
2364             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2365         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2366     } else if (at(node.child1()).shouldSpeculateUint16Array()) {
2367         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint16ArrayDescriptor();
2368         if (!isUint16ArrayPrediction(m_state.forNode(node.child1()).m_type))
2369             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2370         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2371     } else if (at(node.child1()).shouldSpeculateUint32Array()) {
2372         const TypedArrayDescriptor& descriptor = m_jit.globalData()->uint32ArrayDescriptor();
2373         if (!isUint32ArrayPrediction(m_state.forNode(node.child1()).m_type))
2374             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2375         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2376     } else if (at(node.child1()).shouldSpeculateFloat32Array()) {
2377         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float32ArrayDescriptor();
2378         if (!isFloat32ArrayPrediction(m_state.forNode(node.child1()).m_type))
2379             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2380         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2381     } else if (at(node.child1()).shouldSpeculateFloat64Array()) {
2382         const TypedArrayDescriptor& descriptor = m_jit.globalData()->float64ArrayDescriptor();
2383         if (!isFloat64ArrayPrediction(m_state.forNode(node.child1()).m_type))
2384             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(descriptor.m_vptr)));
2385         m_jit.loadPtr(MacroAssembler::Address(baseReg, descriptor.m_storageOffset), storageReg);
2386     } else {
2387         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
2388             speculationCheck(BadType, JSValueSource::unboxedCell(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2389         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
2390     }
2391     storageResult(storageReg, m_compileIndex);
2392 }
2393
2394 } } // namespace JSC::DFG
2395
2396 #endif