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