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