tizen beta release
[profile/ivi/webkit-efl.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT64.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 #include "JSByteArray.h"
30
31 #if ENABLE(DFG_JIT)
32
33 namespace JSC { namespace DFG {
34
35 #if USE(JSVALUE64)
36
37 GPRReg SpeculativeJIT::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
38 {
39     Node& node = at(nodeIndex);
40     VirtualRegister virtualRegister = node.virtualRegister();
41     GenerationInfo& info = m_generationInfo[virtualRegister];
42
43     if (info.registerFormat() == DataFormatNone) {
44         GPRReg gpr = allocate();
45
46         if (node.hasConstant()) {
47             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
48             if (isInt32Constant(nodeIndex)) {
49                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
50                 info.fillInteger(gpr);
51                 returnFormat = DataFormatInteger;
52                 return gpr;
53             }
54             if (isNumberConstant(nodeIndex)) {
55                 JSValue jsValue = jsNumber(valueOfNumberConstant(nodeIndex));
56                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
57             } else {
58                 ASSERT(isJSConstant(nodeIndex));
59                 JSValue jsValue = valueOfJSConstant(nodeIndex);
60                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
61             }
62         } else if (info.spillFormat() == DataFormatInteger) {
63             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
64             m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
65             // Tag it, since fillInteger() is used when we want a boxed integer.
66             m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr);
67         } else {
68             ASSERT(info.spillFormat() == DataFormatJS || info.spillFormat() == DataFormatJSInteger);
69             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
70             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
71         }
72
73         // Since we statically know that we're filling an integer, and values
74         // in the RegisterFile are boxed, this must be DataFormatJSInteger.
75         // We will check this with a jitAssert below.
76         info.fillJSValue(gpr, DataFormatJSInteger);
77         unlock(gpr);
78     }
79
80     switch (info.registerFormat()) {
81     case DataFormatNone:
82         // Should have filled, above.
83     case DataFormatJSDouble:
84     case DataFormatDouble:
85     case DataFormatJS:
86     case DataFormatCell:
87     case DataFormatJSCell:
88     case DataFormatBoolean:
89     case DataFormatJSBoolean:
90     case DataFormatStorage:
91         // Should only be calling this function if we know this operand to be integer.
92         ASSERT_NOT_REACHED();
93
94     case DataFormatJSInteger: {
95         GPRReg gpr = info.gpr();
96         m_gprs.lock(gpr);
97         m_jit.jitAssertIsJSInt32(gpr);
98         returnFormat = DataFormatJSInteger;
99         return gpr;
100     }
101
102     case DataFormatInteger: {
103         GPRReg gpr = info.gpr();
104         m_gprs.lock(gpr);
105         m_jit.jitAssertIsInt32(gpr);
106         returnFormat = DataFormatInteger;
107         return gpr;
108     }
109     }
110
111     ASSERT_NOT_REACHED();
112     return InvalidGPRReg;
113 }
114
115 FPRReg SpeculativeJIT::fillDouble(NodeIndex nodeIndex)
116 {
117     Node& node = at(nodeIndex);
118     VirtualRegister virtualRegister = node.virtualRegister();
119     GenerationInfo& info = m_generationInfo[virtualRegister];
120
121     if (info.registerFormat() == DataFormatNone) {
122         if (node.hasConstant()) {
123             GPRReg gpr = allocate();
124         
125             if (isInt32Constant(nodeIndex)) {
126                 // FIXME: should not be reachable?
127                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
128                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
129                 info.fillInteger(gpr);
130                 unlock(gpr);
131             } else if (isNumberConstant(nodeIndex)) {
132                 FPRReg fpr = fprAllocate();
133                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(nodeIndex)))), gpr);
134                 m_jit.movePtrToDouble(gpr, fpr);
135                 unlock(gpr);
136
137                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
138                 info.fillDouble(fpr);
139                 return fpr;
140             } else {
141                 // FIXME: should not be reachable?
142                 ASSERT(isJSConstant(nodeIndex));
143                 JSValue jsValue = valueOfJSConstant(nodeIndex);
144                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
145                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
146                 info.fillJSValue(gpr, DataFormatJS);
147                 unlock(gpr);
148             }
149         } else {
150             DataFormat spillFormat = info.spillFormat();
151             switch (spillFormat) {
152             case DataFormatDouble: {
153                 FPRReg fpr = fprAllocate();
154                 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
155                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
156                 info.fillDouble(fpr);
157                 return fpr;
158             }
159                 
160             case DataFormatInteger: {
161                 GPRReg gpr = allocate();
162                 
163                 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
164                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
165                 info.fillInteger(gpr);
166                 unlock(gpr);
167                 break;
168             }
169
170             default:
171                 GPRReg gpr = allocate();
172         
173                 ASSERT(spillFormat & DataFormatJS);
174                 m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
175                 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
176                 info.fillJSValue(gpr, spillFormat);
177                 unlock(gpr);
178                 break;
179             }
180         }
181     }
182
183     switch (info.registerFormat()) {
184     case DataFormatNone:
185         // Should have filled, above.
186     case DataFormatCell:
187     case DataFormatJSCell:
188     case DataFormatBoolean:
189     case DataFormatJSBoolean:
190     case DataFormatStorage:
191         // Should only be calling this function if we know this operand to be numeric.
192         ASSERT_NOT_REACHED();
193
194     case DataFormatJS: {
195         GPRReg jsValueGpr = info.gpr();
196         m_gprs.lock(jsValueGpr);
197         FPRReg fpr = fprAllocate();
198         GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?
199
200         JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
201
202         m_jit.jitAssertIsJSDouble(jsValueGpr);
203
204         // First, if we get here we have a double encoded as a JSValue
205         m_jit.move(jsValueGpr, tempGpr);
206         unboxDouble(tempGpr, fpr);
207         JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
208
209         // Finally, handle integers.
210         isInteger.link(&m_jit);
211         m_jit.convertInt32ToDouble(jsValueGpr, fpr);
212         hasUnboxedDouble.link(&m_jit);
213
214         m_gprs.release(jsValueGpr);
215         m_gprs.unlock(jsValueGpr);
216         m_gprs.unlock(tempGpr);
217         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
218         info.fillDouble(fpr);
219         info.killSpilled();
220         return fpr;
221     }
222
223     case DataFormatJSInteger:
224     case DataFormatInteger: {
225         FPRReg fpr = fprAllocate();
226         GPRReg gpr = info.gpr();
227         m_gprs.lock(gpr);
228         m_jit.convertInt32ToDouble(gpr, fpr);
229         m_gprs.unlock(gpr);
230         return fpr;
231     }
232
233     // Unbox the double
234     case DataFormatJSDouble: {
235         GPRReg gpr = info.gpr();
236         FPRReg fpr = fprAllocate();
237         if (m_gprs.isLocked(gpr)) {
238             // Make sure we don't trample gpr if it is in use.
239             GPRReg temp = allocate();
240             m_jit.move(gpr, temp);
241             unboxDouble(temp, fpr);
242             unlock(temp);
243         } else
244             unboxDouble(gpr, fpr);
245
246         m_gprs.release(gpr);
247         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
248
249         info.fillDouble(fpr);
250         return fpr;
251     }
252
253     case DataFormatDouble: {
254         FPRReg fpr = info.fpr();
255         m_fprs.lock(fpr);
256         return fpr;
257     }
258     }
259
260     ASSERT_NOT_REACHED();
261     return InvalidFPRReg;
262 }
263
264 GPRReg SpeculativeJIT::fillJSValue(NodeIndex nodeIndex)
265 {
266     Node& node = at(nodeIndex);
267     VirtualRegister virtualRegister = node.virtualRegister();
268     GenerationInfo& info = m_generationInfo[virtualRegister];
269     
270     switch (info.registerFormat()) {
271     case DataFormatNone: {
272         GPRReg gpr = allocate();
273
274         if (node.hasConstant()) {
275             if (isInt32Constant(nodeIndex)) {
276                 info.fillJSValue(gpr, DataFormatJSInteger);
277                 JSValue jsValue = jsNumber(valueOfInt32Constant(nodeIndex));
278                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
279             } else if (isNumberConstant(nodeIndex)) {
280                 info.fillJSValue(gpr, DataFormatJSDouble);
281                 JSValue jsValue(JSValue::EncodeAsDouble, valueOfNumberConstant(nodeIndex));
282                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
283             } else {
284                 ASSERT(isJSConstant(nodeIndex));
285                 JSValue jsValue = valueOfJSConstant(nodeIndex);
286                 m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
287                 info.fillJSValue(gpr, DataFormatJS);
288             }
289
290             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
291         } else {
292             DataFormat spillFormat = info.spillFormat();
293             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
294             if (spillFormat == DataFormatInteger) {
295                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
296                 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr);
297                 spillFormat = DataFormatJSInteger;
298             } else {
299                 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
300                 if (spillFormat == DataFormatDouble) {
301                     // Need to box the double, since we want a JSValue.
302                     m_jit.subPtr(GPRInfo::tagTypeNumberRegister, gpr);
303                     spillFormat = DataFormatJSDouble;
304                 } else
305                     ASSERT(spillFormat & DataFormatJS);
306             }
307             info.fillJSValue(gpr, spillFormat);
308         }
309         return gpr;
310     }
311
312     case DataFormatInteger: {
313         GPRReg gpr = info.gpr();
314         // If the register has already been locked we need to take a copy.
315         // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
316         if (m_gprs.isLocked(gpr)) {
317             GPRReg result = allocate();
318             m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr, result);
319             return result;
320         }
321         m_gprs.lock(gpr);
322         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr);
323         info.fillJSValue(gpr, DataFormatJSInteger);
324         return gpr;
325     }
326
327     case DataFormatDouble: {
328         FPRReg fpr = info.fpr();
329         GPRReg gpr = boxDouble(fpr);
330
331         // Update all info
332         info.fillJSValue(gpr, DataFormatJSDouble);
333         m_fprs.release(fpr);
334         m_gprs.retain(gpr, virtualRegister, SpillOrderJS);
335
336         return gpr;
337     }
338
339     case DataFormatCell:
340         // No retag required on JSVALUE64!
341     case DataFormatJS:
342     case DataFormatJSInteger:
343     case DataFormatJSDouble:
344     case DataFormatJSCell:
345     case DataFormatJSBoolean: {
346         GPRReg gpr = info.gpr();
347         m_gprs.lock(gpr);
348         return gpr;
349     }
350         
351     case DataFormatBoolean:
352     case DataFormatStorage:
353         // this type currently never occurs
354         ASSERT_NOT_REACHED();
355     }
356
357     ASSERT_NOT_REACHED();
358     return InvalidGPRReg;
359 }
360
361 void SpeculativeJIT::nonSpeculativeValueToNumber(Node& node)
362 {
363     if (isKnownNumeric(node.child1())) {
364         JSValueOperand op1(this, node.child1());
365         GPRTemporary result(this, op1);
366         m_jit.move(op1.gpr(), result.gpr());
367         jsValueResult(result.gpr(), m_compileIndex);
368         return;
369     }
370
371     JSValueOperand op1(this, node.child1());
372     GPRTemporary result(this);
373     
374     ASSERT(!isInt32Constant(node.child1()));
375     ASSERT(!isNumberConstant(node.child1()));
376     
377     GPRReg jsValueGpr = op1.gpr();
378     GPRReg gpr = result.gpr();
379     op1.use();
380
381     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
382     JITCompiler::Jump nonNumeric = m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister);
383
384     // First, if we get here we have a double encoded as a JSValue
385     m_jit.move(jsValueGpr, gpr);
386     JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
387
388     // Next handle cells (& other JS immediates)
389     nonNumeric.link(&m_jit);
390     silentSpillAllRegisters(gpr);
391     callOperation(dfgConvertJSValueToNumber, FPRInfo::returnValueFPR, jsValueGpr);
392     boxDouble(FPRInfo::returnValueFPR, gpr);
393     silentFillAllRegisters(gpr);
394     JITCompiler::Jump hasCalledToNumber = m_jit.jump();
395     
396     // Finally, handle integers.
397     isInteger.link(&m_jit);
398     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, jsValueGpr, gpr);
399     hasUnboxedDouble.link(&m_jit);
400     hasCalledToNumber.link(&m_jit);
401     
402     jsValueResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
403 }
404
405 void SpeculativeJIT::nonSpeculativeValueToInt32(Node& node)
406 {
407     ASSERT(!isInt32Constant(node.child1()));
408     
409     if (isKnownInteger(node.child1())) {
410         IntegerOperand op1(this, node.child1());
411         GPRTemporary result(this, op1);
412         m_jit.move(op1.gpr(), result.gpr());
413         integerResult(result.gpr(), m_compileIndex);
414         return;
415     }
416     
417     GenerationInfo& childInfo = m_generationInfo[at(node.child1()).virtualRegister()];
418     if (childInfo.isJSDouble()) {
419         DoubleOperand op1(this, node.child1());
420         GPRTemporary result(this);
421         FPRReg fpr = op1.fpr();
422         GPRReg gpr = result.gpr();
423         op1.use();
424         JITCompiler::Jump truncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateSuccessful);
425         
426         silentSpillAllRegisters(gpr);
427         callOperation(toInt32, gpr, fpr);
428         silentFillAllRegisters(gpr);
429         
430         truncatedToInteger.link(&m_jit);
431         integerResult(gpr, m_compileIndex, UseChildrenCalledExplicitly);
432         return;
433     }
434     
435     JSValueOperand op1(this, node.child1());
436     GPRTemporary result(this, op1);
437     GPRReg jsValueGpr = op1.gpr();
438     GPRReg resultGPR = result.gpr();
439     op1.use();
440
441     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
442
443     // First handle non-integers
444     silentSpillAllRegisters(resultGPR);
445     callOperation(dfgConvertJSValueToInt32, resultGPR, jsValueGpr);
446     silentFillAllRegisters(resultGPR);
447     JITCompiler::Jump hasCalledToInt32 = m_jit.jump();
448
449     // Then handle integers.
450     isInteger.link(&m_jit);
451     m_jit.zeroExtend32ToPtr(jsValueGpr, resultGPR);
452     hasCalledToInt32.link(&m_jit);
453     integerResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
454 }
455
456 void SpeculativeJIT::nonSpeculativeUInt32ToNumber(Node& node)
457 {
458     IntegerOperand op1(this, node.child1());
459     FPRTemporary boxer(this);
460     GPRTemporary result(this, op1);
461     
462     JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, op1.gpr(), TrustedImm32(0));
463     
464     m_jit.convertInt32ToDouble(op1.gpr(), boxer.fpr());
465     m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), boxer.fpr());
466     
467     boxDouble(boxer.fpr(), result.gpr());
468     
469     JITCompiler::Jump done = m_jit.jump();
470     
471     positive.link(&m_jit);
472     
473     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, op1.gpr(), result.gpr());
474     
475     done.link(&m_jit);
476     
477     jsValueResult(result.gpr(), m_compileIndex);
478 }
479
480 void SpeculativeJIT::nonSpeculativeKnownConstantArithOp(NodeType op, NodeIndex regChild, NodeIndex immChild, bool commute)
481 {
482     JSValueOperand regArg(this, regChild);
483     GPRReg regArgGPR = regArg.gpr();
484     GPRTemporary result(this);
485     GPRReg resultGPR = result.gpr();
486     FPRTemporary tmp1(this);
487     FPRTemporary tmp2(this);
488     FPRReg tmp1FPR = tmp1.fpr();
489     FPRReg tmp2FPR = tmp2.fpr();
490     
491     regArg.use();
492     use(immChild);
493
494     JITCompiler::Jump notInt;
495     
496     int32_t imm = valueOfInt32Constant(immChild);
497         
498     if (!isKnownInteger(regChild))
499         notInt = m_jit.branchPtr(MacroAssembler::Below, regArgGPR, GPRInfo::tagTypeNumberRegister);
500     
501     JITCompiler::Jump overflow;
502     
503     switch (op) {
504     case ValueAdd:
505     case ArithAdd:
506         overflow = m_jit.branchAdd32(MacroAssembler::Overflow, regArgGPR, Imm32(imm), resultGPR);
507         break;
508         
509     case ArithSub:
510         overflow = m_jit.branchSub32(MacroAssembler::Overflow, regArgGPR, Imm32(imm), resultGPR);
511         break;
512         
513     default:
514         ASSERT_NOT_REACHED();
515     }
516     
517     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
518         
519     JITCompiler::Jump done = m_jit.jump();
520     
521     overflow.link(&m_jit);
522     
523     JITCompiler::Jump notNumber;
524     
525     // first deal with overflow case
526     m_jit.convertInt32ToDouble(regArgGPR, tmp2FPR);
527     
528     // now deal with not-int case, if applicable
529     if (!isKnownInteger(regChild)) {
530         JITCompiler::Jump haveValue = m_jit.jump();
531         
532         notInt.link(&m_jit);
533         
534         if (!isKnownNumeric(regChild)) {
535             ASSERT(op == ValueAdd);
536             notNumber = m_jit.branchTestPtr(MacroAssembler::Zero, regArgGPR, GPRInfo::tagTypeNumberRegister);
537         }
538         
539         m_jit.move(regArgGPR, resultGPR);
540         m_jit.addPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
541         m_jit.movePtrToDouble(resultGPR, tmp2FPR);
542         
543         haveValue.link(&m_jit);
544     }
545     
546     m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(immChild)))), resultGPR);
547     m_jit.movePtrToDouble(resultGPR, tmp1FPR);
548     switch (op) {
549     case ValueAdd:
550     case ArithAdd:
551         m_jit.addDouble(tmp1FPR, tmp2FPR);
552         break;
553         
554     case ArithSub:
555         m_jit.subDouble(tmp1FPR, tmp2FPR);
556         break;
557             
558     default:
559         ASSERT_NOT_REACHED();
560     }
561     
562     JITCompiler::Jump doneCaseConvertedToInt;
563     
564     if (op == ValueAdd) {
565         JITCompiler::JumpList failureCases;
566         m_jit.branchConvertDoubleToInt32(tmp2FPR, resultGPR, failureCases, tmp1FPR);
567         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
568         
569         doneCaseConvertedToInt = m_jit.jump();
570         
571         failureCases.link(&m_jit);
572     }
573     
574     m_jit.moveDoubleToPtr(tmp2FPR, resultGPR);
575     m_jit.subPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
576         
577     if (!isKnownNumeric(regChild)) {
578         ASSERT(notNumber.isSet());
579         ASSERT(op == ValueAdd);
580             
581         JITCompiler::Jump doneCaseWasNumber = m_jit.jump();
582             
583         notNumber.link(&m_jit);
584             
585         silentSpillAllRegisters(resultGPR);
586         if (commute)
587             callOperation(operationValueAddNotNumber, resultGPR, MacroAssembler::Imm32(imm), regArgGPR);
588         else
589             callOperation(operationValueAddNotNumber, resultGPR, regArgGPR, MacroAssembler::Imm32(imm));
590         silentFillAllRegisters(resultGPR);
591             
592         doneCaseWasNumber.link(&m_jit);
593     }
594     
595     done.link(&m_jit);
596     if (doneCaseConvertedToInt.isSet())
597         doneCaseConvertedToInt.link(&m_jit);
598         
599     jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
600 }
601
602 void SpeculativeJIT::nonSpeculativeBasicArithOp(NodeType op, Node &node)
603 {
604     JSValueOperand arg1(this, node.child1());
605     JSValueOperand arg2(this, node.child2());
606     
607     FPRTemporary tmp1(this);
608     FPRTemporary tmp2(this);
609     FPRReg tmp1FPR = tmp1.fpr();
610     FPRReg tmp2FPR = tmp2.fpr();
611     
612     GPRTemporary result(this);
613
614     GPRReg arg1GPR = arg1.gpr();
615     GPRReg arg2GPR = arg2.gpr();
616     
617     GPRReg resultGPR = result.gpr();
618     
619     arg1.use();
620     arg2.use();
621     
622     JITCompiler::Jump child1NotInt;
623     JITCompiler::Jump child2NotInt;
624     JITCompiler::JumpList overflow;
625     
626     if (!isKnownInteger(node.child1()))
627         child1NotInt = m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister);
628     if (!isKnownInteger(node.child2()))
629         child2NotInt = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
630     
631     switch (op) {
632     case ValueAdd:
633     case ArithAdd: {
634         overflow.append(m_jit.branchAdd32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
635         break;
636     }
637         
638     case ArithSub: {
639         overflow.append(m_jit.branchSub32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
640         break;
641     }
642         
643     case ArithMul: {
644         overflow.append(m_jit.branchMul32(MacroAssembler::Overflow, arg1GPR, arg2GPR, resultGPR));
645         overflow.append(m_jit.branchTest32(MacroAssembler::Zero, resultGPR));
646         break;
647     }
648         
649     default:
650         ASSERT_NOT_REACHED();
651     }
652     
653     m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
654         
655     JITCompiler::Jump done = m_jit.jump();
656     
657     JITCompiler::JumpList haveFPRArguments;
658
659     overflow.link(&m_jit);
660         
661     // both arguments are integers
662     m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
663     m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
664         
665     haveFPRArguments.append(m_jit.jump());
666         
667     JITCompiler::JumpList notNumbers;
668         
669     JITCompiler::Jump child2NotInt2;
670         
671     if (!isKnownInteger(node.child1())) {
672         child1NotInt.link(&m_jit);
673             
674         if (!isKnownNumeric(node.child1())) {
675             ASSERT(op == ValueAdd);
676             notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg1GPR, GPRInfo::tagTypeNumberRegister));
677         }
678             
679         m_jit.move(arg1GPR, resultGPR);
680         unboxDouble(resultGPR, tmp1FPR);
681             
682         // child1 is converted to a double; child2 may either be an int or
683         // a boxed double
684             
685         if (!isKnownInteger(node.child2())) {
686             if (isKnownNumeric(node.child2()))
687                 child2NotInt2 = m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister);
688             else {
689                 ASSERT(op == ValueAdd);
690                 JITCompiler::Jump child2IsInt = m_jit.branchPtr(MacroAssembler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
691                 notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg2GPR, GPRInfo::tagTypeNumberRegister));
692                 child2NotInt2 = m_jit.jump();
693                 child2IsInt.link(&m_jit);
694             }
695         }
696             
697         // child 2 is definitely an integer
698         m_jit.convertInt32ToDouble(arg2GPR, tmp2FPR);
699             
700         haveFPRArguments.append(m_jit.jump());
701     }
702         
703     if (!isKnownInteger(node.child2())) {
704         child2NotInt.link(&m_jit);
705             
706         if (!isKnownNumeric(node.child2())) {
707             ASSERT(op == ValueAdd);
708             notNumbers.append(m_jit.branchTestPtr(MacroAssembler::Zero, arg2GPR, GPRInfo::tagTypeNumberRegister));
709         }
710             
711         // child1 is definitely an integer, and child 2 is definitely not
712             
713         m_jit.convertInt32ToDouble(arg1GPR, tmp1FPR);
714             
715         if (child2NotInt2.isSet())
716             child2NotInt2.link(&m_jit);
717             
718         m_jit.move(arg2GPR, resultGPR);
719         unboxDouble(resultGPR, tmp2FPR);
720     }
721         
722     haveFPRArguments.link(&m_jit);
723         
724     switch (op) {
725     case ValueAdd:
726     case ArithAdd:
727         m_jit.addDouble(tmp2FPR, tmp1FPR);
728         break;
729             
730     case ArithSub:
731         m_jit.subDouble(tmp2FPR, tmp1FPR);
732         break;
733             
734     case ArithMul:
735         m_jit.mulDouble(tmp2FPR, tmp1FPR);
736         break;
737             
738     default:
739         ASSERT_NOT_REACHED();
740     }
741     
742     JITCompiler::Jump doneCaseConvertedToInt;
743     
744     if (op == ValueAdd) {
745         JITCompiler::JumpList failureCases;
746         m_jit.branchConvertDoubleToInt32(tmp1FPR, resultGPR, failureCases, tmp2FPR);
747         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, resultGPR);
748         
749         doneCaseConvertedToInt = m_jit.jump();
750         
751         failureCases.link(&m_jit);
752     }
753         
754     boxDouble(tmp1FPR, resultGPR);
755         
756     if (!notNumbers.empty()) {
757         ASSERT(op == ValueAdd);
758             
759         JITCompiler::Jump doneCaseWasNumber = m_jit.jump();
760             
761         notNumbers.link(&m_jit);
762             
763         silentSpillAllRegisters(resultGPR);
764         callOperation(operationValueAddNotNumber, resultGPR, arg1GPR, arg2GPR);
765         silentFillAllRegisters(resultGPR);
766
767         doneCaseWasNumber.link(&m_jit);
768     }
769     
770     done.link(&m_jit);
771     if (doneCaseConvertedToInt.isSet())
772         doneCaseConvertedToInt.link(&m_jit);
773         
774     jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
775 }
776
777 JITCompiler::Call SpeculativeJIT::cachedGetById(GPRReg baseGPR, GPRReg resultGPR, GPRReg scratchGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget)
778 {
779     JITCompiler::DataLabelPtr structureToCompare;
780     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
781     
782     m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
783     JITCompiler::DataLabelCompact loadWithPatch = m_jit.loadPtrWithCompactAddressOffsetPatch(JITCompiler::Address(resultGPR, 0), resultGPR);
784     
785     JITCompiler::Jump done = m_jit.jump();
786
787     structureCheck.link(&m_jit);
788     
789     if (slowPathTarget.isSet())
790         slowPathTarget.link(&m_jit);
791     
792     JITCompiler::Label slowCase = m_jit.label();
793
794     silentSpillAllRegisters(resultGPR);
795     JITCompiler::Call functionCall = callOperation(operationGetByIdOptimize, resultGPR, baseGPR, identifier(identifierNumber));
796     silentFillAllRegisters(resultGPR);
797     
798     done.link(&m_jit);
799     
800     JITCompiler::Label doneLabel = m_jit.label();
801
802     m_jit.addPropertyAccess(PropertyAccessRecord(structureToCompare, functionCall, structureCheck, loadWithPatch, slowCase, doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(resultGPR), safeCast<int8_t>(scratchGPR)));
803     
804     if (scratchGPR != resultGPR && scratchGPR != InvalidGPRReg)
805         unlock(scratchGPR);
806     
807     return functionCall;
808 }
809
810 void SpeculativeJIT::cachedPutById(GPRReg baseGPR, GPRReg valueGPR, NodeIndex valueIndex, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget)
811 {
812     
813     JITCompiler::DataLabelPtr structureToCompare;
814     JITCompiler::Jump structureCheck = m_jit.branchPtrWithPatch(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), structureToCompare, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(-1)));
815
816     writeBarrier(baseGPR, valueGPR, valueIndex, WriteBarrierForPropertyAccess, scratchGPR);
817
818     m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), scratchGPR);
819     JITCompiler::DataLabel32 storeWithPatch = m_jit.storePtrWithAddressOffsetPatch(valueGPR, JITCompiler::Address(scratchGPR, 0));
820
821     JITCompiler::Jump done = m_jit.jump();
822
823     structureCheck.link(&m_jit);
824
825     if (slowPathTarget.isSet())
826         slowPathTarget.link(&m_jit);
827
828     JITCompiler::Label slowCase = m_jit.label();
829
830     silentSpillAllRegisters(InvalidGPRReg);
831     V_DFGOperation_EJCI optimizedCall;
832     if (m_jit.strictModeFor(at(m_compileIndex).codeOrigin)) {
833         if (putKind == Direct)
834             optimizedCall = operationPutByIdDirectStrictOptimize;
835         else
836             optimizedCall = operationPutByIdStrictOptimize;
837     } else {
838         if (putKind == Direct)
839             optimizedCall = operationPutByIdDirectNonStrictOptimize;
840         else
841             optimizedCall = operationPutByIdNonStrictOptimize;
842     }
843     JITCompiler::Call functionCall = callOperation(optimizedCall, valueGPR, baseGPR, identifier(identifierNumber));
844     silentFillAllRegisters(InvalidGPRReg);
845
846     done.link(&m_jit);
847     JITCompiler::Label doneLabel = m_jit.label();
848
849     m_jit.addPropertyAccess(PropertyAccessRecord(structureToCompare, functionCall, structureCheck, JITCompiler::DataLabelCompact(storeWithPatch.label()), slowCase, doneLabel, safeCast<int8_t>(baseGPR), safeCast<int8_t>(valueGPR), safeCast<int8_t>(scratchGPR)));
850 }
851
852 void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(NodeIndex operand, bool invert)
853 {
854     JSValueOperand arg(this, operand);
855     GPRReg argGPR = arg.gpr();
856     
857     GPRTemporary result(this, arg);
858     GPRReg resultGPR = result.gpr();
859     
860     JITCompiler::Jump notCell;
861     
862     if (!isKnownCell(operand))
863         notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
864     
865     m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
866     m_jit.test8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined), resultGPR);
867     
868     if (!isKnownCell(operand)) {
869         JITCompiler::Jump done = m_jit.jump();
870         
871         notCell.link(&m_jit);
872         
873         m_jit.move(argGPR, resultGPR);
874         m_jit.andPtr(JITCompiler::TrustedImm32(~TagBitUndefined), resultGPR);
875         m_jit.comparePtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImm32(ValueNull), resultGPR);
876         
877         done.link(&m_jit);
878     }
879     
880     m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
881     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
882 }
883
884 void SpeculativeJIT::nonSpeculativePeepholeBranchNull(NodeIndex operand, NodeIndex branchNodeIndex, bool invert)
885 {
886     Node& branchNode = at(branchNodeIndex);
887     BlockIndex taken = branchNode.takenBlockIndex();
888     BlockIndex notTaken = branchNode.notTakenBlockIndex();
889     
890     if (taken == (m_block + 1)) {
891         invert = !invert;
892         BlockIndex tmp = taken;
893         taken = notTaken;
894         notTaken = tmp;
895     }
896
897     JSValueOperand arg(this, operand);
898     GPRReg argGPR = arg.gpr();
899     
900     GPRTemporary result(this, arg);
901     GPRReg resultGPR = result.gpr();
902     
903     JITCompiler::Jump notCell;
904     
905     if (!isKnownCell(operand))
906         notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, argGPR, GPRInfo::tagMaskRegister);
907     
908     m_jit.loadPtr(JITCompiler::Address(argGPR, JSCell::structureOffset()), resultGPR);
909     addBranch(m_jit.branchTest8(invert ? JITCompiler::Zero : JITCompiler::NonZero, JITCompiler::Address(resultGPR, Structure::typeInfoFlagsOffset()), JITCompiler::TrustedImm32(MasqueradesAsUndefined)), taken);
910     
911     if (!isKnownCell(operand)) {
912         addBranch(m_jit.jump(), notTaken);
913         
914         notCell.link(&m_jit);
915         
916         m_jit.move(argGPR, resultGPR);
917         m_jit.andPtr(JITCompiler::TrustedImm32(~TagBitUndefined), resultGPR);
918         addBranch(m_jit.branchPtr(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))), taken);
919     }
920     
921     if (notTaken != (m_block + 1))
922         addBranch(m_jit.jump(), notTaken);
923 }
924
925 bool SpeculativeJIT::nonSpeculativeCompareNull(Node& node, NodeIndex operand, bool invert)
926 {
927     NodeIndex branchNodeIndex = detectPeepHoleBranch();
928     if (branchNodeIndex != NoNode) {
929         ASSERT(node.adjustedRefCount() == 1);
930         
931         nonSpeculativePeepholeBranchNull(operand, branchNodeIndex, invert);
932     
933         use(node.child1());
934         use(node.child2());
935         m_compileIndex = branchNodeIndex;
936         
937         return true;
938     }
939     
940     nonSpeculativeNonPeepholeCompareNull(operand, invert);
941     
942     return false;
943 }
944
945 void SpeculativeJIT::nonSpeculativePeepholeBranch(Node& node, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
946 {
947     Node& branchNode = at(branchNodeIndex);
948     BlockIndex taken = branchNode.takenBlockIndex();
949     BlockIndex notTaken = branchNode.notTakenBlockIndex();
950
951     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
952
953     // The branch instruction will branch to the taken block.
954     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
955     if (taken == (m_block + 1)) {
956         cond = JITCompiler::invert(cond);
957         callResultCondition = JITCompiler::Zero;
958         BlockIndex tmp = taken;
959         taken = notTaken;
960         notTaken = tmp;
961     }
962
963     JSValueOperand arg1(this, node.child1());
964     JSValueOperand arg2(this, node.child2());
965     GPRReg arg1GPR = arg1.gpr();
966     GPRReg arg2GPR = arg2.gpr();
967     
968     JITCompiler::JumpList slowPath;
969     
970     if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
971         GPRResult result(this);
972         GPRReg resultGPR = result.gpr();
973     
974         arg1.use();
975         arg2.use();
976     
977         flushRegisters();
978         callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
979
980         addBranch(m_jit.branchTest32(callResultCondition, resultGPR), taken);
981     } else {
982         GPRTemporary result(this, arg2);
983         GPRReg resultGPR = result.gpr();
984     
985         arg1.use();
986         arg2.use();
987     
988         if (!isKnownInteger(node.child1()))
989             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
990         if (!isKnownInteger(node.child2()))
991             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
992     
993         addBranch(m_jit.branch32(cond, arg1GPR, arg2GPR), taken);
994     
995         if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
996             addBranch(m_jit.jump(), notTaken);
997     
998             slowPath.link(&m_jit);
999     
1000             silentSpillAllRegisters(resultGPR);
1001             callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
1002             silentFillAllRegisters(resultGPR);
1003         
1004             addBranch(m_jit.branchTest32(callResultCondition, resultGPR), taken);
1005         }
1006     }
1007
1008     if (notTaken != (m_block + 1))
1009         addBranch(m_jit.jump(), notTaken);
1010 }
1011
1012 void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node& node, MacroAssembler::RelationalCondition cond, S_DFGOperation_EJJ helperFunction)
1013 {
1014     JSValueOperand arg1(this, node.child1());
1015     JSValueOperand arg2(this, node.child2());
1016     GPRReg arg1GPR = arg1.gpr();
1017     GPRReg arg2GPR = arg2.gpr();
1018     
1019     JITCompiler::JumpList slowPath;
1020     
1021     if (isKnownNotInteger(node.child1()) || isKnownNotInteger(node.child2())) {
1022         GPRResult result(this);
1023         GPRReg resultGPR = result.gpr();
1024     
1025         arg1.use();
1026         arg2.use();
1027     
1028         flushRegisters();
1029         callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
1030         
1031         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
1032         jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
1033     } else {
1034         GPRTemporary result(this, arg2);
1035         GPRReg resultGPR = result.gpr();
1036
1037         arg1.use();
1038         arg2.use();
1039     
1040         if (!isKnownInteger(node.child1()))
1041             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg1GPR, GPRInfo::tagTypeNumberRegister));
1042         if (!isKnownInteger(node.child2()))
1043             slowPath.append(m_jit.branchPtr(MacroAssembler::Below, arg2GPR, GPRInfo::tagTypeNumberRegister));
1044     
1045         m_jit.compare32(cond, arg1GPR, arg2GPR, resultGPR);
1046     
1047         if (!isKnownInteger(node.child1()) || !isKnownInteger(node.child2())) {
1048             JITCompiler::Jump haveResult = m_jit.jump();
1049     
1050             slowPath.link(&m_jit);
1051         
1052             silentSpillAllRegisters(resultGPR);
1053             callOperation(helperFunction, resultGPR, arg1GPR, arg2GPR);
1054             silentFillAllRegisters(resultGPR);
1055         
1056             m_jit.andPtr(TrustedImm32(1), resultGPR);
1057         
1058             haveResult.link(&m_jit);
1059         }
1060         
1061         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
1062         
1063         jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
1064     }
1065 }
1066
1067 void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node& node, NodeIndex branchNodeIndex, bool invert)
1068 {
1069     Node& branchNode = at(branchNodeIndex);
1070     BlockIndex taken = branchNode.takenBlockIndex();
1071     BlockIndex notTaken = branchNode.notTakenBlockIndex();
1072
1073     // The branch instruction will branch to the taken block.
1074     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
1075     if (taken == (m_block + 1)) {
1076         invert = !invert;
1077         BlockIndex tmp = taken;
1078         taken = notTaken;
1079         notTaken = tmp;
1080     }
1081     
1082     JSValueOperand arg1(this, node.child1());
1083     JSValueOperand arg2(this, node.child2());
1084     GPRReg arg1GPR = arg1.gpr();
1085     GPRReg arg2GPR = arg2.gpr();
1086     
1087     GPRTemporary result(this);
1088     GPRReg resultGPR = result.gpr();
1089     
1090     arg1.use();
1091     arg2.use();
1092     
1093     if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
1094         // see if we get lucky: if the arguments are cells and they reference the same
1095         // cell, then they must be strictly equal.
1096         addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken);
1097         
1098         silentSpillAllRegisters(resultGPR);
1099         callOperation(operationCompareStrictEqCell, resultGPR, arg1GPR, arg2GPR);
1100         silentFillAllRegisters(resultGPR);
1101         
1102         addBranch(m_jit.branchTest32(invert ? JITCompiler::NonZero : JITCompiler::Zero, resultGPR), taken);
1103     } else {
1104         m_jit.orPtr(arg1GPR, arg2GPR, resultGPR);
1105         
1106         JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
1107         
1108         JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
1109         
1110         addBranch(m_jit.branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR), taken);
1111         addBranch(m_jit.jump(), notTaken);
1112         
1113         twoCellsCase.link(&m_jit);
1114         addBranch(m_jit.branchPtr(JITCompiler::Equal, arg1GPR, arg2GPR), invert ? notTaken : taken);
1115         
1116         numberCase.link(&m_jit);
1117         
1118         silentSpillAllRegisters(resultGPR);
1119         callOperation(operationCompareStrictEq, resultGPR, arg1GPR, arg2GPR);
1120         silentFillAllRegisters(resultGPR);
1121         
1122         addBranch(m_jit.branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, resultGPR), taken);
1123     }
1124     
1125     if (notTaken != (m_block + 1))
1126         addBranch(m_jit.jump(), notTaken);
1127 }
1128
1129 void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node& node, bool invert)
1130 {
1131     JSValueOperand arg1(this, node.child1());
1132     JSValueOperand arg2(this, node.child2());
1133     GPRReg arg1GPR = arg1.gpr();
1134     GPRReg arg2GPR = arg2.gpr();
1135     
1136     GPRTemporary result(this);
1137     GPRReg resultGPR = result.gpr();
1138     
1139     arg1.use();
1140     arg2.use();
1141     
1142     if (isKnownCell(node.child1()) && isKnownCell(node.child2())) {
1143         // see if we get lucky: if the arguments are cells and they reference the same
1144         // cell, then they must be strictly equal.
1145         JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR);
1146         
1147         m_jit.move(JITCompiler::TrustedImmPtr(JSValue::encode(jsBoolean(!invert))), resultGPR);
1148         
1149         JITCompiler::Jump done = m_jit.jump();
1150
1151         notEqualCase.link(&m_jit);
1152         
1153         silentSpillAllRegisters(resultGPR);
1154         callOperation(operationCompareStrictEqCell, resultGPR, arg1GPR, arg2GPR);
1155         silentFillAllRegisters(resultGPR);
1156         
1157         m_jit.andPtr(JITCompiler::TrustedImm32(1), resultGPR);
1158         m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR);
1159         
1160         done.link(&m_jit);
1161     } else {
1162         m_jit.orPtr(arg1GPR, arg2GPR, resultGPR);
1163         
1164         JITCompiler::Jump twoCellsCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
1165         
1166         JITCompiler::Jump numberCase = m_jit.branchTestPtr(JITCompiler::NonZero, resultGPR, GPRInfo::tagTypeNumberRegister);
1167         
1168         m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, arg1GPR, arg2GPR, resultGPR);
1169         
1170         JITCompiler::Jump done1 = m_jit.jump();
1171         
1172         twoCellsCase.link(&m_jit);
1173         JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1GPR, arg2GPR);
1174         
1175         m_jit.move(JITCompiler::TrustedImmPtr(JSValue::encode(jsBoolean(!invert))), resultGPR);
1176         
1177         JITCompiler::Jump done2 = m_jit.jump();
1178         
1179         numberCase.link(&m_jit);
1180         notEqualCase.link(&m_jit);
1181         
1182         silentSpillAllRegisters(resultGPR);
1183         callOperation(operationCompareStrictEq, resultGPR, arg1GPR, arg2GPR);
1184         silentFillAllRegisters(resultGPR);
1185         
1186         m_jit.andPtr(JITCompiler::TrustedImm32(1), resultGPR);
1187
1188         done1.link(&m_jit);
1189
1190         m_jit.or32(JITCompiler::TrustedImm32(ValueFalse), resultGPR);
1191         
1192         done2.link(&m_jit);
1193     }
1194     
1195     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
1196 }
1197
1198 void SpeculativeJIT::emitCall(Node& node)
1199 {
1200     P_DFGOperation_E slowCallFunction;
1201
1202     if (node.op == Call)
1203         slowCallFunction = operationLinkCall;
1204     else {
1205         ASSERT(node.op == Construct);
1206         slowCallFunction = operationLinkConstruct;
1207     }
1208
1209     // For constructors, the this argument is not passed but we have to make space
1210     // for it.
1211     int dummyThisArgument = node.op == Call ? 0 : 1;
1212     
1213     CallLinkInfo::CallType callType = node.op == Call ? CallLinkInfo::Call : CallLinkInfo::Construct;
1214     
1215     NodeIndex calleeNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild()];
1216     JSValueOperand callee(this, calleeNodeIndex);
1217     GPRReg calleeGPR = callee.gpr();
1218     use(calleeNodeIndex);
1219     
1220     // the call instruction's first child is either the function (normal call) or the
1221     // receiver (method call). subsequent children are the arguments.
1222     int numArgs = node.numChildren() - 1;
1223     
1224     int numPassedArgs = numArgs + dummyThisArgument;
1225     
1226     // amount of stuff (in units of sizeof(Register)) that we need to place at the
1227     // top of the JS stack.
1228     int callDataSize = 0;
1229
1230     // first there are the arguments
1231     callDataSize += numPassedArgs;
1232     
1233     // and then there is the call frame header
1234     callDataSize += RegisterFile::CallFrameHeaderSize;
1235     
1236     m_jit.storePtr(MacroAssembler::TrustedImmPtr(JSValue::encode(jsNumber(numPassedArgs))), addressOfCallData(RegisterFile::ArgumentCount));
1237     m_jit.storePtr(GPRInfo::callFrameRegister, addressOfCallData(RegisterFile::CallerFrame));
1238     
1239     for (int argIdx = 0; argIdx < numArgs; argIdx++) {
1240         NodeIndex argNodeIndex = m_jit.graph().m_varArgChildren[node.firstChild() + 1 + argIdx];
1241         JSValueOperand arg(this, argNodeIndex);
1242         GPRReg argGPR = arg.gpr();
1243         use(argNodeIndex);
1244         
1245         m_jit.storePtr(argGPR, addressOfCallData(-callDataSize + argIdx + dummyThisArgument));
1246     }
1247     
1248     m_jit.storePtr(calleeGPR, addressOfCallData(RegisterFile::Callee));
1249     
1250     flushRegisters();
1251     
1252     GPRResult result(this);
1253     GPRReg resultGPR = result.gpr();
1254
1255     JITCompiler::DataLabelPtr targetToCheck;
1256     JITCompiler::Jump slowPath;
1257     
1258     slowPath = m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleeGPR, targetToCheck, MacroAssembler::TrustedImmPtr(JSValue::encode(JSValue())));
1259     m_jit.loadPtr(MacroAssembler::Address(calleeGPR, OBJECT_OFFSETOF(JSFunction, m_scopeChain)), resultGPR);
1260     m_jit.storePtr(resultGPR, addressOfCallData(RegisterFile::ScopeChain));
1261
1262     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
1263     
1264     JITCompiler::Call fastCall = m_jit.nearCall();
1265     m_jit.notifyCall(fastCall, at(m_compileIndex).codeOrigin);
1266     
1267     JITCompiler::Jump done = m_jit.jump();
1268     
1269     slowPath.link(&m_jit);
1270     
1271     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1272     JITCompiler::Call slowCall = m_jit.addFastExceptionCheck(m_jit.appendCall(slowCallFunction), at(m_compileIndex).codeOrigin);
1273     m_jit.addPtr(Imm32(m_jit.codeBlock()->m_numCalleeRegisters * sizeof(Register)), GPRInfo::callFrameRegister);
1274     m_jit.notifyCall(m_jit.call(GPRInfo::returnValueGPR), at(m_compileIndex).codeOrigin);
1275     
1276     done.link(&m_jit);
1277     
1278     m_jit.move(GPRInfo::returnValueGPR, resultGPR);
1279     
1280     jsValueResult(resultGPR, m_compileIndex, DataFormatJS, UseChildrenCalledExplicitly);
1281     
1282     m_jit.addJSCall(fastCall, slowCall, targetToCheck, callType, at(m_compileIndex).codeOrigin);
1283 }
1284
1285 template<bool strict>
1286 GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat)
1287 {
1288 #if DFG_ENABLE(DEBUG_VERBOSE)
1289     fprintf(stderr, "SpecInt@%d   ", nodeIndex);
1290 #endif
1291     Node& node = at(nodeIndex);
1292     VirtualRegister virtualRegister = node.virtualRegister();
1293     GenerationInfo& info = m_generationInfo[virtualRegister];
1294
1295     switch (info.registerFormat()) {
1296     case DataFormatNone: {
1297         if ((node.hasConstant() && !isInt32Constant(nodeIndex)) || info.spillFormat() == DataFormatDouble) {
1298             terminateSpeculativeExecution(JSValueRegs(), NoNode);
1299             returnFormat = DataFormatInteger;
1300             return allocate();
1301         }
1302         
1303         GPRReg gpr = allocate();
1304
1305         if (node.hasConstant()) {
1306             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1307             ASSERT(isInt32Constant(nodeIndex));
1308             m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
1309             info.fillInteger(gpr);
1310             returnFormat = DataFormatInteger;
1311             return gpr;
1312         }
1313         
1314         DataFormat spillFormat = info.spillFormat();
1315         
1316         ASSERT((spillFormat & DataFormatJS) || spillFormat == DataFormatInteger);
1317         
1318         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1319         
1320         if (spillFormat == DataFormatJSInteger || spillFormat == DataFormatInteger) {
1321             // If we know this was spilled as an integer we can fill without checking.
1322             if (strict) {
1323                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
1324                 info.fillInteger(gpr);
1325                 returnFormat = DataFormatInteger;
1326                 return gpr;
1327             }
1328             if (spillFormat == DataFormatInteger) {
1329                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
1330                 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr);
1331             } else
1332                 m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
1333             info.fillJSValue(gpr, DataFormatJSInteger);
1334             returnFormat = DataFormatJSInteger;
1335             return gpr;
1336         }
1337         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
1338
1339         // Fill as JSValue, and fall through.
1340         info.fillJSValue(gpr, DataFormatJSInteger);
1341         m_gprs.unlock(gpr);
1342     }
1343
1344     case DataFormatJS: {
1345         // Check the value is an integer.
1346         GPRReg gpr = info.gpr();
1347         m_gprs.lock(gpr);
1348         speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchPtr(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister));
1349         info.fillJSValue(gpr, DataFormatJSInteger);
1350         // If !strict we're done, return.
1351         if (!strict) {
1352             returnFormat = DataFormatJSInteger;
1353             return gpr;
1354         }
1355         // else fall through & handle as DataFormatJSInteger.
1356         m_gprs.unlock(gpr);
1357     }
1358
1359     case DataFormatJSInteger: {
1360         // In a strict fill we need to strip off the value tag.
1361         if (strict) {
1362             GPRReg gpr = info.gpr();
1363             GPRReg result;
1364             // If the register has already been locked we need to take a copy.
1365             // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
1366             if (m_gprs.isLocked(gpr))
1367                 result = allocate();
1368             else {
1369                 m_gprs.lock(gpr);
1370                 info.fillInteger(gpr);
1371                 result = gpr;
1372             }
1373             m_jit.zeroExtend32ToPtr(gpr, result);
1374             returnFormat = DataFormatInteger;
1375             return result;
1376         }
1377
1378         GPRReg gpr = info.gpr();
1379         m_gprs.lock(gpr);
1380         returnFormat = DataFormatJSInteger;
1381         return gpr;
1382     }
1383
1384     case DataFormatInteger: {
1385         GPRReg gpr = info.gpr();
1386         m_gprs.lock(gpr);
1387         returnFormat = DataFormatInteger;
1388         return gpr;
1389     }
1390
1391     case DataFormatDouble:
1392     case DataFormatCell:
1393     case DataFormatBoolean:
1394     case DataFormatJSDouble:
1395     case DataFormatJSCell:
1396     case DataFormatJSBoolean: {
1397         terminateSpeculativeExecution(JSValueRegs(), NoNode);
1398         returnFormat = DataFormatInteger;
1399         return allocate();
1400     }
1401
1402     case DataFormatStorage:
1403         ASSERT_NOT_REACHED();
1404     }
1405
1406     ASSERT_NOT_REACHED();
1407     return InvalidGPRReg;
1408 }
1409
1410 GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat)
1411 {
1412     return fillSpeculateIntInternal<false>(nodeIndex, returnFormat);
1413 }
1414
1415 GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
1416 {
1417     DataFormat mustBeDataFormatInteger;
1418     GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger);
1419     ASSERT(mustBeDataFormatInteger == DataFormatInteger);
1420     return result;
1421 }
1422
1423 FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex)
1424 {
1425 #if DFG_ENABLE(DEBUG_VERBOSE)
1426     fprintf(stderr, "SpecDouble@%d   ", nodeIndex);
1427 #endif
1428     Node& node = at(nodeIndex);
1429     VirtualRegister virtualRegister = node.virtualRegister();
1430     GenerationInfo& info = m_generationInfo[virtualRegister];
1431
1432     if (info.registerFormat() == DataFormatNone) {
1433         if (node.hasConstant()) {
1434             GPRReg gpr = allocate();
1435
1436             if (isInt32Constant(nodeIndex)) {
1437                 FPRReg fpr = fprAllocate();
1438                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(static_cast<double>(valueOfInt32Constant(nodeIndex))))), gpr);
1439                 m_jit.movePtrToDouble(gpr, fpr);
1440                 unlock(gpr);
1441
1442                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1443                 info.fillDouble(fpr);
1444                 return fpr;
1445             }
1446             if (isNumberConstant(nodeIndex)) {
1447                 FPRReg fpr = fprAllocate();
1448                 m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfNumberConstant(nodeIndex)))), gpr);
1449                 m_jit.movePtrToDouble(gpr, fpr);
1450                 unlock(gpr);
1451
1452                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1453                 info.fillDouble(fpr);
1454                 return fpr;
1455             }
1456             terminateSpeculativeExecution(JSValueRegs(), NoNode);
1457             return fprAllocate();
1458         }
1459         
1460         DataFormat spillFormat = info.spillFormat();
1461         switch (spillFormat) {
1462         case DataFormatDouble: {
1463             FPRReg fpr = fprAllocate();
1464             m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
1465             m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1466             info.fillDouble(fpr);
1467             return fpr;
1468         }
1469             
1470         case DataFormatInteger: {
1471             GPRReg gpr = allocate();
1472             
1473             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1474             m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
1475             info.fillInteger(gpr);
1476             unlock(gpr);
1477             break;
1478         }
1479
1480         default:
1481             GPRReg gpr = allocate();
1482
1483             ASSERT(spillFormat & DataFormatJS);
1484             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1485             m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
1486             info.fillJSValue(gpr, spillFormat);
1487             unlock(gpr);
1488             break;
1489         }
1490     }
1491
1492     switch (info.registerFormat()) {
1493     case DataFormatNone: // Should have filled, above.
1494     case DataFormatBoolean: // This type never occurs.
1495     case DataFormatStorage:
1496         ASSERT_NOT_REACHED();
1497
1498     case DataFormatCell:
1499         terminateSpeculativeExecution(JSValueRegs(), NoNode);
1500         return fprAllocate();
1501
1502     case DataFormatJSCell:
1503     case DataFormatJS:
1504     case DataFormatJSBoolean: {
1505         GPRReg jsValueGpr = info.gpr();
1506         m_gprs.lock(jsValueGpr);
1507         FPRReg fpr = fprAllocate();
1508         GPRReg tempGpr = allocate();
1509
1510         JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
1511
1512         speculationCheck(JSValueRegs(jsValueGpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::Zero, jsValueGpr, GPRInfo::tagTypeNumberRegister));
1513
1514         // First, if we get here we have a double encoded as a JSValue
1515         m_jit.move(jsValueGpr, tempGpr);
1516         unboxDouble(tempGpr, fpr);
1517         JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
1518
1519         // Finally, handle integers.
1520         isInteger.link(&m_jit);
1521         m_jit.convertInt32ToDouble(jsValueGpr, fpr);
1522         hasUnboxedDouble.link(&m_jit);
1523
1524         m_gprs.release(jsValueGpr);
1525         m_gprs.unlock(jsValueGpr);
1526         m_gprs.unlock(tempGpr);
1527         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1528         info.fillDouble(fpr);
1529         info.killSpilled();
1530         return fpr;
1531     }
1532
1533     case DataFormatJSInteger:
1534     case DataFormatInteger: {
1535         FPRReg fpr = fprAllocate();
1536         GPRReg gpr = info.gpr();
1537         m_gprs.lock(gpr);
1538         m_jit.convertInt32ToDouble(gpr, fpr);
1539         m_gprs.unlock(gpr);
1540         return fpr;
1541     }
1542
1543     // Unbox the double
1544     case DataFormatJSDouble: {
1545         GPRReg gpr = info.gpr();
1546         FPRReg fpr = fprAllocate();
1547         if (m_gprs.isLocked(gpr)) {
1548             // Make sure we don't trample gpr if it is in use.
1549             GPRReg temp = allocate();
1550             m_jit.move(gpr, temp);
1551             unboxDouble(temp, fpr);
1552             unlock(temp);
1553         } else
1554             unboxDouble(gpr, fpr);
1555
1556         m_gprs.release(gpr);
1557         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1558
1559         info.fillDouble(fpr);
1560         return fpr;
1561     }
1562
1563     case DataFormatDouble: {
1564         FPRReg fpr = info.fpr();
1565         m_fprs.lock(fpr);
1566         return fpr;
1567     }
1568     }
1569
1570     ASSERT_NOT_REACHED();
1571     return InvalidFPRReg;
1572 }
1573
1574 GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
1575 {
1576 #if DFG_ENABLE(DEBUG_VERBOSE)
1577     fprintf(stderr, "SpecCell@%d   ", nodeIndex);
1578 #endif
1579     Node& node = at(nodeIndex);
1580     VirtualRegister virtualRegister = node.virtualRegister();
1581     GenerationInfo& info = m_generationInfo[virtualRegister];
1582
1583     switch (info.registerFormat()) {
1584     case DataFormatNone: {
1585         if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) {
1586             terminateSpeculativeExecution(JSValueRegs(), NoNode);
1587             return allocate();
1588         }
1589         
1590         GPRReg gpr = allocate();
1591
1592         if (node.hasConstant()) {
1593             JSValue jsValue = valueOfJSConstant(nodeIndex);
1594             if (jsValue.isCell()) {
1595                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1596                 m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
1597                 info.fillJSValue(gpr, DataFormatJSCell);
1598                 return gpr;
1599             }
1600             terminateSpeculativeExecution(JSValueRegs(), NoNode);
1601             return gpr;
1602         }
1603         ASSERT(info.spillFormat() & DataFormatJS);
1604         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1605         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
1606
1607         info.fillJSValue(gpr, DataFormatJS);
1608         if (info.spillFormat() != DataFormatJSCell)
1609             speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
1610         info.fillJSValue(gpr, DataFormatJSCell);
1611         return gpr;
1612     }
1613
1614     case DataFormatCell:
1615     case DataFormatJSCell: {
1616         GPRReg gpr = info.gpr();
1617         m_gprs.lock(gpr);
1618         return gpr;
1619     }
1620
1621     case DataFormatJS: {
1622         GPRReg gpr = info.gpr();
1623         m_gprs.lock(gpr);
1624         speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, GPRInfo::tagMaskRegister));
1625         info.fillJSValue(gpr, DataFormatJSCell);
1626         return gpr;
1627     }
1628
1629     case DataFormatJSInteger:
1630     case DataFormatInteger:
1631     case DataFormatJSDouble:
1632     case DataFormatDouble:
1633     case DataFormatJSBoolean:
1634     case DataFormatBoolean: {
1635         terminateSpeculativeExecution(JSValueRegs(), NoNode);
1636         return allocate();
1637     }
1638
1639     case DataFormatStorage:
1640         ASSERT_NOT_REACHED();
1641     }
1642
1643     ASSERT_NOT_REACHED();
1644     return InvalidGPRReg;
1645 }
1646
1647 GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex)
1648 {
1649 #if DFG_ENABLE(DEBUG_VERBOSE)
1650     fprintf(stderr, "SpecBool@%d   ", nodeIndex);
1651 #endif
1652     Node& node = at(nodeIndex);
1653     VirtualRegister virtualRegister = node.virtualRegister();
1654     GenerationInfo& info = m_generationInfo[virtualRegister];
1655
1656     switch (info.registerFormat()) {
1657     case DataFormatNone: {
1658         if (info.spillFormat() == DataFormatInteger || info.spillFormat() == DataFormatDouble) {
1659             terminateSpeculativeExecution(JSValueRegs(), NoNode);
1660             return allocate();
1661         }
1662         
1663         GPRReg gpr = allocate();
1664
1665         if (node.hasConstant()) {
1666             JSValue jsValue = valueOfJSConstant(nodeIndex);
1667             if (jsValue.isBoolean()) {
1668                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1669                 m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsValue)), gpr);
1670                 info.fillJSValue(gpr, DataFormatJSBoolean);
1671                 return gpr;
1672             }
1673             terminateSpeculativeExecution(JSValueRegs(), NoNode);
1674             return gpr;
1675         }
1676         ASSERT(info.spillFormat() & DataFormatJS);
1677         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1678         m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
1679
1680         info.fillJSValue(gpr, DataFormatJS);
1681         if (info.spillFormat() != DataFormatJSBoolean) {
1682             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1683             speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
1684             m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1685         }
1686         info.fillJSValue(gpr, DataFormatJSBoolean);
1687         return gpr;
1688     }
1689
1690     case DataFormatBoolean:
1691     case DataFormatJSBoolean: {
1692         GPRReg gpr = info.gpr();
1693         m_gprs.lock(gpr);
1694         return gpr;
1695     }
1696
1697     case DataFormatJS: {
1698         GPRReg gpr = info.gpr();
1699         m_gprs.lock(gpr);
1700         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1701         speculationCheck(JSValueRegs(gpr), nodeIndex, m_jit.branchTestPtr(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
1702         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1703         info.fillJSValue(gpr, DataFormatJSBoolean);
1704         return gpr;
1705     }
1706
1707     case DataFormatJSInteger:
1708     case DataFormatInteger:
1709     case DataFormatJSDouble:
1710     case DataFormatDouble:
1711     case DataFormatJSCell:
1712     case DataFormatCell: {
1713         terminateSpeculativeExecution(JSValueRegs(), NoNode);
1714         return allocate();
1715     }
1716         
1717     case DataFormatStorage:
1718         ASSERT_NOT_REACHED();
1719     }
1720
1721     ASSERT_NOT_REACHED();
1722     return InvalidGPRReg;
1723 }
1724
1725 JITCompiler::Jump SpeculativeJIT::convertToDouble(GPRReg value, FPRReg result, GPRReg tmp)
1726 {
1727     JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, value, GPRInfo::tagTypeNumberRegister);
1728     
1729     JITCompiler::Jump notNumber = m_jit.branchTestPtr(MacroAssembler::Zero, value, GPRInfo::tagTypeNumberRegister);
1730     
1731     m_jit.move(value, tmp);
1732     unboxDouble(tmp, result);
1733     
1734     JITCompiler::Jump done = m_jit.jump();
1735     
1736     isInteger.link(&m_jit);
1737     
1738     m_jit.convertInt32ToDouble(value, result);
1739     
1740     done.link(&m_jit);
1741
1742     return notNumber;
1743 }
1744
1745 void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr, PredictionChecker predictionCheck)
1746 {
1747     SpeculateCellOperand op1(this, node.child1());
1748     SpeculateCellOperand op2(this, node.child2());
1749     GPRTemporary result(this, op1);
1750     
1751     GPRReg op1GPR = op1.gpr();
1752     GPRReg op2GPR = op2.gpr();
1753     GPRReg resultGPR = result.gpr();
1754     
1755     if (!predictionCheck(m_state.forNode(node.child1()).m_type))
1756         speculationCheck(JSValueRegs(op1GPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
1757     if (!predictionCheck(m_state.forNode(node.child2()).m_type))
1758         speculationCheck(JSValueRegs(op2GPR), node.child2(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
1759     
1760     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
1761     m_jit.move(Imm32(ValueTrue), resultGPR);
1762     MacroAssembler::Jump done = m_jit.jump();
1763     falseCase.link(&m_jit);
1764     m_jit.move(Imm32(ValueFalse), resultGPR);
1765     done.link(&m_jit);
1766
1767     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
1768 }
1769
1770 // Returns true if the compare is fused with a subsequent branch.
1771 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, S_DFGOperation_EJJ operation)
1772 {
1773     if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
1774         return true;
1775
1776     if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2()))) {
1777         SpeculateIntegerOperand op1(this, node.child1());
1778         SpeculateIntegerOperand op2(this, node.child2());
1779         GPRTemporary result(this, op1, op2);
1780         
1781         m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
1782         
1783         // If we add a DataFormatBool, we should use it here.
1784         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1785         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1786     } else if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
1787         SpeculateDoubleOperand op1(this, node.child1());
1788         SpeculateDoubleOperand op2(this, node.child2());
1789         GPRTemporary result(this);
1790         
1791         m_jit.move(TrustedImm32(ValueTrue), result.gpr());
1792         MacroAssembler::Jump trueCase = m_jit.branchDouble(doubleCondition, op1.fpr(), op2.fpr());
1793         m_jit.xorPtr(Imm32(true), result.gpr());
1794         trueCase.link(&m_jit);
1795
1796         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1797     } else if (node.op == CompareEq && Node::shouldSpeculateFinalObject(at(node.child1()), at(node.child2())))
1798         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr, isFinalObjectPrediction);
1799     else if (node.op == CompareEq && Node::shouldSpeculateArray(at(node.child1()), at(node.child2())))
1800         compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr, isArrayPrediction);
1801     else
1802         nonSpeculativeNonPeepholeCompare(node, condition, operation);
1803     
1804     return false;
1805 }
1806
1807 void SpeculativeJIT::compileValueAdd(Node& node)
1808 {
1809     JSValueOperand op1(this, node.child1());
1810     JSValueOperand op2(this, node.child2());
1811     
1812     GPRReg op1GPR = op1.gpr();
1813     GPRReg op2GPR = op2.gpr();
1814     
1815     flushRegisters();
1816     
1817     GPRResult result(this);
1818     if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
1819         callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
1820     else
1821         callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
1822     
1823     jsValueResult(result.gpr(), m_compileIndex);
1824 }
1825
1826 void SpeculativeJIT::compileObjectOrOtherLogicalNot(NodeIndex nodeIndex, void *vptr, bool needSpeculationCheck)
1827 {
1828     JSValueOperand value(this, nodeIndex);
1829     GPRTemporary result(this);
1830     GPRReg valueGPR = value.gpr();
1831     GPRReg resultGPR = result.gpr();
1832     
1833     MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
1834     if (needSpeculationCheck)
1835         speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr)));
1836     m_jit.move(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
1837     MacroAssembler::Jump done = m_jit.jump();
1838     
1839     notCell.link(&m_jit);
1840     
1841     if (needSpeculationCheck) {
1842         m_jit.move(valueGPR, resultGPR);
1843         m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
1844         speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, resultGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
1845     }
1846     m_jit.move(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
1847     
1848     done.link(&m_jit);
1849     
1850     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean);
1851 }
1852
1853 void SpeculativeJIT::compileLogicalNot(Node& node)
1854 {
1855     if (isKnownBoolean(node.child1())) {
1856         SpeculateBooleanOperand value(this, node.child1());
1857         GPRTemporary result(this, value);
1858         
1859         m_jit.move(value.gpr(), result.gpr());
1860         m_jit.xorPtr(TrustedImm32(true), result.gpr());
1861         
1862         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1863         return;
1864     }
1865     if (at(node.child1()).shouldSpeculateFinalObjectOrOther()) {
1866         compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsFinalObjectVPtr, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
1867         return;
1868     }
1869     if (at(node.child1()).shouldSpeculateArrayOrOther()) {
1870         compileObjectOrOtherLogicalNot(node.child1(), m_jit.globalData()->jsArrayVPtr, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
1871         return;
1872     }
1873     if (at(node.child1()).shouldSpeculateInteger()) {
1874         SpeculateIntegerOperand value(this, node.child1());
1875         GPRTemporary result(this, value);
1876         m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), result.gpr());
1877         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1878         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1879         return;
1880     }
1881     if (at(node.child1()).shouldSpeculateNumber()) {
1882         SpeculateDoubleOperand value(this, node.child1());
1883         FPRTemporary scratch(this);
1884         GPRTemporary result(this);
1885         m_jit.move(TrustedImm32(ValueFalse), result.gpr());
1886         MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
1887         m_jit.xor32(Imm32(true), result.gpr());
1888         nonZero.link(&m_jit);
1889         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1890         return;
1891     }
1892     
1893     PredictedType prediction = m_jit.getPrediction(node.child1());
1894     if (isBooleanPrediction(prediction) || !prediction) {
1895         JSValueOperand value(this, node.child1());
1896         GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
1897         
1898         m_jit.move(value.gpr(), result.gpr());
1899         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
1900         speculationCheck(JSValueRegs(value.gpr()), node.child1(), m_jit.branchTestPtr(JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1901         m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
1902         
1903         // If we add a DataFormatBool, we should use it here.
1904         jsValueResult(result.gpr(), m_compileIndex, DataFormatJSBoolean);
1905         return;
1906     }
1907     
1908     JSValueOperand arg1(this, node.child1());
1909     GPRTemporary result(this);
1910     
1911     GPRReg arg1GPR = arg1.gpr();
1912     GPRReg resultGPR = result.gpr();
1913     
1914     arg1.use();
1915     
1916     m_jit.move(arg1GPR, resultGPR);
1917     m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
1918     JITCompiler::Jump fastCase = m_jit.branchTestPtr(JITCompiler::Zero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
1919     
1920     silentSpillAllRegisters(resultGPR);
1921     callOperation(dfgConvertJSValueToBoolean, resultGPR, arg1GPR);
1922     silentFillAllRegisters(resultGPR);
1923     
1924     fastCase.link(&m_jit);
1925     
1926     m_jit.xorPtr(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
1927     jsValueResult(resultGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
1928 }
1929
1930 void SpeculativeJIT::emitObjectOrOtherBranch(NodeIndex nodeIndex, BlockIndex taken, BlockIndex notTaken, void *vptr, bool needSpeculationCheck)
1931 {
1932     JSValueOperand value(this, nodeIndex);
1933     GPRTemporary scratch(this);
1934     GPRReg valueGPR = value.gpr();
1935     GPRReg scratchGPR = scratch.gpr();
1936     
1937     MacroAssembler::Jump notCell = m_jit.branchTestPtr(MacroAssembler::NonZero, valueGPR, GPRInfo::tagMaskRegister);
1938     if (needSpeculationCheck)
1939         speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(valueGPR), MacroAssembler::TrustedImmPtr(vptr)));
1940     addBranch(m_jit.jump(), taken);
1941     
1942     notCell.link(&m_jit);
1943     
1944     if (needSpeculationCheck) {
1945         m_jit.move(valueGPR, scratchGPR);
1946         m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
1947         speculationCheck(JSValueRegs(valueGPR), nodeIndex, m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
1948     }
1949     if (notTaken != (m_block + 1))
1950         addBranch(m_jit.jump(), notTaken);
1951     
1952     noResult(m_compileIndex);
1953 }
1954
1955 void SpeculativeJIT::emitBranch(Node& node)
1956 {
1957     JSValueOperand value(this, node.child1());
1958     GPRReg valueGPR = value.gpr();
1959     
1960     BlockIndex taken = node.takenBlockIndex();
1961     BlockIndex notTaken = node.notTakenBlockIndex();
1962     
1963     if (isKnownBoolean(node.child1())) {
1964         MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1965         
1966         if (taken == (m_block + 1)) {
1967             condition = MacroAssembler::Zero;
1968             BlockIndex tmp = taken;
1969             taken = notTaken;
1970             notTaken = tmp;
1971         }
1972         
1973         addBranch(m_jit.branchTest32(condition, valueGPR, TrustedImm32(true)), taken);
1974         if (notTaken != (m_block + 1))
1975             addBranch(m_jit.jump(), notTaken);
1976         
1977         noResult(m_compileIndex);
1978     } else if (at(node.child1()).shouldSpeculateFinalObjectOrOther()) {
1979         emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsFinalObjectVPtr, !isFinalObjectOrOtherPrediction(m_state.forNode(node.child1()).m_type));
1980     } else if (at(node.child1()).shouldSpeculateArrayOrOther()) {
1981         emitObjectOrOtherBranch(node.child1(), taken, notTaken, m_jit.globalData()->jsArrayVPtr, !isArrayOrOtherPrediction(m_state.forNode(node.child1()).m_type));
1982     } else if (at(node.child1()).shouldSpeculateNumber()) {
1983         if (at(node.child1()).shouldSpeculateInteger()) {
1984             bool invert = false;
1985             
1986             if (taken == (m_block + 1)) {
1987                 invert = true;
1988                 BlockIndex tmp = taken;
1989                 taken = notTaken;
1990                 notTaken = tmp;
1991             }
1992
1993             SpeculateIntegerOperand value(this, node.child1());
1994             addBranch(m_jit.branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr()), taken);
1995         } else {
1996             SpeculateDoubleOperand value(this, node.child1());
1997             FPRTemporary scratch(this);
1998             addBranch(m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr()), taken);
1999         }
2000         
2001         if (notTaken != (m_block + 1))
2002             addBranch(m_jit.jump(), notTaken);
2003         
2004         noResult(m_compileIndex);
2005     } else {
2006         GPRTemporary result(this);
2007         GPRReg resultGPR = result.gpr();
2008         
2009         bool predictBoolean = isBooleanPrediction(m_jit.getPrediction(node.child1()));
2010     
2011         if (predictBoolean) {
2012             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
2013             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
2014
2015             speculationCheck(JSValueRegs(valueGPR), node.child1(), m_jit.jump());
2016             value.use();
2017         } else {
2018             addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsNumber(0)))), notTaken);
2019             addBranch(m_jit.branchPtr(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister), taken);
2020     
2021             if (!predictBoolean) {
2022                 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(false)))), notTaken);
2023                 addBranch(m_jit.branchPtr(MacroAssembler::Equal, valueGPR, MacroAssembler::ImmPtr(JSValue::encode(jsBoolean(true)))), taken);
2024             }
2025     
2026             value.use();
2027     
2028             silentSpillAllRegisters(resultGPR);
2029             callOperation(dfgConvertJSValueToBoolean, resultGPR, valueGPR);
2030             silentFillAllRegisters(resultGPR);
2031     
2032             addBranch(m_jit.branchTest32(MacroAssembler::NonZero, resultGPR), taken);
2033             if (notTaken != (m_block + 1))
2034                 addBranch(m_jit.jump(), notTaken);
2035         }
2036         
2037         noResult(m_compileIndex, UseChildrenCalledExplicitly);
2038     }
2039 }
2040
2041 void SpeculativeJIT::compile(Node& node)
2042 {
2043     NodeType op = node.op;
2044
2045     switch (op) {
2046     case JSConstant:
2047         initConstantInfo(m_compileIndex);
2048         break;
2049
2050     case WeakJSConstant:
2051         m_jit.addWeakReference(node.weakConstant());
2052         initConstantInfo(m_compileIndex);
2053         break;
2054
2055     case GetLocal: {
2056         PredictedType prediction = node.variableAccessData()->prediction();
2057         AbstractValue& value = block()->valuesAtHead.operand(node.local());
2058
2059         // If we have no prediction for this local, then don't attempt to compile.
2060         if (prediction == PredictNone || value.isClear()) {
2061             terminateSpeculativeExecution(JSValueRegs(), NoNode);
2062             break;
2063         }
2064         
2065         GPRTemporary result(this);
2066         if (isInt32Prediction(value.m_type)) {
2067             m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
2068
2069             // Like integerResult, but don't useChildren - our children are phi nodes,
2070             // and don't represent values within this dataflow with virtual registers.
2071             VirtualRegister virtualRegister = node.virtualRegister();
2072             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
2073             m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
2074             break;
2075         }
2076
2077         m_jit.loadPtr(JITCompiler::addressFor(node.local()), result.gpr());
2078
2079         // Like jsValueResult, but don't useChildren - our children are phi nodes,
2080         // and don't represent values within this dataflow with virtual registers.
2081         VirtualRegister virtualRegister = node.virtualRegister();
2082         m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
2083
2084         DataFormat format;
2085         if (isCellPrediction(value.m_type))
2086             format = DataFormatJSCell;
2087         else if (isBooleanPrediction(value.m_type))
2088             format = DataFormatJSBoolean;
2089         else
2090             format = DataFormatJS;
2091
2092         m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), result.gpr(), format);
2093         break;
2094     }
2095
2096     case SetLocal: {
2097         // SetLocal doubles as a hint as to where a node will be stored and
2098         // as a speculation point. So before we speculate make sure that we
2099         // know where the child of this node needs to go in the virtual
2100         // register file.
2101         compileMovHint(node);
2102         
2103         // As far as OSR is concerned, we're on the bytecode index corresponding
2104         // to the *next* instruction, since we've already "executed" the
2105         // SetLocal and whatever other DFG Nodes are associated with the same
2106         // bytecode index as the SetLocal.
2107         ASSERT(m_codeOriginForOSR == node.codeOrigin);
2108         Node& nextNode = at(m_compileIndex + 1);
2109         
2110         // Oddly, it's possible for the bytecode index for the next node to be
2111         // equal to ours. This will happen for op_post_inc. And, even more oddly,
2112         // this is just fine. Ordinarily, this wouldn't be fine, since if the
2113         // next node failed OSR then we'd be OSR-ing with this SetLocal's local
2114         // variable already set even though from the standpoint of the old JIT,
2115         // this SetLocal should not have executed. But for op_post_inc, it's just
2116         // fine, because this SetLocal's local (i.e. the LHS in a x = y++
2117         // statement) would be dead anyway - so the fact that DFG would have
2118         // already made the assignment, and baked it into the register file during
2119         // OSR exit, would not be visible to the old JIT in any way.
2120         m_codeOriginForOSR = nextNode.codeOrigin;
2121         
2122         PredictedType predictedType = node.variableAccessData()->prediction();
2123         if (isInt32Prediction(predictedType)) {
2124             SpeculateIntegerOperand value(this, node.child1());
2125             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
2126             noResult(m_compileIndex);
2127         } else if (isArrayPrediction(predictedType)) {
2128             SpeculateCellOperand cell(this, node.child1());
2129             GPRReg cellGPR = cell.gpr();
2130             if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
2131                 speculationCheck(JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2132             m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
2133             noResult(m_compileIndex);
2134         } else if (isByteArrayPrediction(predictedType)) {
2135             SpeculateCellOperand cell(this, node.child1());
2136             GPRReg cellGPR = cell.gpr();
2137             if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
2138                 speculationCheck(JSValueRegs(cellGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
2139             m_jit.storePtr(cellGPR, JITCompiler::addressFor(node.local()));
2140             noResult(m_compileIndex);
2141         } else if (isBooleanPrediction(predictedType)) {
2142             SpeculateBooleanOperand boolean(this, node.child1());
2143             m_jit.storePtr(boolean.gpr(), JITCompiler::addressFor(node.local()));
2144             noResult(m_compileIndex);
2145         } else {
2146             JSValueOperand value(this, node.child1());
2147             m_jit.storePtr(value.gpr(), JITCompiler::addressFor(node.local()));
2148             noResult(m_compileIndex);
2149         }
2150
2151         // Indicate that it's no longer necessary to retrieve the value of
2152         // this bytecode variable from registers or other locations in the register file.
2153         valueSourceReferenceForOperand(node.local()) = ValueSource::forPrediction(predictedType);
2154         break;
2155     }
2156
2157     case SetArgument:
2158         // This is a no-op; it just marks the fact that the argument is being used.
2159         // But it may be profitable to use this as a hook to run speculation checks
2160         // on arguments, thereby allowing us to trivially eliminate such checks if
2161         // the argument is not used.
2162         break;
2163
2164     case BitAnd:
2165     case BitOr:
2166     case BitXor:
2167         if (isInt32Constant(node.child1())) {
2168             SpeculateIntegerOperand op2(this, node.child2());
2169             GPRTemporary result(this, op2);
2170
2171             bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
2172
2173             integerResult(result.gpr(), m_compileIndex);
2174         } else if (isInt32Constant(node.child2())) {
2175             SpeculateIntegerOperand op1(this, node.child1());
2176             GPRTemporary result(this, op1);
2177
2178             bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
2179
2180             integerResult(result.gpr(), m_compileIndex);
2181         } else {
2182             SpeculateIntegerOperand op1(this, node.child1());
2183             SpeculateIntegerOperand op2(this, node.child2());
2184             GPRTemporary result(this, op1, op2);
2185
2186             GPRReg reg1 = op1.gpr();
2187             GPRReg reg2 = op2.gpr();
2188             bitOp(op, reg1, reg2, result.gpr());
2189
2190             integerResult(result.gpr(), m_compileIndex);
2191         }
2192         break;
2193
2194     case BitRShift:
2195     case BitLShift:
2196     case BitURShift:
2197         if (isInt32Constant(node.child2())) {
2198             SpeculateIntegerOperand op1(this, node.child1());
2199             GPRTemporary result(this, op1);
2200
2201             shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
2202
2203             integerResult(result.gpr(), m_compileIndex);
2204         } else {
2205             // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
2206             SpeculateIntegerOperand op1(this, node.child1());
2207             SpeculateIntegerOperand op2(this, node.child2());
2208             GPRTemporary result(this, op1);
2209
2210             GPRReg reg1 = op1.gpr();
2211             GPRReg reg2 = op2.gpr();
2212             shiftOp(op, reg1, reg2, result.gpr());
2213
2214             integerResult(result.gpr(), m_compileIndex);
2215         }
2216         break;
2217
2218     case UInt32ToNumber: {
2219         if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
2220             // We know that this sometimes produces doubles. So produce a double every
2221             // time. This at least allows subsequent code to not have weird conditionals.
2222             
2223             IntegerOperand op1(this, node.child1());
2224             FPRTemporary result(this);
2225             
2226             GPRReg inputGPR = op1.gpr();
2227             FPRReg outputFPR = result.fpr();
2228             
2229             m_jit.convertInt32ToDouble(inputGPR, outputFPR);
2230             
2231             JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
2232             m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), outputFPR);
2233             positive.link(&m_jit);
2234             
2235             doubleResult(outputFPR, m_compileIndex);
2236             break;
2237         }
2238
2239         IntegerOperand op1(this, node.child1());
2240         GPRTemporary result(this, op1);
2241
2242         // Test the operand is positive.
2243         speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));
2244
2245         m_jit.move(op1.gpr(), result.gpr());
2246         integerResult(result.gpr(), m_compileIndex, op1.format());
2247         break;
2248     }
2249
2250     case ValueToInt32: {
2251         compileValueToInt32(node);
2252         break;
2253     }
2254
2255     case ValueToNumber: {
2256         if (at(node.child1()).shouldNotSpeculateInteger()) {
2257             SpeculateDoubleOperand op1(this, node.child1());
2258             FPRTemporary result(this, op1);
2259             m_jit.moveDouble(op1.fpr(), result.fpr());
2260             doubleResult(result.fpr(), m_compileIndex);
2261             break;
2262         }
2263         
2264         SpeculateIntegerOperand op1(this, node.child1());
2265         GPRTemporary result(this, op1);
2266         m_jit.move(op1.gpr(), result.gpr());
2267         integerResult(result.gpr(), m_compileIndex, op1.format());
2268         break;
2269     }
2270
2271     case ValueToDouble: {
2272         SpeculateDoubleOperand op1(this, node.child1());
2273         FPRTemporary result(this, op1);
2274         m_jit.moveDouble(op1.fpr(), result.fpr());
2275         doubleResult(result.fpr(), m_compileIndex);
2276         break;
2277     }
2278
2279     case ValueAdd:
2280     case ArithAdd: {
2281         if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) {
2282             if (isInt32Constant(node.child1())) {
2283                 int32_t imm1 = valueOfInt32Constant(node.child1());
2284                 SpeculateIntegerOperand op2(this, node.child2());
2285                 GPRTemporary result(this);
2286
2287                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2288                     m_jit.move(op2.gpr(), result.gpr());
2289                     m_jit.add32(Imm32(imm1), result.gpr());
2290                 } else
2291                     speculationCheck(JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
2292
2293                 integerResult(result.gpr(), m_compileIndex);
2294                 break;
2295             }
2296                 
2297             if (isInt32Constant(node.child2())) {
2298                 SpeculateIntegerOperand op1(this, node.child1());
2299                 int32_t imm2 = valueOfInt32Constant(node.child2());
2300                 GPRTemporary result(this);
2301                 
2302                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2303                     m_jit.move(op1.gpr(), result.gpr());
2304                     m_jit.add32(Imm32(imm2), result.gpr());
2305                 } else
2306                     speculationCheck(JSValueRegs(), NoNode, m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
2307
2308                 integerResult(result.gpr(), m_compileIndex);
2309                 break;
2310             }
2311                 
2312             SpeculateIntegerOperand op1(this, node.child1());
2313             SpeculateIntegerOperand op2(this, node.child2());
2314             GPRTemporary result(this, op1, op2);
2315
2316             GPRReg gpr1 = op1.gpr();
2317             GPRReg gpr2 = op2.gpr();
2318             GPRReg gprResult = result.gpr();
2319
2320             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2321                 if (gpr1 == gprResult)
2322                     m_jit.add32(gpr2, gprResult);
2323                 else {
2324                     m_jit.move(gpr2, gprResult);
2325                     m_jit.add32(gpr1, gprResult);
2326                 }
2327             } else {
2328                 MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
2329                 
2330                 if (gpr1 == gprResult)
2331                     speculationCheck(JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
2332                 else if (gpr2 == gprResult)
2333                     speculationCheck(JSValueRegs(), NoNode, check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
2334                 else
2335                     speculationCheck(JSValueRegs(), NoNode, check);
2336             }
2337
2338             integerResult(gprResult, m_compileIndex);
2339             break;
2340         }
2341         
2342         if (Node::shouldSpeculateNumber(at(node.child1()), at(node.child2()))) {
2343             SpeculateDoubleOperand op1(this, node.child1());
2344             SpeculateDoubleOperand op2(this, node.child2());
2345             FPRTemporary result(this, op1, op2);
2346
2347             FPRReg reg1 = op1.fpr();
2348             FPRReg reg2 = op2.fpr();
2349             m_jit.addDouble(reg1, reg2, result.fpr());
2350
2351             doubleResult(result.fpr(), m_compileIndex);
2352             break;
2353         }
2354
2355         ASSERT(op == ValueAdd);
2356         compileValueAdd(node);
2357         break;
2358     }
2359
2360     case ArithSub: {
2361         if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) {
2362             if (isInt32Constant(node.child2())) {
2363                 SpeculateIntegerOperand op1(this, node.child1());
2364                 int32_t imm2 = valueOfInt32Constant(node.child2());
2365                 GPRTemporary result(this);
2366
2367                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2368                     m_jit.move(op1.gpr(), result.gpr());
2369                     m_jit.sub32(Imm32(imm2), result.gpr());
2370                 } else
2371                     speculationCheck(JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
2372
2373                 integerResult(result.gpr(), m_compileIndex);
2374                 break;
2375             }
2376                 
2377             SpeculateIntegerOperand op1(this, node.child1());
2378             SpeculateIntegerOperand op2(this, node.child2());
2379             GPRTemporary result(this);
2380
2381             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
2382                 m_jit.move(op1.gpr(), result.gpr());
2383                 m_jit.sub32(op2.gpr(), result.gpr());
2384             } else
2385                 speculationCheck(JSValueRegs(), NoNode, m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
2386
2387             integerResult(result.gpr(), m_compileIndex);
2388             break;
2389         }
2390         
2391         SpeculateDoubleOperand op1(this, node.child1());
2392         SpeculateDoubleOperand op2(this, node.child2());
2393         FPRTemporary result(this, op1);
2394
2395         FPRReg reg1 = op1.fpr();
2396         FPRReg reg2 = op2.fpr();
2397         m_jit.subDouble(reg1, reg2, result.fpr());
2398
2399         doubleResult(result.fpr(), m_compileIndex);
2400         break;
2401     }
2402
2403     case ArithMul: {
2404         compileArithMul(node);
2405         break;
2406     }
2407
2408     case ArithDiv: {
2409         if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) {
2410             SpeculateIntegerOperand op1(this, node.child1());
2411             SpeculateIntegerOperand op2(this, node.child2());
2412             GPRTemporary eax(this, X86Registers::eax);
2413             GPRTemporary edx(this, X86Registers::edx);
2414             GPRReg op1GPR = op1.gpr();
2415             GPRReg op2GPR = op2.gpr();
2416             
2417             speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::Zero, op2GPR));
2418             
2419             // If the user cares about negative zero, then speculate that we're not about
2420             // to produce negative zero.
2421             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
2422                 MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
2423                 speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
2424                 numeratorNonZero.link(&m_jit);
2425             }
2426             
2427             GPRReg temp2 = InvalidGPRReg;
2428             if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
2429                 temp2 = allocate();
2430                 m_jit.move(op2GPR, temp2);
2431                 op2GPR = temp2;
2432             }
2433             
2434             m_jit.move(op1GPR, eax.gpr());
2435             m_jit.assembler().cdq();
2436             m_jit.assembler().idivl_r(op2GPR);
2437             
2438             if (temp2 != InvalidGPRReg)
2439                 unlock(temp2);
2440
2441             // Check that there was no remainder. If there had been, then we'd be obligated to
2442             // produce a double result instead.
2443             speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
2444             
2445             integerResult(eax.gpr(), m_compileIndex);
2446             break;
2447         }
2448         
2449         SpeculateDoubleOperand op1(this, node.child1());
2450         SpeculateDoubleOperand op2(this, node.child2());
2451         FPRTemporary result(this, op1);
2452
2453         FPRReg reg1 = op1.fpr();
2454         FPRReg reg2 = op2.fpr();
2455         m_jit.divDouble(reg1, reg2, result.fpr());
2456
2457         doubleResult(result.fpr(), m_compileIndex);
2458         break;
2459     }
2460
2461     case ArithMod: {
2462         compileArithMod(node);
2463         break;
2464     }
2465
2466     case ArithAbs: {
2467         if (at(node.child1()).shouldSpeculateInteger() && node.canSpeculateInteger()) {
2468             SpeculateIntegerOperand op1(this, node.child1());
2469             GPRTemporary result(this, op1);
2470             GPRTemporary scratch(this);
2471             
2472             m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
2473             m_jit.rshift32(result.gpr(), MacroAssembler::TrustedImm32(31), scratch.gpr());
2474             m_jit.add32(scratch.gpr(), result.gpr());
2475             m_jit.xor32(scratch.gpr(), result.gpr());
2476             speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
2477             integerResult(result.gpr(), m_compileIndex);
2478             break;
2479         }
2480         
2481         SpeculateDoubleOperand op1(this, node.child1());
2482         FPRTemporary result(this);
2483         
2484         m_jit.absDouble(op1.fpr(), result.fpr());
2485         doubleResult(result.fpr(), m_compileIndex);
2486         break;
2487     }
2488         
2489     case ArithMin:
2490     case ArithMax: {
2491         if (Node::shouldSpeculateInteger(at(node.child1()), at(node.child2())) && node.canSpeculateInteger()) {
2492             SpeculateStrictInt32Operand op1(this, node.child1());
2493             SpeculateStrictInt32Operand op2(this, node.child2());
2494             GPRTemporary result(this, op1);
2495             
2496             MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr());
2497             m_jit.move(op2.gpr(), result.gpr());
2498             if (op1.gpr() != result.gpr()) {
2499                 MacroAssembler::Jump done = m_jit.jump();
2500                 op1Less.link(&m_jit);
2501                 m_jit.move(op1.gpr(), result.gpr());
2502                 done.link(&m_jit);
2503             } else
2504                 op1Less.link(&m_jit);
2505             
2506             integerResult(result.gpr(), m_compileIndex);
2507             break;
2508         }
2509         
2510         SpeculateDoubleOperand op1(this, node.child1());
2511         SpeculateDoubleOperand op2(this, node.child2());
2512         FPRTemporary result(this, op1);
2513         
2514         MacroAssembler::JumpList done;
2515         
2516         MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
2517         
2518         // op2 is eather the lesser one or one of then is NaN
2519         MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1.fpr(), op2.fpr());
2520         
2521         // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding 
2522         // op1 + op2 and putting it into result.
2523         m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
2524         done.append(m_jit.jump());
2525         
2526         op2Less.link(&m_jit);
2527         m_jit.moveDouble(op2.fpr(), result.fpr());
2528         
2529         if (op1.fpr() != result.fpr()) {
2530             done.append(m_jit.jump());
2531             
2532             op1Less.link(&m_jit);
2533             m_jit.moveDouble(op1.fpr(), result.fpr());
2534         } else
2535             op1Less.link(&m_jit);
2536         
2537         done.link(&m_jit);
2538         
2539         doubleResult(result.fpr(), m_compileIndex);
2540         break;
2541     }
2542         
2543     case ArithSqrt: {
2544         SpeculateDoubleOperand op1(this, node.child1());
2545         FPRTemporary result(this, op1);
2546         
2547         m_jit.sqrtDouble(op1.fpr(), result.fpr());
2548         
2549         doubleResult(result.fpr(), m_compileIndex);
2550         break;
2551     }
2552
2553     case LogicalNot:
2554         compileLogicalNot(node);
2555         break;
2556
2557     case CompareLess:
2558         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
2559             return;
2560         break;
2561
2562     case CompareLessEq:
2563         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
2564             return;
2565         break;
2566
2567     case CompareGreater:
2568         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
2569             return;
2570         break;
2571
2572     case CompareGreaterEq:
2573         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
2574             return;
2575         break;
2576
2577     case CompareEq:
2578         if (isNullConstant(node.child1())) {
2579             if (nonSpeculativeCompareNull(node, node.child2()))
2580                 return;
2581             break;
2582         }
2583         if (isNullConstant(node.child2())) {
2584             if (nonSpeculativeCompareNull(node, node.child1()))
2585                 return;
2586             break;
2587         }
2588         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
2589             return;
2590         break;
2591
2592     case CompareStrictEq:
2593         if (nonSpeculativeStrictEq(node))
2594             return;
2595         break;
2596
2597     case StringCharCodeAt: {
2598         compileGetCharCodeAt(node);
2599         break;
2600     }
2601
2602     case StringCharAt: {
2603         // Relies on StringCharAt node having same basic layout as GetByVal
2604         compileGetByValOnString(node);
2605         break;
2606     }
2607
2608     case GetByVal: {
2609         PredictedType basePrediction = at(node.child2()).prediction();
2610         if (!(basePrediction & PredictInt32) && basePrediction) {
2611             JSValueOperand base(this, node.child1());
2612             JSValueOperand property(this, node.child2());
2613             GPRReg baseGPR = base.gpr();
2614             GPRReg propertyGPR = property.gpr();
2615             
2616             flushRegisters();
2617             GPRResult result(this);
2618             callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR);
2619             
2620             jsValueResult(result.gpr(), m_compileIndex);
2621             break;
2622         }
2623         
2624         if (at(node.child1()).prediction() == PredictString) {
2625             compileGetByValOnString(node);
2626             if (!m_compileOkay)
2627                 return;
2628             break;
2629         }
2630
2631         if (at(node.child1()).shouldSpeculateByteArray()) {
2632             compileGetByValOnByteArray(node);
2633             if (!m_compileOkay)
2634                 return;
2635             break;            
2636         }
2637
2638         ASSERT(node.child3() == NoNode);
2639         SpeculateCellOperand base(this, node.child1());
2640         SpeculateStrictInt32Operand property(this, node.child2());
2641         GPRTemporary storage(this);
2642
2643         GPRReg baseReg = base.gpr();
2644         GPRReg propertyReg = property.gpr();
2645         GPRReg storageReg = storage.gpr();
2646         
2647         if (!m_compileOkay)
2648             return;
2649
2650         // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
2651         // an access with offset JSArray::storageOffset() is valid for all JSCells!
2652         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
2653
2654         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
2655         // If we have predicted the base to be type array, we can skip the check.
2656         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
2657             speculationCheck(JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2658         speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
2659
2660         // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache
2661         // the storage pointer - especially if there happens to be another register free right now. If we do so,
2662         // then we'll need to allocate a new temporary for result.
2663         GPRTemporary& result = storage;
2664         m_jit.loadPtr(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
2665         speculationCheck(JSValueRegs(), NoNode, m_jit.branchTestPtr(MacroAssembler::Zero, result.gpr()));
2666
2667         jsValueResult(result.gpr(), m_compileIndex);
2668         break;
2669     }
2670
2671     case PutByVal: {
2672         PredictedType basePrediction = at(node.child2()).prediction();
2673         if (!(basePrediction & PredictInt32) && basePrediction) {
2674             JSValueOperand arg1(this, node.child1());
2675             JSValueOperand arg2(this, node.child2());
2676             JSValueOperand arg3(this, node.child3());
2677             GPRReg arg1GPR = arg1.gpr();
2678             GPRReg arg2GPR = arg2.gpr();
2679             GPRReg arg3GPR = arg3.gpr();
2680             flushRegisters();
2681             
2682             callOperation(m_jit.strictModeFor(node.codeOrigin) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
2683             
2684             noResult(m_compileIndex);
2685             break;
2686         }
2687
2688         SpeculateCellOperand base(this, node.child1());
2689         SpeculateStrictInt32Operand property(this, node.child2());
2690         if (at(node.child1()).shouldSpeculateByteArray()) {
2691             compilePutByValForByteArray(base.gpr(), property.gpr(), node);
2692             break;
2693         }
2694
2695         JSValueOperand value(this, node.child3());
2696         GPRTemporary scratch(this);
2697
2698         // Map base, property & value into registers, allocate a scratch register.
2699         GPRReg baseReg = base.gpr();
2700         GPRReg propertyReg = property.gpr();
2701         GPRReg valueReg = value.gpr();
2702         GPRReg scratchReg = scratch.gpr();
2703         
2704         if (!m_compileOkay)
2705             return;
2706         
2707         writeBarrier(baseReg, value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg);
2708
2709         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
2710         // If we have predicted the base to be type array, we can skip the check.
2711         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
2712             speculationCheck(JSValueRegs(baseReg), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2713
2714         base.use();
2715         property.use();
2716         value.use();
2717         
2718         MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
2719
2720         // Code to handle put beyond array bounds.
2721         silentSpillAllRegisters(scratchReg);
2722         callOperation(operationPutByValBeyondArrayBounds, baseReg, propertyReg, valueReg);
2723         silentFillAllRegisters(scratchReg);
2724         JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
2725
2726         withinArrayBounds.link(&m_jit);
2727
2728         // Get the array storage.
2729         GPRReg storageReg = scratchReg;
2730         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
2731
2732         // Check if we're writing to a hole; if so increment m_numValuesInVector.
2733         MacroAssembler::Jump notHoleValue = m_jit.branchTestPtr(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2734         m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
2735
2736         // If we're writing to a hole we might be growing the array; 
2737         MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
2738         m_jit.add32(TrustedImm32(1), propertyReg);
2739         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
2740         m_jit.sub32(TrustedImm32(1), propertyReg);
2741
2742         lengthDoesNotNeedUpdate.link(&m_jit);
2743         notHoleValue.link(&m_jit);
2744
2745         // Store the value to the array.
2746         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2747
2748         wasBeyondArrayBounds.link(&m_jit);
2749
2750         noResult(m_compileIndex, UseChildrenCalledExplicitly);
2751         break;
2752     }
2753
2754     case PutByValAlias: {
2755         PredictedType basePrediction = at(node.child2()).prediction();
2756         ASSERT_UNUSED(basePrediction, (basePrediction & PredictInt32) || !basePrediction);
2757             
2758         SpeculateCellOperand base(this, node.child1());
2759         SpeculateStrictInt32Operand property(this, node.child2());
2760         if (at(node.child1()).shouldSpeculateByteArray()) {
2761             compilePutByValForByteArray(base.gpr(), property.gpr(), node);
2762             break;
2763         }
2764
2765         JSValueOperand value(this, node.child3());
2766         GPRTemporary scratch(this);
2767         
2768         GPRReg baseReg = base.gpr();
2769         GPRReg scratchReg = scratch.gpr();
2770
2771         writeBarrier(base.gpr(), value.gpr(), node.child3(), WriteBarrierForPropertyAccess, scratchReg);
2772
2773         // Get the array storage.
2774         GPRReg storageReg = scratchReg;
2775         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
2776
2777         // Store the value to the array.
2778         GPRReg propertyReg = property.gpr();
2779         GPRReg valueReg = value.gpr();
2780         m_jit.storePtr(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2781
2782         noResult(m_compileIndex);
2783         break;
2784     }
2785         
2786     case ArrayPush: {
2787         SpeculateCellOperand base(this, node.child1());
2788         JSValueOperand value(this, node.child2());
2789         GPRTemporary storage(this);
2790         GPRTemporary storageLength(this);
2791         
2792         GPRReg baseGPR = base.gpr();
2793         GPRReg valueGPR = value.gpr();
2794         GPRReg storageGPR = storage.gpr();
2795         GPRReg storageLengthGPR = storageLength.gpr();
2796         
2797         writeBarrier(baseGPR, valueGPR, node.child2(), WriteBarrierForPropertyAccess, storageGPR, storageLengthGPR);
2798
2799         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
2800             speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2801         
2802         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
2803         m_jit.load32(MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), storageLengthGPR);
2804         
2805         // Refuse to handle bizarre lengths.
2806         speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
2807         
2808         MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset()));
2809         
2810         m_jit.storePtr(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2811         
2812         m_jit.add32(Imm32(1), storageLengthGPR);
2813         m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
2814         m_jit.add32(Imm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
2815         m_jit.orPtr(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
2816         
2817         MacroAssembler::Jump done = m_jit.jump();
2818         
2819         slowPath.link(&m_jit);
2820         
2821         silentSpillAllRegisters(storageLengthGPR);
2822         callOperation(operationArrayPush, storageLengthGPR, valueGPR, baseGPR);
2823         silentFillAllRegisters(storageLengthGPR);
2824         
2825         done.link(&m_jit);
2826         
2827         jsValueResult(storageLengthGPR, m_compileIndex);
2828         break;
2829     }
2830         
2831     case ArrayPop: {
2832         SpeculateCellOperand base(this, node.child1());
2833         GPRTemporary value(this);
2834         GPRTemporary storage(this);
2835         GPRTemporary storageLength(this);
2836         
2837         GPRReg baseGPR = base.gpr();
2838         GPRReg valueGPR = value.gpr();
2839         GPRReg storageGPR = storage.gpr();
2840         GPRReg storageLengthGPR = storageLength.gpr();
2841         
2842         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
2843             speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
2844         
2845         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), storageGPR);
2846         m_jit.load32(MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), storageLengthGPR);
2847         
2848         MacroAssembler::Jump emptyArrayCase = m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
2849         
2850         m_jit.sub32(Imm32(1), storageLengthGPR);
2851         
2852         MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(baseGPR, JSArray::vectorLengthOffset()));
2853         
2854         m_jit.loadPtr(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), valueGPR);
2855         
2856         m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)));
2857
2858         MacroAssembler::Jump holeCase = m_jit.branchTestPtr(MacroAssembler::Zero, valueGPR);
2859         
2860         m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::ScalePtr, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2861         m_jit.sub32(MacroAssembler::Imm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
2862         
2863         MacroAssembler::JumpList done;
2864         
2865         done.append(m_jit.jump());
2866         
2867         holeCase.link(&m_jit);
2868         emptyArrayCase.link(&m_jit);
2869         m_jit.move(MacroAssembler::TrustedImmPtr(JSValue::encode(jsUndefined())), valueGPR);
2870         done.append(m_jit.jump());
2871         
2872         slowCase.link(&m_jit);
2873         
2874         silentSpillAllRegisters(valueGPR);
2875         callOperation(operationArrayPop, valueGPR, baseGPR);
2876         silentFillAllRegisters(valueGPR);
2877         
2878         done.link(&m_jit);
2879         
2880         jsValueResult(valueGPR, m_compileIndex);
2881         break;
2882     }
2883
2884     case DFG::Jump: {
2885         BlockIndex taken = node.takenBlockIndex();
2886         if (taken != (m_block + 1))
2887             addBranch(m_jit.jump(), taken);
2888         noResult(m_compileIndex);
2889         break;
2890     }
2891
2892     case Branch:
2893         if (isStrictInt32(node.child1()) || at(node.child1()).shouldSpeculateInteger()) {
2894             SpeculateIntegerOperand op(this, node.child1());
2895             
2896             BlockIndex taken = node.takenBlockIndex();
2897             BlockIndex notTaken = node.notTakenBlockIndex();
2898             
2899             MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
2900             
2901             if (taken == (m_block + 1)) {
2902                 condition = MacroAssembler::Zero;
2903                 BlockIndex tmp = taken;
2904                 taken = notTaken;
2905                 notTaken = tmp;
2906             }
2907             
2908             addBranch(m_jit.branchTest32(condition, op.gpr()), taken);
2909             if (notTaken != (m_block + 1))
2910                 addBranch(m_jit.jump(), notTaken);
2911             
2912             noResult(m_compileIndex);
2913             break;
2914         }
2915         emitBranch(node);
2916         break;
2917
2918     case Return: {
2919         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);
2920         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
2921         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
2922
2923 #if DFG_ENABLE(SUCCESS_STATS)
2924         static SamplingCounter counter("SpeculativeJIT");
2925         m_jit.emitCount(counter);
2926 #endif
2927
2928         // Return the result in returnValueGPR.
2929         JSValueOperand op1(this, node.child1());
2930         m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
2931
2932         // Grab the return address.
2933         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, GPRInfo::regT1);
2934         // Restore our caller's "r".
2935         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, GPRInfo::callFrameRegister);
2936         // Return.
2937         m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT1);
2938         m_jit.ret();
2939         
2940         noResult(m_compileIndex);
2941         break;
2942     }
2943         
2944     case Throw:
2945     case ThrowReferenceError: {
2946         // We expect that throw statements are rare and are intended to exit the code block
2947         // anyway, so we just OSR back to the old JIT for now.
2948         terminateSpeculativeExecution(JSValueRegs(), NoNode);
2949         break;
2950     }
2951         
2952     case ToPrimitive: {
2953         if (at(node.child1()).shouldSpeculateInteger()) {
2954             // It's really profitable to speculate integer, since it's really cheap,
2955             // it means we don't have to do any real work, and we emit a lot less code.
2956             
2957             SpeculateIntegerOperand op1(this, node.child1());
2958             GPRTemporary result(this, op1);
2959             
2960             m_jit.move(op1.gpr(), result.gpr());
2961             if (op1.format() == DataFormatInteger)
2962                 m_jit.orPtr(GPRInfo::tagTypeNumberRegister, result.gpr());
2963             
2964             jsValueResult(result.gpr(), m_compileIndex);
2965             break;
2966         }
2967         
2968         // FIXME: Add string speculation here.
2969         
2970         bool wasPrimitive = isKnownNumeric(node.child1()) || isKnownBoolean(node.child1());
2971         
2972         JSValueOperand op1(this, node.child1());
2973         GPRTemporary result(this, op1);
2974         
2975         GPRReg op1GPR = op1.gpr();
2976         GPRReg resultGPR = result.gpr();
2977         
2978         op1.use();
2979         
2980         if (wasPrimitive)
2981             m_jit.move(op1GPR, resultGPR);
2982         else {
2983             MacroAssembler::JumpList alreadyPrimitive;
2984             
2985             alreadyPrimitive.append(m_jit.branchTestPtr(MacroAssembler::NonZero, op1GPR, GPRInfo::tagMaskRegister));
2986             alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
2987             
2988             silentSpillAllRegisters(resultGPR);
2989             callOperation(operationToPrimitive, resultGPR, op1GPR);
2990             silentFillAllRegisters(resultGPR);
2991             
2992             MacroAssembler::Jump done = m_jit.jump();
2993             
2994             alreadyPrimitive.link(&m_jit);
2995             m_jit.move(op1GPR, resultGPR);
2996             
2997             done.link(&m_jit);
2998         }
2999         
3000         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
3001         break;
3002     }
3003         
3004     case StrCat:
3005     case NewArray: {
3006         // We really don't want to grow the register file just to do a StrCat or NewArray.
3007         // Say we have 50 functions on the stack that all have a StrCat in them that has
3008         // upwards of 10 operands. In the DFG this would mean that each one gets
3009         // some random virtual register, and then to do the StrCat we'd need a second
3010         // span of 10 operands just to have somewhere to copy the 10 operands to, where
3011         // they'd be contiguous and we could easily tell the C code how to find them.
3012         // Ugly! So instead we use the scratchBuffer infrastructure in JSGlobalData. That
3013         // way, those 50 functions will share the same scratchBuffer for offloading their
3014         // StrCat operands. It's about as good as we can do, unless we start doing
3015         // virtual register coalescing to ensure that operands to StrCat get spilled
3016         // in exactly the place where StrCat wants them, or else have the StrCat
3017         // refer to those operands' SetLocal instructions to force them to spill in
3018         // the right place. Basically, any way you cut it, the current approach
3019         // probably has the best balance of performance and sensibility in the sense
3020         // that it does not increase the complexity of the DFG JIT just to make StrCat
3021         // fast and pretty.
3022         
3023         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_jit.globalData()->scratchBufferForSize(sizeof(EncodedJSValue) * node.numChildren()));
3024         
3025         for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
3026             JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
3027             GPRReg opGPR = operand.gpr();
3028             operand.use();
3029             
3030             m_jit.storePtr(opGPR, buffer + operandIdx);
3031         }
3032         
3033         flushRegisters();
3034         
3035         GPRResult result(this);
3036         
3037         callOperation(op == StrCat ? operationStrCat : operationNewArray, result.gpr(), buffer, node.numChildren());
3038         
3039         cellResult(result.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
3040         break;
3041     }
3042         
3043     case NewArrayBuffer: {
3044         flushRegisters();
3045         GPRResult result(this);
3046         
3047         callOperation(operationNewArrayBuffer, result.gpr(), node.startConstant(), node.numConstants());
3048         
3049         cellResult(result.gpr(), m_compileIndex);
3050         break;
3051     }
3052         
3053     case NewRegexp: {
3054         flushRegisters();
3055         GPRResult result(this);
3056         
3057         callOperation(operationNewRegexp, result.gpr(), m_jit.codeBlock()->regexp(node.regexpIndex()));
3058         
3059         cellResult(result.gpr(), m_compileIndex);
3060         break;
3061     }
3062         
3063     case ConvertThis: {
3064         if (isObjectPrediction(m_state.forNode(node.child1()).m_type)) {
3065             SpeculateCellOperand thisValue(this, node.child1());
3066             GPRTemporary result(this, thisValue);
3067             m_jit.move(thisValue.gpr(), result.gpr());
3068             cellResult(result.gpr(), m_compileIndex);
3069             break;
3070         }
3071         
3072         if (isOtherPrediction(at(node.child1()).prediction())) {
3073             JSValueOperand thisValue(this, node.child1());
3074             GPRTemporary scratch(this, thisValue);
3075             GPRReg thisValueGPR = thisValue.gpr();
3076             GPRReg scratchGPR = scratch.gpr();
3077             
3078             if (!isOtherPrediction(m_state.forNode(node.child1()).m_type)) {
3079                 m_jit.move(thisValueGPR, scratchGPR);
3080                 m_jit.andPtr(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
3081                 speculationCheck(JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImmPtr(reinterpret_cast<void*>(ValueNull))));
3082             }
3083             
3084             m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), scratchGPR);
3085             cellResult(scratchGPR, m_compileIndex);
3086             break;
3087         }
3088         
3089         if (isObjectPrediction(at(node.child1()).prediction())) {
3090             SpeculateCellOperand thisValue(this, node.child1());
3091             GPRTemporary result(this, thisValue);
3092             GPRReg thisValueGPR = thisValue.gpr();
3093             GPRReg resultGPR = result.gpr();
3094             
3095             if (!isObjectPrediction(m_state.forNode(node.child1()).m_type))
3096                 speculationCheck(JSValueRegs(thisValueGPR), node.child1(), m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValueGPR), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
3097             
3098             m_jit.move(thisValueGPR, resultGPR);
3099             
3100             cellResult(resultGPR, m_compileIndex);
3101             break;
3102         }
3103         
3104         JSValueOperand thisValue(this, node.child1());
3105         GPRReg thisValueGPR = thisValue.gpr();
3106         
3107         flushRegisters();
3108         
3109         GPRResult result(this);
3110         callOperation(operationConvertThis, result.gpr(), thisValueGPR);
3111         
3112         cellResult(result.gpr(), m_compileIndex);
3113         break;
3114     }
3115
3116     case CreateThis: {
3117         // Note that there is not so much profit to speculate here. The only things we
3118         // speculate on are (1) that it's a cell, since that eliminates cell checks
3119         // later if the proto is reused, and (2) if we have a FinalObject prediction
3120         // then we speculate because we want to get recompiled if it isn't (since
3121         // otherwise we'd start taking slow path a lot).
3122         
3123         SpeculateCellOperand proto(this, node.child1());
3124         GPRTemporary result(this);
3125         GPRTemporary scratch(this);
3126         
3127         GPRReg protoGPR = proto.gpr();
3128         GPRReg resultGPR = result.gpr();
3129         GPRReg scratchGPR = scratch.gpr();
3130         
3131         proto.use();
3132         
3133         MacroAssembler::JumpList slowPath;
3134         
3135         // Need to verify that the prototype is an object. If we have reason to believe
3136         // that it's a FinalObject then we speculate on that directly. Otherwise we
3137         // do the slow (structure-based) check.
3138         if (at(node.child1()).shouldSpeculateFinalObject()) {
3139             if (!isFinalObjectPrediction(m_state.forNode(node.child1()).m_type))
3140                 speculationCheck(JSValueRegs(protoGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));
3141         } else {
3142             m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);
3143             slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));
3144         }
3145         
3146         // Load the inheritorID (the Structure that objects who have protoGPR as the prototype
3147         // use to refer to that prototype). If the inheritorID is not set, go to slow path.
3148         m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSObject::offsetOfInheritorID()), scratchGPR);
3149         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, scratchGPR));
3150         
3151         emitAllocateJSFinalObject(scratchGPR, resultGPR, scratchGPR, slowPath);
3152         
3153         MacroAssembler::Jump done = m_jit.jump();
3154         
3155         slowPath.link(&m_jit);
3156         
3157         silentSpillAllRegisters(resultGPR);
3158         if (node.codeOrigin.inlineCallFrame)
3159             callOperation(operationCreateThisInlined, resultGPR, protoGPR, node.codeOrigin.inlineCallFrame->callee.get());
3160         else
3161             callOperation(operationCreateThis, resultGPR, protoGPR);
3162         silentFillAllRegisters(resultGPR);
3163         
3164         done.link(&m_jit);
3165         
3166         cellResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
3167         break;
3168     }
3169
3170     case NewObject: {
3171         GPRTemporary result(this);
3172         GPRTemporary scratch(this);
3173         
3174         GPRReg resultGPR = result.gpr();
3175         GPRReg scratchGPR = scratch.gpr();
3176         
3177         MacroAssembler::JumpList slowPath;
3178         
3179         emitAllocateJSFinalObject(MacroAssembler::TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)->emptyObjectStructure()), resultGPR, scratchGPR, slowPath);
3180         
3181         MacroAssembler::Jump done = m_jit.jump();
3182         
3183         slowPath.link(&m_jit);
3184         
3185         silentSpillAllRegisters(resultGPR);
3186         callOperation(operationNewObject, resultGPR);
3187         silentFillAllRegisters(resultGPR);
3188         
3189         done.link(&m_jit);
3190         
3191         cellResult(resultGPR, m_compileIndex);
3192         break;
3193     }
3194
3195     case GetCallee: {
3196         GPRTemporary result(this);
3197         m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::Callee)), result.gpr());
3198         cellResult(result.gpr(), m_compileIndex);
3199         break;
3200     }
3201
3202     case GetScopeChain: {
3203         GPRTemporary result(this);
3204         GPRReg resultGPR = result.gpr();
3205
3206         m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::ScopeChain)), resultGPR);
3207         bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain();
3208         int skip = node.scopeChainDepth();
3209         ASSERT(skip || !checkTopLevel);
3210         if (checkTopLevel && skip--) {
3211             JITCompiler::Jump activationNotCreated;
3212             if (checkTopLevel)
3213                 activationNotCreated = m_jit.branchTestPtr(JITCompiler::Zero, JITCompiler::addressFor(static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
3214             m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
3215             activationNotCreated.link(&m_jit);
3216         }
3217         while (skip--)
3218             m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
3219         
3220         m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, object)), resultGPR);
3221
3222         cellResult(resultGPR, m_compileIndex);
3223         break;
3224     }
3225     case GetScopedVar: {
3226         SpeculateCellOperand scopeChain(this, node.child1());
3227         GPRTemporary result(this);
3228         GPRReg resultGPR = result.gpr();
3229         m_jit.loadPtr(JITCompiler::Address(scopeChain.gpr(), JSVariableObject::offsetOfRegisters()), resultGPR);
3230         m_jit.loadPtr(JITCompiler::Address(resultGPR, node.varNumber() * sizeof(Register)), resultGPR);
3231         jsValueResult(resultGPR, m_compileIndex);
3232         break;
3233     }
3234     case PutScopedVar: {
3235         SpeculateCellOperand scopeChain(this, node.child1());
3236         GPRTemporary scratchRegister(this);
3237         GPRReg scratchGPR = scratchRegister.gpr();
3238         m_jit.loadPtr(JITCompiler::Address(scopeChain.gpr(), JSVariableObject::offsetOfRegisters()), scratchGPR);
3239         JSValueOperand value(this, node.child2());
3240         m_jit.storePtr(value.gpr(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register)));
3241         writeBarrier(scopeChain.gpr(), value.gpr(), node.child2(), WriteBarrierForVariableAccess, scratchGPR);
3242         noResult(m_compileIndex);
3243         break;
3244     }
3245     case GetById: {
3246         if (!node.prediction()) {
3247             terminateSpeculativeExecution(JSValueRegs(), NoNode);
3248             break;
3249         }
3250         
3251         if (isCellPrediction(at(node.child1()).prediction())) {
3252             SpeculateCellOperand base(this, node.child1());
3253             GPRTemporary result(this, base);
3254             
3255             GPRReg baseGPR = base.gpr();
3256             GPRReg resultGPR = result.gpr();
3257             GPRReg scratchGPR;
3258             
3259             if (resultGPR == baseGPR)
3260                 scratchGPR = tryAllocate();
3261             else
3262                 scratchGPR = resultGPR;
3263             
3264             base.use();
3265             
3266             cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber());
3267             
3268             jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
3269             break;
3270         }
3271         
3272         JSValueOperand base(this, node.child1());
3273         GPRTemporary result(this, base);
3274         
3275         GPRReg baseGPR = base.gpr();
3276         GPRReg resultGPR = result.gpr();
3277         GPRReg scratchGPR;
3278         
3279         if (resultGPR == baseGPR)
3280             scratchGPR = tryAllocate();
3281         else
3282             scratchGPR = resultGPR;
3283         
3284         base.use();
3285         
3286         JITCompiler::Jump notCell = m_jit.branchTestPtr(JITCompiler::NonZero, baseGPR, GPRInfo::tagMaskRegister);
3287         
3288         cachedGetById(baseGPR, resultGPR, scratchGPR, node.identifierNumber(), notCell);
3289         
3290         jsValueResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
3291         
3292         break;
3293     }
3294
3295     case GetArrayLength: {
3296         SpeculateCellOperand base(this, node.child1());
3297         GPRTemporary result(this);
3298         
3299         GPRReg baseGPR = base.gpr();
3300         GPRReg resultGPR = result.gpr();
3301         
3302         if (!isArrayPrediction(m_state.forNode(node.child1()).m_type))
3303             speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
3304         
3305         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
3306         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
3307         
3308         speculationCheck(JSValueRegs(), NoNode, m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));
3309         
3310         integerResult(resultGPR, m_compileIndex);
3311         break;
3312     }
3313
3314     case GetStringLength: {
3315         SpeculateCellOperand base(this, node.child1());
3316         GPRTemporary result(this);
3317         
3318         GPRReg baseGPR = base.gpr();
3319         GPRReg resultGPR = result.gpr();
3320         
3321         if (!isStringPrediction(m_state.forNode(node.child1()).m_type))
3322             speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
3323         
3324         m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
3325
3326         integerResult(resultGPR, m_compileIndex);
3327         break;
3328     }
3329
3330     case GetByteArrayLength: {
3331         SpeculateCellOperand base(this, node.child1());
3332         GPRTemporary result(this);
3333         
3334         GPRReg baseGPR = base.gpr();
3335         GPRReg resultGPR = result.gpr();
3336         
3337         if (!isByteArrayPrediction(m_state.forNode(node.child1()).m_type))
3338             speculationCheck(JSValueRegs(baseGPR), node.child1(), m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsByteArrayVPtr)));
3339         
3340         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSByteArray::offsetOfStorage()), resultGPR);
3341         m_jit.load32(MacroAssembler::Address(baseGPR, ByteArray::offsetOfSize()), resultGPR);
3342
3343         integerResult(resultGPR, m_compileIndex);
3344         break;
3345     }
3346
3347     case CheckFunction: {
3348         SpeculateCellOperand function(this, node.child1());
3349         speculationCheck(JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, function.gpr(), node.function()));
3350         noResult(m_compileIndex);
3351         break;
3352     }
3353     case CheckStructure: {
3354         if (m_state.forNode(node.child1()).m_structure.isSubsetOf(node.structureSet())) {
3355             noResult(m_compileIndex);
3356             break;
3357         }
3358         
3359         SpeculateCellOperand base(this, node.child1());
3360         
3361         ASSERT(node.structureSet().size());
3362         
3363         if (node.structureSet().size() == 1)
3364             speculationCheck(JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), node.structureSet()[0]));
3365         else {
3366             GPRTemporary structure(this);
3367             
3368             m_jit.loadPtr(JITCompiler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
3369             
3370             JITCompiler::JumpList done;
3371             
3372             for (size_t i = 0; i < node.structureSet().size() - 1; ++i)
3373                 done.append(m_jit.branchWeakPtr(JITCompiler::Equal, structure.gpr(), node.structureSet()[i]));
3374             
3375             speculationCheck(JSValueRegs(), NoNode, m_jit.branchWeakPtr(JITCompiler::NotEqual, structure.gpr(), node.structureSet().last()));
3376             
3377             done.link(&m_jit);
3378         }
3379         
3380         noResult(m_compileIndex);
3381         break;
3382     }
3383         
3384     case PutStructure: {
3385         SpeculateCellOperand base(this, node.child1());
3386         GPRReg baseGPR = base.gpr();
3387         
3388         m_jit.addWeakReferenceTransition(
3389             node.codeOrigin.codeOriginOwner(),
3390             node.structureTransitionData().previousStructure,
3391             node.structureTransitionData().newStructure);
3392         
3393 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
3394         // Must always emit this write barrier as the structure transition itself requires it
3395         writeBarrier(baseGPR, node.structureTransitionData().newStructure, WriteBarrierForGenericAccess);
3396 #endif
3397         
3398         m_jit.storePtr(MacroAssembler::TrustedImmPtr(node.structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
3399         
3400         noResult(m_compileIndex);
3401         break;
3402     }
3403         
3404     case GetPropertyStorage: {
3405         SpeculateCellOperand base(this, node.child1());
3406         GPRTemporary result(this, base);
3407         
3408         GPRReg baseGPR = base.gpr();
3409         GPRReg resultGPR = result.gpr();
3410         
3411         m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
3412         
3413         storageResult(resultGPR, m_compileIndex);
3414         break;
3415     }
3416         
3417     case GetByOffset: {
3418         StorageOperand storage(this, node.child1());
3419         GPRTemporary result(this, storage);
3420         
3421         GPRReg storageGPR = storage.gpr();
3422         GPRReg resultGPR = result.gpr();
3423         
3424         StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
3425         
3426         m_jit.loadPtr(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue)), resultGPR);
3427         
3428         jsValueResult(resultGPR, m_compileIndex);
3429         break;
3430     }
3431         
3432     case PutByOffset: {
3433 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
3434         SpeculateCellOperand base(this, node.child1());
3435 #endif
3436         StorageOperand storage(this, node.child2());
3437         JSValueOperand value(this, node.child3());
3438
3439         GPRReg storageGPR = storage.gpr();
3440         GPRReg valueGPR = value.gpr();
3441         
3442 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
3443         writeBarrier(base.gpr(), value.gpr(), node.child3(), WriteBarrierForPropertyAccess);
3444 #endif
3445
3446         StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
3447         
3448         m_jit.storePtr(valueGPR, JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue)));
3449         
3450         noResult(m_compileIndex);
3451         break;
3452     }
3453         
3454     case PutById: {
3455         SpeculateCellOperand base(this, node.child1());
3456         JSValueOperand value(this, node.child2());
3457         GPRTemporary scratch(this);
3458         
3459         GPRReg baseGPR = base.gpr();
3460         GPRReg valueGPR = value.gpr();
3461         GPRReg scratchGPR = scratch.gpr();
3462         
3463         base.use();
3464         value.use();
3465
3466         cachedPutById(baseGPR, valueGPR, node.child2(), scratchGPR, node.identifierNumber(), NotDirect);
3467         
3468         noResult(m_compileIndex, UseChildrenCalledExplicitly);
3469         break;
3470     }
3471
3472     case PutByIdDirect: {
3473         SpeculateCellOperand base(this, node.child1());
3474         JSValueOperand value(this, node.child2());
3475         GPRTemporary scratch(this);
3476         
3477         GPRReg baseGPR = base.gpr();
3478         GPRReg valueGPR = value.gpr();
3479         GPRReg scratchGPR = scratch.gpr();
3480         
3481         base.use();
3482         value.use();
3483
3484         cachedPutById(baseGPR, valueGPR, node.child2(), scratchGPR, node.identifierNumber(), Direct);
3485
3486         noResult(m_compileIndex, UseChildrenCalledExplicitly);
3487         break;
3488     }
3489
3490     case GetGlobalVar: {
3491         GPRTemporary result(this);
3492
3493         JSVariableObject* globalObject = m_jit.globalObjectFor(node.codeOrigin);
3494         m_jit.loadPtr(globalObject->addressOfRegisters(), result.gpr());
3495         m_jit.loadPtr(JITCompiler::addressForGlobalVar(result.gpr(), node.varNumber()), result.gpr());
3496
3497         jsValueResult(result.gpr(), m_compileIndex);
3498         break;
3499     }
3500
3501     case PutGlobalVar: {
3502         JSValueOperand value(this, node.child1());
3503         GPRTemporary globalObject(this);
3504         GPRTemporary scratch(this);
3505         
3506         GPRReg globalObjectReg = globalObject.gpr();
3507         GPRReg scratchReg = scratch.gpr();
3508
3509         m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), globalObjectReg);
3510
3511         writeBarrier(m_jit.globalObjectFor(node.codeOrigin), value.gpr(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
3512
3513         m_jit.loadPtr(MacroAssembler::Address(globalObjectReg, JSVariableObject::offsetOfRegisters()), scratchReg);
3514         m_jit.storePtr(value.gpr(), JITCompiler::addressForGlobalVar(scratchReg, node.varNumber()));
3515
3516         noResult(m_compileIndex);
3517         break;
3518     }
3519
3520     case CheckHasInstance: {
3521         SpeculateCellOperand base(this, node.child1());
3522         GPRTemporary structure(this);
3523
3524         // Speculate that base 'ImplementsDefaultHasInstance'.
3525         m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
3526         speculationCheck(JSValueRegs(), NoNode, m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
3527
3528         noResult(m_compileIndex);
3529         break;
3530     }
3531
3532     case InstanceOf: {
3533         compileInstanceOf(node);
3534         break;
3535     }
3536
3537     case Phi:
3538     case Flush:
3539         ASSERT_NOT_REACHED();
3540
3541     case Breakpoint:
3542 #if ENABLE(DEBUG_WITH_BREAKPOINT)
3543         m_jit.breakpoint();
3544 #else
3545         ASSERT_NOT_REACHED();
3546 #endif
3547         break;
3548         
3549     case Call:
3550     case Construct:
3551         emitCall(node);
3552         break;
3553
3554     case Resolve: {
3555         flushRegisters();
3556         GPRResult result(this);
3557         callOperation(operationResolve, result.gpr(), identifier(node.identifierNumber()));
3558         jsValueResult(result.gpr(), m_compileIndex);
3559         break;
3560     }
3561
3562     case ResolveBase: {
3563         flushRegisters();
3564         GPRResult result(this);
3565         callOperation(operationResolveBase, result.gpr(), identifier(node.identifierNumber()));
3566         jsValueResult(result.gpr(), m_compileIndex);
3567         break;
3568     }
3569
3570     case ResolveBaseStrictPut: {
3571         flushRegisters();
3572         GPRResult result(this);
3573         callOperation(operationResolveBaseStrictPut, result.gpr(), identifier(node.identifierNumber()));
3574         jsValueResult(result.gpr(), m_compileIndex);
3575         break;
3576     }
3577
3578     case ResolveGlobal: {
3579         GPRTemporary globalObject(this);
3580         GPRTemporary resolveInfo(this);
3581         GPRTemporary result(this);
3582
3583         GPRReg globalObjectGPR = globalObject.gpr();
3584         GPRReg resolveInfoGPR = resolveInfo.gpr();
3585         GPRReg resultGPR = result.gpr();
3586
3587         ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node.resolveGlobalDataIndex()];
3588         GlobalResolveInfo* resolveInfoAddress = &(m_jit.codeBlock()->globalResolveInfo(data.resolveInfoIndex));
3589
3590         // Check Structure of global object
3591         m_jit.move(JITCompiler::TrustedImmPtr(m_jit.globalObjectFor(node.codeOrigin)), globalObjectGPR);
3592         m_jit.move(JITCompiler::TrustedImmPtr(resolveInfoAddress), resolveInfoGPR);
3593         m_jit.loadPtr(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, structure)), resultGPR);
3594         JITCompiler::Jump structuresMatch = m_jit.branchPtr(JITCompiler::Equal, resultGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset()));
3595
3596         silentSpillAllRegisters(resultGPR);
3597         callOperation(operationResolveGlobal, resultGPR, resolveInfoGPR, &m_jit.codeBlock()->identifier(data.identifierNumber));
3598         silentFillAllRegisters(resultGPR);
3599
3600         JITCompiler::Jump wasSlow = m_jit.jump();
3601
3602         // Fast case
3603         structuresMatch.link(&m_jit);
3604         m_jit.loadPtr(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
3605         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR);
3606         m_jit.loadPtr(JITCompiler::BaseIndex(resultGPR, resolveInfoGPR, JITCompiler::ScalePtr), resultGPR);
3607
3608         wasSlow.link(&m_jit);
3609
3610         jsValueResult(resultGPR, m_compileIndex);
3611         break;
3612     }
3613
3614     case ForceOSRExit: {
3615         terminateSpeculativeExecution(JSValueRegs(), NoNode);
3616         break;
3617     }
3618
3619     case Phantom:
3620         // This is a no-op.
3621         noResult(m_compileIndex);
3622         break;
3623         
3624     case InlineStart:
3625         ASSERT_NOT_REACHED();
3626         break;
3627     }
3628
3629     if (node.hasResult() && node.mustGenerate())
3630         use(m_compileIndex);
3631 }
3632
3633 #endif
3634
3635 } } // namespace JSC::DFG
3636
3637 #endif