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