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