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