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