bd66eb513c27ecf6c5d59657b82ab5917e7addc8
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT32_64.cpp
1 /*
2  * Copyright (C) 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGSpeculativeJIT.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGJITCompilerInlineMethods.h"
32
33 namespace JSC { namespace DFG {
34
35 #if USE(JSVALUE32_64)
36
37 template<bool strict>
38 GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat& returnFormat)
39 {
40 #if ENABLE(DFG_DEBUG_VERBOSE)
41     fprintf(stderr, "SpecInt@%d   ", nodeIndex);
42 #endif
43     Node& node = m_jit.graph()[nodeIndex];
44     VirtualRegister virtualRegister = node.virtualRegister();
45     GenerationInfo& info = m_generationInfo[virtualRegister];
46
47     switch (info.registerFormat()) {
48     case DataFormatNone: {
49         GPRReg gpr = allocate();
50
51         if (node.hasConstant()) {
52             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
53             if (isInt32Constant(nodeIndex)) {
54                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
55                 info.fillInteger(gpr);
56                 returnFormat = DataFormatInteger;
57                 return gpr;
58             }
59             terminateSpeculativeExecution();
60             returnFormat = DataFormatInteger;
61             return allocate();
62         }
63
64         ASSERT(info.spillFormat() & DataFormatJS);
65
66         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
67
68         // If we know this was spilled as an integer we can fill without checking.
69         // FIXME: Currently we always assume strict integers.
70         m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
71         info.fillInteger(gpr);
72         returnFormat = DataFormatInteger;
73         return gpr;
74     }
75
76     case DataFormatJSInteger:
77     case DataFormatJS: {
78         // Check the value is an integer.
79         GPRReg tagGPR = info.tagGPR();
80         GPRReg payloadGPR = info.payloadGPR();
81         m_gprs.lock(tagGPR);
82         m_gprs.lock(payloadGPR);
83         if (info.registerFormat() != DataFormatJSInteger) 
84             speculationCheck(m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)));
85         m_gprs.unlock(tagGPR);
86         m_gprs.release(tagGPR);
87         info.fillInteger(payloadGPR);
88         // If !strict we're done, return.
89         returnFormat = DataFormatInteger;
90         return payloadGPR;
91     }
92
93     case DataFormatInteger: {
94         GPRReg gpr = info.gpr();
95         m_gprs.lock(gpr);
96         returnFormat = DataFormatInteger;
97         return gpr;
98     }
99
100     case DataFormatDouble:
101     case DataFormatCell:
102     case DataFormatBoolean:
103     case DataFormatJSDouble:
104     case DataFormatJSCell:
105     case DataFormatJSBoolean: {
106         terminateSpeculativeExecution();
107         returnFormat = DataFormatInteger;
108         return allocate();
109     }
110
111     case DataFormatStorage:
112         ASSERT_NOT_REACHED();
113     }
114
115     ASSERT_NOT_REACHED();
116     return InvalidGPRReg;
117 }
118
119 GPRReg SpeculativeJIT::fillSpeculateInt(NodeIndex nodeIndex, DataFormat& returnFormat)
120 {
121     return fillSpeculateIntInternal<false>(nodeIndex, returnFormat);
122 }
123
124 GPRReg SpeculativeJIT::fillSpeculateIntStrict(NodeIndex nodeIndex)
125 {
126     DataFormat mustBeDataFormatInteger;
127     GPRReg result = fillSpeculateIntInternal<true>(nodeIndex, mustBeDataFormatInteger);
128     ASSERT(mustBeDataFormatInteger == DataFormatInteger);
129     return result;
130 }
131
132 FPRReg SpeculativeJIT::fillSpeculateDouble(NodeIndex nodeIndex)
133 {
134 #if ENABLE(DFG_DEBUG_VERBOSE)
135     fprintf(stderr, "SpecDouble@%d   ", nodeIndex);
136 #endif
137     Node& node = m_jit.graph()[nodeIndex];
138     VirtualRegister virtualRegister = node.virtualRegister();
139     GenerationInfo& info = m_generationInfo[virtualRegister];
140
141     if (info.registerFormat() == DataFormatNone) {
142
143         if (node.hasConstant()) {
144             if (isInt32Constant(nodeIndex)) {
145                 GPRReg gpr = allocate();
146                 m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
147                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
148                 info.fillInteger(gpr);
149                 unlock(gpr);
150             } else if (isNumberConstant(nodeIndex)) {
151                 FPRReg fpr = fprAllocate();
152                 m_jit.loadDouble(addressOfDoubleConstant(nodeIndex), fpr);
153                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
154                 info.fillDouble(fpr);
155                 return fpr;
156             } else {
157                 terminateSpeculativeExecution();
158                 return fprAllocate();
159             }
160         } else {
161             DataFormat spillFormat = info.spillFormat();
162             ASSERT(spillFormat & DataFormatJS);
163             if (spillFormat == DataFormatJSDouble) {
164                 FPRReg fpr = fprAllocate();
165                 m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
166                 m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
167                 info.fillDouble(fpr);
168                 return fpr;
169             } 
170             GPRReg tag = allocate();
171             GPRReg payload = allocate();
172             m_jit.emitLoad(nodeIndex, tag, payload);
173             m_gprs.retain(tag, virtualRegister, SpillOrderSpilled);
174             m_gprs.retain(payload, virtualRegister, SpillOrderSpilled);
175             info.fillJSValue(tag, payload, spillFormat);
176             unlock(tag);
177             unlock(payload);
178         }
179     }
180
181     switch (info.registerFormat()) {
182     case DataFormatNone:
183     case DataFormatCell:
184     case DataFormatBoolean:
185     case DataFormatStorage:
186         // Should have filled, above.
187         ASSERT_NOT_REACHED();
188         
189     case DataFormatJSCell:
190     case DataFormatJS:
191     case DataFormatJSInteger:
192     case DataFormatJSBoolean: {
193         GPRReg tagGPR = info.tagGPR();
194         GPRReg payloadGPR = info.payloadGPR();
195         FPRReg fpr = fprAllocate();
196
197         m_gprs.lock(tagGPR);
198         m_gprs.lock(payloadGPR);
199
200         JITCompiler::Jump hasUnboxedDouble;
201
202         if (info.registerFormat() != DataFormatJSInteger) {
203             JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag));
204             speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
205             unboxDouble(tagGPR, payloadGPR, fpr, virtualRegister);
206             hasUnboxedDouble = m_jit.jump();
207             isInteger.link(&m_jit);
208         }
209
210         m_jit.convertInt32ToDouble(payloadGPR, fpr);
211
212         if (info.registerFormat() != DataFormatJSInteger)
213             hasUnboxedDouble.link(&m_jit);
214
215         m_gprs.release(tagGPR);
216         m_gprs.release(payloadGPR);
217         m_gprs.unlock(tagGPR);
218         m_gprs.unlock(payloadGPR);
219         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
220         info.fillDouble(fpr);
221         info.killSpilled();
222         return fpr;
223     }
224
225     case DataFormatInteger: {
226         FPRReg fpr = fprAllocate();
227         GPRReg gpr = info.gpr();
228         m_gprs.lock(gpr);
229         m_jit.convertInt32ToDouble(gpr, fpr);
230         m_gprs.unlock(gpr);
231         return fpr;
232     }
233
234     case DataFormatJSDouble:
235     case DataFormatDouble: {
236         FPRReg fpr = info.fpr();
237         m_fprs.lock(fpr);
238         return fpr;
239     }
240     }
241
242     ASSERT_NOT_REACHED();
243     return InvalidFPRReg;
244 }
245
246 GPRReg SpeculativeJIT::fillSpeculateCell(NodeIndex nodeIndex)
247 {
248 #if ENABLE(DFG_DEBUG_VERBOSE)
249     fprintf(stderr, "SpecCell@%d   ", nodeIndex);
250 #endif
251     Node& node = m_jit.graph()[nodeIndex];
252     VirtualRegister virtualRegister = node.virtualRegister();
253     GenerationInfo& info = m_generationInfo[virtualRegister];
254
255     switch (info.registerFormat()) {
256     case DataFormatNone: {
257
258         GPRReg gpr = allocate();
259         if (node.hasConstant()) {
260             JSValue jsValue = valueOfJSConstant(nodeIndex);
261             if (jsValue.isCell()) {
262                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
263                 m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
264                 info.fillCell(gpr);
265                 return gpr;
266             }
267             terminateSpeculativeExecution();
268             return gpr;
269         }
270         ASSERT(info.spillFormat() & DataFormatJS);
271         m_jit.load32(JITCompiler::tagFor(virtualRegister), gpr);
272         if (info.spillFormat() != DataFormatJSCell)
273             speculationCheck(m_jit.branch32(MacroAssembler::NotEqual, gpr, TrustedImm32(JSValue::CellTag)));
274         m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
275         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
276         info.fillCell(gpr);
277         return gpr;
278     }
279
280     case DataFormatCell: {
281         GPRReg gpr = info.gpr();
282         m_gprs.lock(gpr);
283         return gpr;
284     }
285
286     case DataFormatJSCell:
287     case DataFormatJS: {
288         GPRReg tagGPR = info.tagGPR();
289         GPRReg payloadGPR = info.payloadGPR();
290         m_gprs.lock(tagGPR);
291         m_gprs.lock(payloadGPR);
292         if (info.spillFormat() != DataFormatJSCell)
293             speculationCheck(m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::CellTag)));
294         m_gprs.unlock(tagGPR);
295         m_gprs.release(tagGPR);
296         m_gprs.release(payloadGPR);
297         m_gprs.retain(payloadGPR, virtualRegister, SpillOrderCell);
298         info.fillCell(payloadGPR);
299         return payloadGPR;
300     }
301
302     case DataFormatJSInteger:
303     case DataFormatInteger:
304     case DataFormatJSDouble:
305     case DataFormatDouble:
306     case DataFormatJSBoolean:
307     case DataFormatBoolean: {
308         terminateSpeculativeExecution();
309         return allocate();
310     }
311
312     case DataFormatStorage:
313         ASSERT_NOT_REACHED();
314     }
315
316     ASSERT_NOT_REACHED();
317     return InvalidGPRReg;
318 }
319
320 GPRReg SpeculativeJIT::fillSpeculateBoolean(NodeIndex nodeIndex)
321 {
322     ASSERT_NOT_REACHED();
323     UNUSED_PARAM(nodeIndex);
324
325 #if ENABLE(DFG_DEBUG_VERBOSE)
326      fprintf(stderr, "SpecBool@%d   ", nodeIndex);
327 #endif
328     return InvalidGPRReg;
329 }
330
331 JITCompiler::Jump SpeculativeJIT::convertToDouble(JSValueOperand& op, FPRReg result)
332 {
333     JITCompiler::Jump isInteger = m_jit.branch32(MacroAssembler::Equal, op.tagGPR(), TrustedImm32(JSValue::Int32Tag));
334     JITCompiler::Jump notNumber = m_jit.branch32(MacroAssembler::AboveOrEqual, op.payloadGPR(), TrustedImm32(JSValue::LowestTag));
335
336     unboxDouble(op.tagGPR(), op.payloadGPR(), result, m_jit.graph()[op.index()].virtualRegister());
337     JITCompiler::Jump done = m_jit.jump();
338
339     isInteger.link(&m_jit);
340     m_jit.convertInt32ToDouble(op.payloadGPR(), result);
341
342     done.link(&m_jit);
343
344     return notNumber;
345 }
346
347 void SpeculativeJIT::compileObjectEquality(Node& node, void* vptr)
348 {
349     SpeculateCellOperand op1(this, node.child1());
350     SpeculateCellOperand op2(this, node.child2());
351     GPRTemporary resultTag(this, op1);
352     GPRTemporary resultPayload(this, op1);
353     
354     GPRReg op1GPR = op1.gpr();
355     GPRReg op2GPR = op2.gpr();
356     GPRReg resultTagGPR = resultTag.gpr();
357     GPRReg resultPayloadGPR = resultPayload.gpr();
358     
359     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op1GPR), MacroAssembler::TrustedImmPtr(vptr)));
360     speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(op2GPR), MacroAssembler::TrustedImmPtr(vptr)));
361     
362     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
363     m_jit.move(Imm32(1), resultPayloadGPR);
364     MacroAssembler::Jump done = m_jit.jump();
365     falseCase.link(&m_jit);
366     m_jit.move(Imm32(0), resultPayloadGPR);
367     done.link(&m_jit);
368
369     m_jit.move(Imm32(JSValue::BooleanTag), resultTagGPR);
370     jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean);
371 }
372
373 // Returns true if the compare is fused with a subsequent branch.
374 bool SpeculativeJIT::compare(Node& node, MacroAssembler::RelationalCondition condition, MacroAssembler::DoubleCondition doubleCondition, Z_DFGOperation_EJJ operation)
375 {
376     if (compilePeepHoleBranch(node, condition, doubleCondition, operation))
377         return true;
378
379     if (shouldSpeculateFinalObject(node.child1(), node.child2()))
380         compileObjectEquality(node, m_jit.globalData()->jsFinalObjectVPtr);
381     else if (shouldSpeculateArray(node.child1(), node.child2()))
382         compileObjectEquality(node, m_jit.globalData()->jsArrayVPtr);
383     else if (!shouldSpeculateNumber(node.child1()) && !shouldSpeculateNumber(node.child2()))
384         nonSpeculativeNonPeepholeCompare(node, condition, operation);
385     else if ((shouldSpeculateNumber(node.child1()) || shouldSpeculateNumber(node.child2())) && !shouldSpeculateInteger(node.child1(), node.child2())) {
386         // Normal case, not fused to branch.
387         SpeculateDoubleOperand op1(this, node.child1());
388         SpeculateDoubleOperand op2(this, node.child2());
389         GPRTemporary resultTag(this);
390         GPRTemporary resultPayload(this);
391         
392         m_jit.move(Imm32(1), resultPayload.gpr());
393         MacroAssembler::Jump trueCase = m_jit.branchDouble(doubleCondition, op1.fpr(), op2.fpr());
394         m_jit.move(Imm32(0), resultPayload.gpr());
395         trueCase.link(&m_jit);
396
397         m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
398         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
399     } else {
400         // Normal case, not fused to branch.
401         SpeculateIntegerOperand op1(this, node.child1());
402         SpeculateIntegerOperand op2(this, node.child2());
403         GPRTemporary resultTag(this, op1, op2);
404         GPRTemporary resultPayload(this);
405         
406         m_jit.compare32(condition, op1.gpr(), op2.gpr(), resultPayload.gpr());
407         
408         // If we add a DataFormatBool, we should use it here.
409         m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
410         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
411     }
412     
413     return false;
414 }
415
416 void SpeculativeJIT::compileValueAdd(Node& node)
417 {
418     JSValueOperand op1(this, node.child1());
419     JSValueOperand op2(this, node.child2());
420
421     GPRReg op1TagGPR = op1.tagGPR();
422     GPRReg op1PayloadGPR = op1.payloadGPR();
423     GPRReg op2TagGPR = op2.tagGPR();
424     GPRReg op2PayloadGPR = op2.payloadGPR();
425
426     flushRegisters();
427     
428     GPRResult2 resultTag(this);
429     GPRResult resultPayload(this);
430     if (isKnownNotNumber(node.child1()) || isKnownNotNumber(node.child2()))
431         callOperation(operationValueAddNotNumber, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
432     else
433         callOperation(operationValueAdd, resultTag.gpr(), resultPayload.gpr(), op1TagGPR, op1PayloadGPR, op2TagGPR, op2PayloadGPR);
434     
435     jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
436 }
437
438 void SpeculativeJIT::compileLogicalNot(Node& node)
439 {
440     // FIXME: Need to add fast paths for known booleans.
441     JSValueOperand value(this, node.child1());
442     GPRTemporary resultTag(this, value);
443     GPRTemporary resultPayload(this, value, false);
444     speculationCheck(m_jit.branch32(JITCompiler::NotEqual, value.tagGPR(), TrustedImm32(JSValue::BooleanTag)));
445     m_jit.move(value.payloadGPR(), resultPayload.gpr());
446     m_jit.xor32(TrustedImm32(1), resultPayload.gpr());
447     m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTag.gpr());
448
449     // If we add a DataFormatBool, we should use it here.
450     jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex, DataFormatJSBoolean);
451
452     // This code is moved from nonSpeculativeLogicalNot, currently unused!
453 #if 0
454     JSValueOperand arg1(this, node.child1());
455     GPRTemporary resultTag(this, arg1);
456     GPRTemporary resultPayload(this, arg1, false);
457     GPRReg arg1TagGPR = arg1.tagGPR();
458     GPRReg arg1PayloadGPR = arg1.payloadGPR();
459     GPRReg resultTagGPR = resultTag.gpr();
460     GPRReg resultPayloadGPR = resultPayload.gpr();
461         
462     arg1.use();
463
464     JITCompiler::Jump fastCase = m_jit.branch32(JITCompiler::Equal, arg1TagGPR, TrustedImm32(JSValue::BooleanTag));
465         
466     silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
467     m_jit.push(arg1TagGPR);
468     m_jit.push(arg1PayloadGPR);
469     m_jit.push(GPRInfo::callFrameRegister);
470     appendCallWithExceptionCheck(dfgConvertJSValueToBoolean);
471     m_jit.move(GPRInfo::returnValueGPR, resultPayloadGPR);
472     silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
473     JITCompiler::Jump doNot = m_jit.jump();
474         
475     fastCase.link(&m_jit);
476     m_jit.move(arg1PayloadGPR, resultPayloadGPR);
477
478     doNot.link(&m_jit);
479     m_jit.xor32(TrustedImm32(1), resultPayloadGPR);
480     m_jit.move(TrustedImm32(JSValue::BooleanTag), resultTagGPR);
481     jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, DataFormatJSBoolean, UseChildrenCalledExplicitly);
482 #endif
483 }
484
485 void SpeculativeJIT::compile(Node& node)
486 {
487     NodeType op = node.op;
488
489     switch (op) {
490     case JSConstant:
491         initConstantInfo(m_compileIndex);
492         break;
493
494     case GetLocal: {
495         PredictedType prediction = node.variableAccessData()->prediction();
496
497         // If we have no prediction for this local, then don't attempt to compile.
498         if (prediction == PredictNone) {
499             terminateSpeculativeExecution();
500             break;
501         }
502         
503         GPRTemporary result(this);
504         if (isInt32Prediction(prediction)) {
505             m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
506
507             // Like integerResult, but don't useChildren - our children are phi nodes,
508             // and don't represent values within this dataflow with virtual registers.
509             VirtualRegister virtualRegister = node.virtualRegister();
510             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
511             m_generationInfo[virtualRegister].initInteger(m_compileIndex, node.refCount(), result.gpr());
512             break;
513         }
514
515         GPRTemporary tag(this);
516         m_jit.load32(JITCompiler::payloadFor(node.local()), result.gpr());
517         m_jit.load32(JITCompiler::tagFor(node.local()), tag.gpr());
518
519         // Like jsValueResult, but don't useChildren - our children are phi nodes,
520         // and don't represent values within this dataflow with virtual registers.
521         VirtualRegister virtualRegister = node.virtualRegister();
522         m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
523         m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
524
525         DataFormat format;
526         if (isArrayPrediction(prediction))
527             format = DataFormatJSCell;
528         else if (isBooleanPrediction(prediction))
529             format = DataFormatJSBoolean;
530         else
531             format = DataFormatJS;
532
533         m_generationInfo[virtualRegister].initJSValue(m_compileIndex, node.refCount(), tag.gpr(), result.gpr(), format);
534         break;
535     }
536
537     case SetLocal: {
538         // SetLocal doubles as a hint as to where a node will be stored and
539         // as a speculation point. So before we speculate make sure that we
540         // know where the child of this node needs to go in the virtual
541         // register file.
542         compileMovHint(node);
543         
544         // As far as OSR is concerned, we're on the bytecode index corresponding
545         // to the *next* instruction, since we've already "executed" the
546         // SetLocal and whatever other DFG Nodes are associated with the same
547         // bytecode index as the SetLocal.
548         ASSERT(m_bytecodeIndexForOSR == node.codeOrigin.bytecodeIndex());
549         Node& nextNode = m_jit.graph()[m_compileIndex+1];
550         
551         // This assertion will fail if we ever emit multiple SetLocal's for
552         // a single bytecode instruction. That's unlikely to happen. But if
553         // it does, the solution is to to have this perform a search until
554         // it finds a Node with a different bytecode index from the one we've
555         // got, and to abstractly execute the SetLocal's along the way. Or,
556         // better yet, handle all of the SetLocal's at once: abstract interpret
557         // all of them, then emit code for all of them, with OSR exiting to
558         // the next non-SetLocal instruction. Note the special case for when
559         // both this SetLocal and the next op have a bytecode index of 0; this
560         // occurs for SetLocal's generated at the top of the code block to
561         // initialize locals to undefined. Ideally, we'd have a way of marking
562         // in the CodeOrigin that a SetLocal is synthetic. This will make the
563         // assertion more sensible-looking. We should then also assert that
564         // synthetic SetLocal's don't have speculation checks, since they
565         // should only be dropping values that we statically know we are
566         // allowed to drop into the variables. DFGPropagator will guarantee
567         // this, since it should have at least an approximation (if not
568         // exact knowledge) of the type of the SetLocal's child node, and
569         // should merge that information into the local that is being set.
570         ASSERT(m_bytecodeIndexForOSR != nextNode.codeOrigin.bytecodeIndex()
571                || (!m_bytecodeIndexForOSR && !nextNode.codeOrigin.bytecodeIndex()));
572         m_bytecodeIndexForOSR = nextNode.codeOrigin.bytecodeIndex();
573         
574         PredictedType predictedType = node.variableAccessData()->prediction();
575         if (isInt32Prediction(predictedType)) {
576             SpeculateIntegerOperand value(this, node.child1());
577             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node.local()));
578             noResult(m_compileIndex);
579         } else if (isArrayPrediction(predictedType)) {
580             SpeculateCellOperand cell(this, node.child1());
581             GPRReg cellGPR = cell.gpr();
582             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(cellGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
583             m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node.local()));
584             noResult(m_compileIndex);
585         } else { // FIXME: Add BooleanPrediction handling
586             JSValueOperand value(this, node.child1());
587             m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node.local()));
588             m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node.local()));
589             noResult(m_compileIndex);
590         }
591
592         // Indicate that it's no longer necessary to retrieve the value of
593         // this bytecode variable from registers or other locations in the register file.
594         valueSourceReferenceForOperand(node.local()) = ValueSource::forPrediction(predictedType);
595         break;
596     }
597
598     case SetArgument:
599         // This is a no-op; it just marks the fact that the argument is being used.
600         // But it may be profitable to use this as a hook to run speculation checks
601         // on arguments, thereby allowing us to trivially eliminate such checks if
602         // the argument is not used.
603         break;
604
605     case BitAnd:
606     case BitOr:
607     case BitXor:
608         if (isInt32Constant(node.child1())) {
609             SpeculateIntegerOperand op2(this, node.child2());
610             GPRTemporary result(this, op2);
611
612             bitOp(op, valueOfInt32Constant(node.child1()), op2.gpr(), result.gpr());
613
614             integerResult(result.gpr(), m_compileIndex);
615         } else if (isInt32Constant(node.child2())) {
616             SpeculateIntegerOperand op1(this, node.child1());
617             GPRTemporary result(this, op1);
618
619             bitOp(op, valueOfInt32Constant(node.child2()), op1.gpr(), result.gpr());
620
621             integerResult(result.gpr(), m_compileIndex);
622         } else {
623             SpeculateIntegerOperand op1(this, node.child1());
624             SpeculateIntegerOperand op2(this, node.child2());
625             GPRTemporary result(this, op1, op2);
626
627             GPRReg reg1 = op1.gpr();
628             GPRReg reg2 = op2.gpr();
629             bitOp(op, reg1, reg2, result.gpr());
630
631             integerResult(result.gpr(), m_compileIndex);
632         }
633         break;
634
635     case BitRShift:
636     case BitLShift:
637     case BitURShift:
638         if (isInt32Constant(node.child2())) {
639             SpeculateIntegerOperand op1(this, node.child1());
640             GPRTemporary result(this, op1);
641
642             shiftOp(op, op1.gpr(), valueOfInt32Constant(node.child2()) & 0x1f, result.gpr());
643
644             integerResult(result.gpr(), m_compileIndex);
645         } else {
646             // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
647             SpeculateIntegerOperand op1(this, node.child1());
648             SpeculateIntegerOperand op2(this, node.child2());
649             GPRTemporary result(this, op1);
650
651             GPRReg reg1 = op1.gpr();
652             GPRReg reg2 = op2.gpr();
653             shiftOp(op, reg1, reg2, result.gpr());
654
655             integerResult(result.gpr(), m_compileIndex);
656         }
657         break;
658
659     case UInt32ToNumber: {
660         if (!nodeCanSpeculateInteger(node.arithNodeFlags())) {
661             // We know that this sometimes produces doubles. So produce a double every
662             // time. This at least allows subsequent code to not have weird conditionals.
663             
664             IntegerOperand op1(this, node.child1());
665             FPRTemporary result(this);
666             
667             GPRReg inputGPR = op1.gpr();
668             FPRReg outputFPR = result.fpr();
669             
670             m_jit.convertInt32ToDouble(inputGPR, outputFPR);
671             
672             JITCompiler::Jump positive = m_jit.branch32(MacroAssembler::GreaterThanOrEqual, inputGPR, TrustedImm32(0));
673             m_jit.addDouble(JITCompiler::AbsoluteAddress(&twoToThe32), outputFPR);
674             positive.link(&m_jit);
675             
676             doubleResult(outputFPR, m_compileIndex);
677         }
678
679         IntegerOperand op1(this, node.child1());
680         GPRTemporary result(this, op1);
681
682         // Test the operand is positive.
683         speculationCheck(m_jit.branch32(MacroAssembler::LessThan, op1.gpr(), TrustedImm32(0)));
684
685         m_jit.move(op1.gpr(), result.gpr());
686         integerResult(result.gpr(), m_compileIndex, op1.format());
687         break;
688     }
689
690     case ValueToInt32: {
691         if (shouldNotSpeculateInteger(node.child1())) {
692             // Do it the safe way.
693             nonSpeculativeValueToInt32(node);
694             break;
695         }
696         
697         if (shouldNotSpeculateInteger(node.child1())) {
698             // Do it the safe way.
699             nonSpeculativeValueToInt32(node);
700             break;
701         }
702         
703         SpeculateIntegerOperand op1(this, node.child1());
704         GPRTemporary result(this, op1);
705         m_jit.move(op1.gpr(), result.gpr());
706         integerResult(result.gpr(), m_compileIndex, op1.format());
707         break;
708     }
709
710     case ValueToNumber: {
711         if (shouldNotSpeculateInteger(node.child1())) {
712             SpeculateDoubleOperand op1(this, node.child1());
713             FPRTemporary result(this, op1);
714             m_jit.moveDouble(op1.fpr(), result.fpr());
715             doubleResult(result.fpr(), m_compileIndex);
716             break;
717         }
718         
719         SpeculateIntegerOperand op1(this, node.child1());
720         GPRTemporary result(this, op1);
721         m_jit.move(op1.gpr(), result.gpr());
722         integerResult(result.gpr(), m_compileIndex, op1.format());
723         break;
724     }
725
726     case ValueToDouble: {
727         SpeculateDoubleOperand op1(this, node.child1());
728         FPRTemporary result(this, op1);
729         m_jit.moveDouble(op1.fpr(), result.fpr());
730         doubleResult(result.fpr(), m_compileIndex);
731         break;
732     }
733
734     case ValueAdd:
735     case ArithAdd: {
736         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
737             if (isInt32Constant(node.child1())) {
738                 int32_t imm1 = valueOfInt32Constant(node.child1());
739                 SpeculateIntegerOperand op2(this, node.child2());
740                 GPRTemporary result(this);
741
742                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
743                     m_jit.move(op2.gpr(), result.gpr());
744                     m_jit.add32(Imm32(imm1), result.gpr());
745                 } else
746                     speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op2.gpr(), Imm32(imm1), result.gpr()));
747
748                 integerResult(result.gpr(), m_compileIndex);
749                 break;
750             }
751                 
752             if (isInt32Constant(node.child2())) {
753                 SpeculateIntegerOperand op1(this, node.child1());
754                 int32_t imm2 = valueOfInt32Constant(node.child2());
755                 GPRTemporary result(this);
756                 
757                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
758                     m_jit.move(op1.gpr(), result.gpr());
759                     m_jit.add32(Imm32(imm2), result.gpr());
760                 } else
761                     speculationCheck(m_jit.branchAdd32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
762
763                 integerResult(result.gpr(), m_compileIndex);
764                 break;
765             }
766                 
767             SpeculateIntegerOperand op1(this, node.child1());
768             SpeculateIntegerOperand op2(this, node.child2());
769             GPRTemporary result(this, op1, op2);
770
771             GPRReg gpr1 = op1.gpr();
772             GPRReg gpr2 = op2.gpr();
773             GPRReg gprResult = result.gpr();
774
775             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
776                 if (gpr1 == gprResult)
777                     m_jit.add32(gpr2, gprResult);
778                 else {
779                     m_jit.move(gpr2, gprResult);
780                     m_jit.add32(gpr1, gprResult);
781                 }
782             } else {
783                 MacroAssembler::Jump check = m_jit.branchAdd32(MacroAssembler::Overflow, gpr1, gpr2, gprResult);
784                 
785                 if (gpr1 == gprResult)
786                     speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr2));
787                 else if (gpr2 == gprResult)
788                     speculationCheck(check, SpeculationRecovery(SpeculativeAdd, gprResult, gpr1));
789                 else
790                     speculationCheck(check);
791             }
792
793             integerResult(gprResult, m_compileIndex);
794             break;
795         }
796         
797         if (shouldSpeculateNumber(node.child1(), node.child2())) {
798             SpeculateDoubleOperand op1(this, node.child1());
799             SpeculateDoubleOperand op2(this, node.child2());
800             FPRTemporary result(this, op1, op2);
801
802             FPRReg reg1 = op1.fpr();
803             FPRReg reg2 = op2.fpr();
804             m_jit.addDouble(reg1, reg2, result.fpr());
805
806             doubleResult(result.fpr(), m_compileIndex);
807             break;
808         }
809
810         ASSERT(op == ValueAdd);
811         compileValueAdd(node);
812         break;
813     }
814
815     case ArithSub: {
816         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
817             if (isInt32Constant(node.child2())) {
818                 SpeculateIntegerOperand op1(this, node.child1());
819                 int32_t imm2 = valueOfInt32Constant(node.child2());
820                 GPRTemporary result(this);
821
822                 if (nodeCanTruncateInteger(node.arithNodeFlags())) {
823                     m_jit.move(op1.gpr(), result.gpr());
824                     m_jit.sub32(Imm32(imm2), result.gpr());
825                 } else
826                     speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), Imm32(imm2), result.gpr()));
827
828                 integerResult(result.gpr(), m_compileIndex);
829                 break;
830             }
831                 
832             SpeculateIntegerOperand op1(this, node.child1());
833             SpeculateIntegerOperand op2(this, node.child2());
834             GPRTemporary result(this);
835
836             if (nodeCanTruncateInteger(node.arithNodeFlags())) {
837                 m_jit.move(op1.gpr(), result.gpr());
838                 m_jit.sub32(op2.gpr(), result.gpr());
839             } else
840                 speculationCheck(m_jit.branchSub32(MacroAssembler::Overflow, op1.gpr(), op2.gpr(), result.gpr()));
841
842             integerResult(result.gpr(), m_compileIndex);
843             break;
844         }
845         
846         SpeculateDoubleOperand op1(this, node.child1());
847         SpeculateDoubleOperand op2(this, node.child2());
848         FPRTemporary result(this, op1);
849
850         FPRReg reg1 = op1.fpr();
851         FPRReg reg2 = op2.fpr();
852         m_jit.subDouble(reg1, reg2, result.fpr());
853
854         doubleResult(result.fpr(), m_compileIndex);
855         break;
856     }
857
858     case ArithMul: {
859         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
860             SpeculateIntegerOperand op1(this, node.child1());
861             SpeculateIntegerOperand op2(this, node.child2());
862             GPRTemporary result(this);
863
864             GPRReg reg1 = op1.gpr();
865             GPRReg reg2 = op2.gpr();
866
867             // What is unfortunate is that we cannot take advantage of nodeCanTruncateInteger()
868             // here. A multiply on integers performed in the double domain and then truncated to
869             // an integer will give a different result than a multiply performed in the integer
870             // domain and then truncated, if the integer domain result would have resulted in
871             // something bigger than what a 32-bit integer can hold. JavaScript mandates that
872             // the semantics are always as if the multiply had been performed in the double
873             // domain.
874             
875             speculationCheck(m_jit.branchMul32(MacroAssembler::Overflow, reg1, reg2, result.gpr()));
876             
877             // Check for negative zero, if the users of this node care about such things.
878             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
879                 MacroAssembler::Jump resultNonZero = m_jit.branchTest32(MacroAssembler::NonZero, result.gpr());
880                 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg1, TrustedImm32(0)));
881                 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, reg2, TrustedImm32(0)));
882                 resultNonZero.link(&m_jit);
883             }
884
885             integerResult(result.gpr(), m_compileIndex);
886             break;
887         }
888
889         SpeculateDoubleOperand op1(this, node.child1());
890         SpeculateDoubleOperand op2(this, node.child2());
891         FPRTemporary result(this, op1, op2);
892
893         FPRReg reg1 = op1.fpr();
894         FPRReg reg2 = op2.fpr();
895         
896         m_jit.mulDouble(reg1, reg2, result.fpr());
897         
898         doubleResult(result.fpr(), m_compileIndex);
899         break;
900     }
901
902     case ArithDiv: {
903         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
904             SpeculateIntegerOperand op1(this, node.child1());
905             SpeculateIntegerOperand op2(this, node.child2());
906             GPRTemporary eax(this, X86Registers::eax);
907             GPRTemporary edx(this, X86Registers::edx);
908             GPRReg op1GPR = op1.gpr();
909             GPRReg op2GPR = op2.gpr();
910             
911             speculationCheck(m_jit.branchTest32(JITCompiler::Zero, op2GPR));
912             
913             // If the user cares about negative zero, then speculate that we're not about
914             // to produce negative zero.
915             if (!nodeCanIgnoreNegativeZero(node.arithNodeFlags())) {
916                 MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR);
917                 speculationCheck(m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0)));
918                 numeratorNonZero.link(&m_jit);
919             }
920             
921             GPRReg temp2 = InvalidGPRReg;
922             if (op2GPR == X86Registers::eax || op2GPR == X86Registers::edx) {
923                 temp2 = allocate();
924                 m_jit.move(op2GPR, temp2);
925                 op2GPR = temp2;
926             }
927             
928             m_jit.move(op1GPR, eax.gpr());
929             m_jit.assembler().cdq();
930             m_jit.assembler().idivl_r(op2GPR);
931             
932             if (temp2 != InvalidGPRReg)
933                 unlock(temp2);
934
935             // Check that there was no remainder. If there had been, then we'd be obligated to
936             // produce a double result instead.
937             speculationCheck(m_jit.branchTest32(JITCompiler::NonZero, edx.gpr()));
938             
939             integerResult(eax.gpr(), m_compileIndex);
940             break;
941         }
942         
943         SpeculateDoubleOperand op1(this, node.child1());
944         SpeculateDoubleOperand op2(this, node.child2());
945         FPRTemporary result(this, op1);
946
947         FPRReg reg1 = op1.fpr();
948         FPRReg reg2 = op2.fpr();
949         m_jit.divDouble(reg1, reg2, result.fpr());
950
951         doubleResult(result.fpr(), m_compileIndex);
952         break;
953     }
954
955     case ArithMod: {
956         if (shouldNotSpeculateInteger(node.child1()) || shouldNotSpeculateInteger(node.child2())
957             || !nodeCanSpeculateInteger(node.arithNodeFlags())) {
958             SpeculateDoubleOperand op1(this, node.child1());
959             SpeculateDoubleOperand op2(this, node.child2());
960             
961             FPRReg op1FPR = op1.fpr();
962             FPRReg op2FPR = op2.fpr();
963             
964             flushRegisters();
965             
966             FPRResult result(this);
967
968             callOperation(fmod, result.fpr(), op1FPR, op2FPR);
969             
970             doubleResult(result.fpr(), m_compileIndex);
971             break;
972         }
973         
974         SpeculateIntegerOperand op1(this, node.child1());
975         SpeculateIntegerOperand op2(this, node.child2());
976         GPRTemporary eax(this, X86Registers::eax);
977         GPRTemporary edx(this, X86Registers::edx);
978         GPRReg op1Gpr = op1.gpr();
979         GPRReg op2Gpr = op2.gpr();
980
981         speculationCheck(m_jit.branchTest32(JITCompiler::Zero, op2Gpr));
982
983         GPRReg temp2 = InvalidGPRReg;
984         if (op2Gpr == X86Registers::eax || op2Gpr == X86Registers::edx) {
985             temp2 = allocate();
986             m_jit.move(op2Gpr, temp2);
987             op2Gpr = temp2;
988         }
989
990         m_jit.move(op1Gpr, eax.gpr());
991         m_jit.assembler().cdq();
992         m_jit.assembler().idivl_r(op2Gpr);
993
994         if (temp2 != InvalidGPRReg)
995             unlock(temp2);
996
997         integerResult(edx.gpr(), m_compileIndex);
998         break;
999     }
1000
1001     case ArithAbs: {
1002         if (shouldSpeculateInteger(node.child1()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1003             SpeculateIntegerOperand op1(this, node.child1());
1004             GPRTemporary result(this, op1);
1005             GPRTemporary scratch(this);
1006             
1007             m_jit.zeroExtend32ToPtr(op1.gpr(), result.gpr());
1008             m_jit.rshift32(result.gpr(), MacroAssembler::TrustedImm32(31), scratch.gpr());
1009             m_jit.add32(scratch.gpr(), result.gpr());
1010             m_jit.xor32(scratch.gpr(), result.gpr());
1011             speculationCheck(m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
1012             integerResult(result.gpr(), m_compileIndex);
1013             break;
1014         }
1015         
1016         SpeculateDoubleOperand op1(this, node.child1());
1017         FPRTemporary result(this);
1018         
1019         static const double negativeZeroConstant = -0.0;
1020         
1021         m_jit.loadDouble(&negativeZeroConstant, result.fpr());
1022         m_jit.andnotDouble(op1.fpr(), result.fpr());
1023         doubleResult(result.fpr(), m_compileIndex);
1024         break;
1025     }
1026         
1027     case ArithMin:
1028     case ArithMax: {
1029         if (shouldSpeculateInteger(node.child1(), node.child2()) && nodeCanSpeculateInteger(node.arithNodeFlags())) {
1030             SpeculateStrictInt32Operand op1(this, node.child1());
1031             SpeculateStrictInt32Operand op2(this, node.child2());
1032             GPRTemporary result(this, op1);
1033             
1034             MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr());
1035             m_jit.move(op2.gpr(), result.gpr());
1036             if (op1.gpr() != result.gpr()) {
1037                 MacroAssembler::Jump done = m_jit.jump();
1038                 op1Less.link(&m_jit);
1039                 m_jit.move(op1.gpr(), result.gpr());
1040                 done.link(&m_jit);
1041             } else
1042                 op1Less.link(&m_jit);
1043             
1044             integerResult(result.gpr(), m_compileIndex);
1045             break;
1046         }
1047         
1048         SpeculateDoubleOperand op1(this, node.child1());
1049         SpeculateDoubleOperand op2(this, node.child2());
1050         FPRTemporary result(this, op1);
1051         
1052         MacroAssembler::JumpList done;
1053         
1054         MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1.fpr(), op2.fpr());
1055         
1056         // op2 is eather the lesser one or one of then is NaN
1057         MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThan : MacroAssembler::DoubleLessThan, op1.fpr(), op2.fpr());
1058         
1059         // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding 
1060         // op1 + op2 and putting it into result.
1061         m_jit.addDouble(op1.fpr(), op2.fpr(), result.fpr());
1062         done.append(m_jit.jump());
1063         
1064         op2Less.link(&m_jit);
1065         m_jit.moveDouble(op2.fpr(), result.fpr());
1066         
1067         if (op1.fpr() != result.fpr()) {
1068             done.append(m_jit.jump());
1069             
1070             op1Less.link(&m_jit);
1071             m_jit.moveDouble(op1.fpr(), result.fpr());
1072         } else
1073             op1Less.link(&m_jit);
1074         
1075         done.link(&m_jit);
1076         
1077         doubleResult(result.fpr(), m_compileIndex);
1078         break;
1079     }
1080         
1081     case ArithSqrt: {
1082         SpeculateDoubleOperand op1(this, node.child1());
1083         FPRTemporary result(this, op1);
1084         
1085         m_jit.sqrtDouble(op1.fpr(), result.fpr());
1086         
1087         doubleResult(result.fpr(), m_compileIndex);
1088         break;
1089     }
1090
1091     case LogicalNot:
1092         compileLogicalNot(node);
1093         break;
1094
1095     case CompareLess:
1096         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
1097             return;
1098         break;
1099
1100     case CompareLessEq:
1101         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
1102             return;
1103         break;
1104
1105     case CompareGreater:
1106         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
1107             return;
1108         break;
1109
1110     case CompareGreaterEq:
1111         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
1112             return;
1113         break;
1114
1115     case CompareEq:
1116         if (isNullConstant(node.child1())) {
1117             if (nonSpeculativeCompareNull(node, node.child2()))
1118                 return;
1119             break;
1120         }
1121         if (isNullConstant(node.child2())) {
1122             if (nonSpeculativeCompareNull(node, node.child1()))
1123                 return;
1124             break;
1125         }
1126         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
1127             return;
1128         break;
1129
1130     case CompareStrictEq:
1131         if (nonSpeculativeStrictEq(node))
1132             return;
1133         break;
1134
1135     case GetByVal: {
1136         ASSERT(node.child3() == NoNode);
1137         SpeculateCellOperand base(this, node.child1());
1138         SpeculateStrictInt32Operand property(this, node.child2());
1139         GPRTemporary storage(this);
1140         GPRTemporary resultTag(this, base);
1141
1142         GPRReg baseReg = base.gpr();
1143         GPRReg propertyReg = property.gpr();
1144         GPRReg storageReg = storage.gpr();
1145         
1146         if (!m_compileOkay)
1147             return;
1148
1149         // Get the array storage. We haven't yet checked this is a JSArray, so this is only safe if
1150         // an access with offset JSArray::storageOffset() is valid for all JSCells!
1151         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1152
1153         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
1154         // If we have predicted the base to be type array, we can skip the check.
1155         if (!isKnownArray(node.child1()))
1156             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1157         speculationCheck(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset())));
1158
1159         // FIXME: In cases where there are subsequent by_val accesses to the same base it might help to cache
1160         // the storage pointer - especially if there happens to be another register free right now. If we do so,
1161         // then we'll need to allocate a new temporary for result.
1162         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
1163         speculationCheck(m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
1164         m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), storageReg);
1165
1166         jsValueResult(resultTag.gpr(), storageReg, m_compileIndex);
1167         break;
1168     }
1169
1170     case PutByVal: {
1171         SpeculateCellOperand base(this, node.child1());
1172         SpeculateStrictInt32Operand property(this, node.child2());
1173         JSValueOperand value(this, node.child3());
1174         GPRTemporary scratch(this);
1175
1176         // Map base, property & value into registers, allocate a scratch register.
1177         GPRReg baseReg = base.gpr();
1178         GPRReg propertyReg = property.gpr();
1179         GPRReg valueTagReg = value.tagGPR();
1180         GPRReg valuePayloadReg = value.payloadGPR();
1181         GPRReg scratchReg = scratch.gpr();
1182         
1183         if (!m_compileOkay)
1184             return;
1185         
1186         writeBarrier(baseReg, valueTagReg, node.child3(), WriteBarrierForPropertyAccess, scratchReg);
1187
1188         // Check that base is an array, and that property is contained within m_vector (< m_vectorLength).
1189         // If we have predicted the base to be type array, we can skip the check.
1190         if (!isKnownArray(node.child1()))
1191             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseReg), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1192
1193         base.use();
1194         property.use();
1195         value.use();
1196         
1197         MacroAssembler::Jump withinArrayBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(baseReg, JSArray::vectorLengthOffset()));
1198
1199         // Code to handle put beyond array bounds.
1200         silentSpillAllRegisters(scratchReg);
1201         m_jit.push(valueTagReg);
1202         m_jit.push(valuePayloadReg);
1203         m_jit.push(propertyReg);
1204         m_jit.push(baseReg);
1205         m_jit.push(GPRInfo::callFrameRegister);
1206         JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationPutByValBeyondArrayBounds);
1207         silentFillAllRegisters(scratchReg);
1208         JITCompiler::Jump wasBeyondArrayBounds = m_jit.jump();
1209
1210         withinArrayBounds.link(&m_jit);
1211
1212         // Get the array storage.
1213         GPRReg storageReg = scratchReg;
1214         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1215
1216         // Check if we're writing to a hole; if so increment m_numValuesInVector.
1217         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));
1218         m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
1219
1220         // If we're writing to a hole we might be growing the array; 
1221         MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
1222         m_jit.add32(TrustedImm32(1), propertyReg);
1223         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, OBJECT_OFFSETOF(ArrayStorage, m_length)));
1224         m_jit.sub32(TrustedImm32(1), propertyReg);
1225
1226         lengthDoesNotNeedUpdate.link(&m_jit);
1227         notHoleValue.link(&m_jit);
1228
1229         // Store the value to the array.
1230         m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
1231         m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
1232
1233         wasBeyondArrayBounds.link(&m_jit);
1234
1235         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1236         break;
1237     }
1238
1239     case PutByValAlias: {
1240         SpeculateCellOperand base(this, node.child1());
1241         SpeculateStrictInt32Operand property(this, node.child2());
1242         JSValueOperand value(this, node.child3());
1243         GPRTemporary scratch(this, base);
1244         
1245         GPRReg baseReg = base.gpr();
1246         GPRReg scratchReg = scratch.gpr();
1247
1248         writeBarrier(baseReg, value.tagGPR(), node.child3(), WriteBarrierForPropertyAccess, scratchReg);
1249
1250         // Get the array storage.
1251         GPRReg storageReg = scratchReg;
1252         m_jit.loadPtr(MacroAssembler::Address(baseReg, JSArray::storageOffset()), storageReg);
1253
1254         // Store the value to the array.
1255         GPRReg propertyReg = property.gpr();
1256         m_jit.store32(value.tagGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
1257         m_jit.store32(value.payloadGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
1258
1259         noResult(m_compileIndex);
1260         break;
1261     }
1262
1263     case DFG::Jump: {
1264         BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1265         if (taken != (m_block + 1))
1266             addBranch(m_jit.jump(), taken);
1267         noResult(m_compileIndex);
1268         break;
1269     }
1270
1271     case Branch:
1272         if (isStrictInt32(node.child1()) || shouldSpeculateInteger(node.child1())) {
1273             SpeculateIntegerOperand op(this, node.child1());
1274             
1275             BlockIndex taken = m_jit.graph().blockIndexForBytecodeOffset(node.takenBytecodeOffset());
1276             BlockIndex notTaken = m_jit.graph().blockIndexForBytecodeOffset(node.notTakenBytecodeOffset());
1277             
1278             MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1279             
1280             if (taken == (m_block + 1)) {
1281                 condition = MacroAssembler::Zero;
1282                 BlockIndex tmp = taken;
1283                 taken = notTaken;
1284                 notTaken = tmp;
1285             }
1286             
1287             addBranch(m_jit.branchTest32(condition, op.gpr()), taken);
1288             if (notTaken != (m_block + 1))
1289                 addBranch(m_jit.jump(), notTaken);
1290             
1291             noResult(m_compileIndex);
1292             break;
1293         }
1294         emitBranch(node);
1295         break;
1296
1297     case Return: {
1298         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT2);
1299         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
1300         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
1301
1302 #if ENABLE(DFG_SUCCESS_STATS)
1303         static SamplingCounter counter("SpeculativeJIT");
1304         m_jit.emitCount(counter);
1305 #endif
1306
1307         // Return the result in returnValueGPR.
1308         JSValueOperand op1(this, node.child1());
1309         op1.fill();
1310         if (op1.isDouble())
1311             boxDouble(op1.fpr(), GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR, m_jit.graph()[op1.index()].virtualRegister());
1312         else {
1313             if (op1.payloadGPR() == GPRInfo::returnValueGPR2 && op1.tagGPR() == GPRInfo::returnValueGPR)
1314                 m_jit.swap(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1315             else if (op1.payloadGPR() == GPRInfo::returnValueGPR2) {
1316                 m_jit.move(op1.payloadGPR(), GPRInfo::returnValueGPR);
1317                 m_jit.move(op1.tagGPR(), GPRInfo::returnValueGPR2);
1318             } else {
1319                 m_jit.move(op1.tagGPR(), GPRInfo::returnValueGPR2);
1320                 m_jit.move(op1.payloadGPR(), GPRInfo::returnValueGPR);
1321             }
1322         }
1323
1324         // Grab the return address.
1325         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, GPRInfo::regT2);
1326         // Restore our caller's "r".
1327         m_jit.emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, GPRInfo::callFrameRegister);
1328         // Return.
1329         m_jit.restoreReturnAddressBeforeReturn(GPRInfo::regT2);
1330         m_jit.ret();
1331         
1332         noResult(m_compileIndex);
1333         break;
1334     }
1335         
1336     case Throw:
1337     case ThrowReferenceError: {
1338         // We expect that throw statements are rare and are intended to exit the code block
1339         // anyway, so we just OSR back to the old JIT for now.
1340         terminateSpeculativeExecution();
1341         break;
1342     }
1343         
1344     case ToPrimitive: {
1345         if (shouldSpeculateInteger(node.child1())) {
1346             // It's really profitable to speculate integer, since it's really cheap,
1347             // it means we don't have to do any real work, and we emit a lot less code.
1348             
1349             SpeculateIntegerOperand op1(this, node.child1());
1350             GPRTemporary result(this, op1);
1351             
1352             ASSERT(op1.format() == DataFormatInteger);
1353             m_jit.move(op1.gpr(), result.gpr());
1354             
1355             integerResult(result.gpr(), m_compileIndex);
1356             break;
1357         }
1358         
1359         // FIXME: Add string speculation here.
1360         
1361         bool wasPrimitive = isKnownNumeric(node.child1()) || isKnownBoolean(node.child1());
1362         
1363         JSValueOperand op1(this, node.child1());
1364         GPRTemporary resultTag(this, op1);
1365         GPRTemporary resultPayload(this, op1, false);
1366         
1367         GPRReg op1TagGPR = op1.tagGPR();
1368         GPRReg op1PayloadGPR = op1.payloadGPR();
1369         GPRReg resultTagGPR = resultTag.gpr();
1370         GPRReg resultPayloadGPR = resultPayload.gpr();
1371         
1372         op1.use();
1373         
1374         if (wasPrimitive) {
1375             m_jit.move(op1TagGPR, resultTagGPR);
1376             m_jit.move(op1PayloadGPR, resultPayloadGPR);
1377         } else {
1378             MacroAssembler::JumpList alreadyPrimitive;
1379             
1380             alreadyPrimitive.append(m_jit.branch32(MacroAssembler::NotEqual, op1TagGPR, TrustedImm32(JSValue::CellTag)));
1381             alreadyPrimitive.append(m_jit.branchPtr(MacroAssembler::Equal, MacroAssembler::Address(op1PayloadGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
1382             
1383             silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
1384             m_jit.push(op1TagGPR);
1385             m_jit.push(op1PayloadGPR);
1386             m_jit.push(GPRInfo::callFrameRegister);
1387             appendCallWithExceptionCheck(operationToPrimitive);
1388             setupResults(resultTagGPR, resultPayloadGPR);
1389             silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
1390             
1391             MacroAssembler::Jump done = m_jit.jump();
1392             
1393             alreadyPrimitive.link(&m_jit);
1394             m_jit.move(op1TagGPR, resultTagGPR);
1395             m_jit.move(op1PayloadGPR, resultPayloadGPR);
1396             
1397             done.link(&m_jit);
1398         }
1399         
1400         jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
1401         break;
1402     }
1403         
1404     case StrCat:
1405     case NewArray: {
1406         // We really don't want to grow the register file just to do a StrCat or NewArray.
1407         // Say we have 50 functions on the stack that all have a StrCat in them that has
1408         // upwards of 10 operands. In the DFG this would mean that each one gets
1409         // some random virtual register, and then to do the StrCat we'd need a second
1410         // span of 10 operands just to have somewhere to copy the 10 operands to, where
1411         // they'd be contiguous and we could easily tell the C code how to find them.
1412         // Ugly! So instead we use the scratchBuffer infrastructure in JSGlobalData. That
1413         // way, those 50 functions will share the same scratchBuffer for offloading their
1414         // StrCat operands. It's about as good as we can do, unless we start doing
1415         // virtual register coalescing to ensure that operands to StrCat get spilled
1416         // in exactly the place where StrCat wants them, or else have the StrCat
1417         // refer to those operands' SetLocal instructions to force them to spill in
1418         // the right place. Basically, any way you cut it, the current approach
1419         // probably has the best balance of performance and sensibility in the sense
1420         // that it does not increase the complexity of the DFG JIT just to make StrCat
1421         // fast and pretty.
1422         
1423         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(m_jit.globalData()->scratchBufferForSize(sizeof(EncodedJSValue) * node.numChildren()));
1424         
1425         for (unsigned operandIdx = 0; operandIdx < node.numChildren(); ++operandIdx) {
1426             JSValueOperand operand(this, m_jit.graph().m_varArgChildren[node.firstChild() + operandIdx]);
1427             GPRReg opTagGPR = operand.tagGPR();
1428             GPRReg opPayloadGPR = operand.payloadGPR();
1429             operand.use();
1430             
1431             m_jit.store32(opTagGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
1432             m_jit.store32(opPayloadGPR, reinterpret_cast<char*>(buffer + operandIdx) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
1433         }
1434         
1435         flushRegisters();
1436         
1437         GPRResult resultPayload(this);
1438         GPRResult2 resultTag(this);
1439         
1440         callOperation(op == StrCat ? operationStrCat : operationNewArray, resultTag.gpr(), resultPayload.gpr(), buffer, node.numChildren());
1441
1442         // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag.
1443         cellResult(resultPayload.gpr(), m_compileIndex, UseChildrenCalledExplicitly);
1444         break;
1445     }
1446
1447     case NewArrayBuffer: {
1448         flushRegisters();
1449         GPRResult resultPayload(this);
1450         GPRResult2 resultTag(this);
1451         
1452         callOperation(operationNewArrayBuffer, resultTag.gpr(), resultPayload.gpr(), node.startConstant(), node.numConstants());
1453         
1454         // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag.
1455         cellResult(resultPayload.gpr(), m_compileIndex);
1456         break;
1457     }
1458         
1459     case NewRegexp: {
1460         flushRegisters();
1461         GPRResult resultPayload(this);
1462         GPRResult2 resultTag(this);
1463         
1464         callOperation(operationNewRegexp, resultTag.gpr(), resultPayload.gpr(), m_jit.codeBlock()->regexp(node.regexpIndex()));
1465         
1466         // FIXME: make the callOperation above explicitly return a cell result, or jitAssert the tag is a cell tag.
1467         cellResult(resultPayload.gpr(), m_compileIndex);
1468         break;
1469     }
1470         
1471     case ConvertThis: {
1472         SpeculateCellOperand thisValue(this, node.child1());
1473
1474         speculationCheck(m_jit.branchPtr(JITCompiler::Equal, JITCompiler::Address(thisValue.gpr()), JITCompiler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
1475
1476         cellResult(thisValue.gpr(), m_compileIndex);
1477         break;
1478     }
1479
1480     case CreateThis: {
1481         // Note that there is not so much profit to speculate here. The only things we
1482         // speculate on are (1) that it's a cell, since that eliminates cell checks
1483         // later if the proto is reused, and (2) if we have a FinalObject prediction
1484         // then we speculate because we want to get recompiled if it isn't (since
1485         // otherwise we'd start taking slow path a lot).
1486         
1487         SpeculateCellOperand proto(this, node.child1());
1488         GPRTemporary result(this);
1489         GPRTemporary scratch(this);
1490         
1491         GPRReg protoGPR = proto.gpr();
1492         GPRReg resultGPR = result.gpr();
1493         GPRReg scratchGPR = scratch.gpr();
1494         
1495         proto.use();
1496         
1497         MacroAssembler::JumpList slowPath;
1498         
1499         // Need to verify that the prototype is an object. If we have reason to believe
1500         // that it's a FinalObject then we speculate on that directly. Otherwise we
1501         // do the slow (structure-based) check.
1502         if (shouldSpeculateFinalObject(node.child1()))
1503             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(protoGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsFinalObjectVPtr)));
1504         else {
1505             m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSCell::structureOffset()), scratchGPR);
1506             slowPath.append(m_jit.branch8(MacroAssembler::Below, MacroAssembler::Address(scratchGPR, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));
1507         }
1508         
1509         // Load the inheritorID (the Structure that objects who have protoGPR as the prototype
1510         // use to refer to that prototype). If the inheritorID is not set, go to slow path.
1511         m_jit.loadPtr(MacroAssembler::Address(protoGPR, JSObject::offsetOfInheritorID()), scratchGPR);
1512         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, scratchGPR));
1513         
1514         emitAllocateJSFinalObject(scratchGPR, resultGPR, scratchGPR, slowPath);
1515         
1516         MacroAssembler::Jump done = m_jit.jump();
1517         
1518         slowPath.link(&m_jit);
1519         
1520         silentSpillAllRegisters(resultGPR);
1521         m_jit.push(TrustedImm32(JSValue::CellTag));
1522         m_jit.push(protoGPR);
1523         m_jit.push(GPRInfo::callFrameRegister);
1524         appendCallWithExceptionCheck(operationCreateThis);
1525         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
1526         silentFillAllRegisters(resultGPR);
1527         
1528         done.link(&m_jit);
1529         
1530         cellResult(resultGPR, m_compileIndex, UseChildrenCalledExplicitly);
1531         break;
1532     }
1533
1534     case NewObject: {
1535         GPRTemporary result(this);
1536         GPRTemporary scratch(this);
1537         
1538         GPRReg resultGPR = result.gpr();
1539         GPRReg scratchGPR = scratch.gpr();
1540         
1541         MacroAssembler::JumpList slowPath;
1542         
1543         emitAllocateJSFinalObject(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()->emptyObjectStructure()), resultGPR, scratchGPR, slowPath);
1544         
1545         MacroAssembler::Jump done = m_jit.jump();
1546         
1547         slowPath.link(&m_jit);
1548         
1549         silentSpillAllRegisters(resultGPR);
1550         m_jit.push(GPRInfo::callFrameRegister);
1551         appendCallWithExceptionCheck(operationNewObject);
1552         m_jit.move(GPRInfo::returnValueGPR, resultGPR);
1553         silentFillAllRegisters(resultGPR);
1554         
1555         done.link(&m_jit);
1556         
1557         cellResult(resultGPR, m_compileIndex);
1558         break;
1559     }
1560
1561     case GetCallee: {
1562         GPRTemporary result(this);
1563         m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::Callee)), result.gpr());
1564         cellResult(result.gpr(), m_compileIndex);
1565         break;
1566     }
1567
1568     case GetScopeChain: {
1569         GPRTemporary result(this);
1570         GPRReg resultGPR = result.gpr();
1571
1572         m_jit.loadPtr(JITCompiler::addressFor(static_cast<VirtualRegister>(RegisterFile::ScopeChain)), resultGPR);
1573         bool checkTopLevel = m_jit.codeBlock()->codeType() == FunctionCode && m_jit.codeBlock()->needsFullScopeChain();
1574         int skip = node.scopeChainDepth();
1575         ASSERT(skip || !checkTopLevel);
1576         if (checkTopLevel && skip--) {
1577             JITCompiler::Jump activationNotCreated;
1578             if (checkTopLevel)
1579                 activationNotCreated = m_jit.branchTestPtr(JITCompiler::Zero, JITCompiler::addressFor(static_cast<VirtualRegister>(m_jit.codeBlock()->activationRegister())));
1580             m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
1581             activationNotCreated.link(&m_jit);
1582         }
1583         while (skip--)
1584             m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, next)), resultGPR);
1585         
1586         m_jit.loadPtr(JITCompiler::Address(resultGPR, OBJECT_OFFSETOF(ScopeChainNode, object)), resultGPR);
1587
1588         cellResult(resultGPR, m_compileIndex);
1589         break;
1590     }
1591     case GetScopedVar: {
1592         SpeculateCellOperand scopeChain(this, node.child1());
1593         GPRTemporary resultTag(this);
1594         GPRTemporary resultPayload(this);
1595         GPRReg resultTagGPR = resultTag.gpr();
1596         GPRReg resultPayloadGPR = resultPayload.gpr();
1597         m_jit.loadPtr(JITCompiler::Address(scopeChain.gpr(), JSVariableObject::offsetOfRegisters()), resultPayloadGPR);
1598         m_jit.load32(JITCompiler::Address(resultPayloadGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
1599         m_jit.load32(JITCompiler::Address(resultPayloadGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
1600         jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
1601         break;
1602     }
1603     case PutScopedVar: {
1604         SpeculateCellOperand scopeChain(this, node.child1());
1605         GPRTemporary scratchRegister(this);
1606         GPRReg scratchGPR = scratchRegister.gpr();
1607         m_jit.loadPtr(JITCompiler::Address(scopeChain.gpr(), JSVariableObject::offsetOfRegisters()), scratchGPR);
1608         JSValueOperand value(this, node.child2());
1609         m_jit.store32(value.tagGPR(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
1610         m_jit.store32(value.payloadGPR(), JITCompiler::Address(scratchGPR, node.varNumber() * sizeof(Register) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
1611         writeBarrier(scopeChain.gpr(), value.tagGPR(), node.child2(), WriteBarrierForVariableAccess, scratchGPR);
1612         noResult(m_compileIndex);
1613         break;
1614     }
1615         
1616     case GetById: {
1617         SpeculateCellOperand base(this, node.child1());
1618         GPRTemporary resultTag(this, base);
1619         GPRTemporary resultPayload(this);
1620         
1621         GPRReg baseGPR = base.gpr();
1622         GPRReg resultTagGPR = resultTag.gpr();
1623         GPRReg resultPayloadGPR = resultPayload.gpr();
1624         GPRReg scratchGPR;
1625         
1626         if (resultTagGPR == baseGPR)
1627             scratchGPR = resultPayloadGPR;
1628         else
1629             scratchGPR = resultTagGPR;
1630         
1631         base.use();
1632
1633         cachedGetById(baseGPR, resultTagGPR, resultPayloadGPR, scratchGPR, node.identifierNumber());
1634
1635         jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
1636         break;
1637     }
1638
1639     case GetArrayLength: {
1640         SpeculateCellOperand base(this, node.child1());
1641         GPRTemporary result(this);
1642         
1643         GPRReg baseGPR = base.gpr();
1644         GPRReg resultGPR = result.gpr();
1645         
1646         if (!isKnownArray(node.child1()))
1647             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsArrayVPtr)));
1648         
1649         m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArray::storageOffset()), resultGPR);
1650         m_jit.load32(MacroAssembler::Address(resultGPR, OBJECT_OFFSETOF(ArrayStorage, m_length)), resultGPR);
1651         
1652         speculationCheck(m_jit.branch32(MacroAssembler::LessThan, resultGPR, MacroAssembler::TrustedImm32(0)));
1653         
1654         integerResult(resultGPR, m_compileIndex);
1655         break;
1656     }
1657
1658     case GetStringLength: {
1659         SpeculateCellOperand base(this, node.child1());
1660         GPRTemporary result(this);
1661         
1662         GPRReg baseGPR = base.gpr();
1663         GPRReg resultGPR = result.gpr();
1664         
1665         if (!isKnownString(node.child1()))
1666             speculationCheck(m_jit.branchPtr(MacroAssembler::NotEqual, MacroAssembler::Address(baseGPR), MacroAssembler::TrustedImmPtr(m_jit.globalData()->jsStringVPtr)));
1667         
1668         m_jit.load32(MacroAssembler::Address(baseGPR, JSString::offsetOfLength()), resultGPR);
1669
1670         integerResult(resultGPR, m_compileIndex);
1671         break;
1672     }
1673
1674     case CheckStructure: {
1675         SpeculateCellOperand base(this, node.child1());
1676         
1677         ASSERT(node.structureSet().size());
1678         
1679         if (node.structureSet().size() == 1)
1680             speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0])));
1681         else {
1682             GPRTemporary structure(this);
1683             
1684             m_jit.loadPtr(JITCompiler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
1685             
1686             JITCompiler::JumpList done;
1687             
1688             for (size_t i = 0; i < node.structureSet().size() - 1; ++i)
1689                 done.append(m_jit.branchPtr(JITCompiler::Equal, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet()[i])));
1690             
1691             speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last())));
1692             
1693             done.link(&m_jit);
1694         }
1695         
1696         noResult(m_compileIndex);
1697         break;
1698     }
1699         
1700     case PutStructure: {
1701         SpeculateCellOperand base(this, node.child1());
1702         GPRReg baseGPR = base.gpr();
1703         
1704 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
1705         // Must always emit this write barrier as the structure transition itself requires it
1706         writeBarrier(baseGPR, node.structureTransitionData().newStructure, WriteBarrierForGenericAccess);
1707 #endif
1708         
1709         m_jit.storePtr(MacroAssembler::TrustedImmPtr(node.structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));
1710         
1711         noResult(m_compileIndex);
1712         break;
1713     }
1714         
1715     case GetPropertyStorage: {
1716         SpeculateCellOperand base(this, node.child1());
1717         GPRTemporary result(this, base);
1718         
1719         GPRReg baseGPR = base.gpr();
1720         GPRReg resultGPR = result.gpr();
1721         
1722         m_jit.loadPtr(JITCompiler::Address(baseGPR, JSObject::offsetOfPropertyStorage()), resultGPR);
1723         
1724         storageResult(resultGPR, m_compileIndex);
1725         break;
1726     }
1727         
1728     case GetByOffset: {
1729         StorageOperand storage(this, node.child1());
1730         GPRTemporary resultTag(this, storage);
1731         GPRTemporary resultPayload(this);
1732         
1733         GPRReg storageGPR = storage.gpr();
1734         GPRReg resultTagGPR = resultTag.gpr();
1735         GPRReg resultPayloadGPR = resultPayload.gpr();
1736         
1737         StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
1738         
1739         m_jit.load32(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
1740         m_jit.load32(JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
1741         
1742         jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
1743         break;
1744     }
1745         
1746     case PutByOffset: {
1747 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
1748         SpeculateCellOperand base(this, node.child1());
1749 #endif
1750         StorageOperand storage(this, node.child2());
1751         JSValueOperand value(this, node.child3());
1752
1753         GPRReg storageGPR = storage.gpr();
1754         GPRReg valueTagGPR = value.tagGPR();
1755         GPRReg valuePayloadGPR = value.payloadGPR();
1756         
1757 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING)
1758         writeBarrier(base.gpr(), valueTagGPR, node.child3(), WriteBarrierForPropertyAccess);
1759 #endif
1760
1761         StorageAccessData& storageAccessData = m_jit.graph().m_storageAccessData[node.storageAccessDataIndex()];
1762         
1763         m_jit.storePtr(valueTagGPR, JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)));
1764         m_jit.storePtr(valuePayloadGPR, JITCompiler::Address(storageGPR, storageAccessData.offset * sizeof(EncodedJSValue) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)));
1765         
1766         noResult(m_compileIndex);
1767         break;
1768     }
1769         
1770     case GetMethod: {
1771         SpeculateCellOperand base(this, node.child1());
1772         GPRTemporary resultTag(this, base);
1773         GPRTemporary resultPayload(this);
1774
1775         GPRReg baseGPR = base.gpr();
1776         GPRReg resultTagGPR = resultTag.gpr();
1777         GPRReg resultPayloadGPR = resultPayload.gpr();
1778         GPRReg scratchGPR;
1779         
1780         if (resultTagGPR == baseGPR)
1781             scratchGPR = resultPayloadGPR;
1782         else
1783             scratchGPR = resultTagGPR;
1784         
1785         base.use();
1786
1787         cachedGetMethod(baseGPR, resultTagGPR, resultPayloadGPR, scratchGPR, node.identifierNumber());
1788
1789         jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex, UseChildrenCalledExplicitly);
1790         break;
1791     }
1792
1793     case CheckMethod: {
1794         MethodCheckData& methodCheckData = m_jit.graph().m_methodCheckData[node.methodCheckDataIndex()];
1795         
1796         SpeculateCellOperand base(this, node.child1());
1797         GPRTemporary scratch(this); // this needs to be a separate register, unfortunately.
1798         GPRReg baseGPR = base.gpr();
1799         GPRReg scratchGPR = scratch.gpr();
1800         
1801         speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(methodCheckData.structure)));
1802         if (methodCheckData.prototype != m_jit.codeBlock()->globalObject()->methodCallDummy()) {
1803             m_jit.move(JITCompiler::TrustedImmPtr(methodCheckData.prototype->structureAddress()), scratchGPR);
1804             speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(scratchGPR), JITCompiler::TrustedImmPtr(methodCheckData.prototypeStructure)));
1805         }
1806         
1807         useChildren(node);
1808         initConstantInfo(m_compileIndex);
1809         break;
1810     }
1811
1812     case PutById: {
1813         SpeculateCellOperand base(this, node.child1());
1814         JSValueOperand value(this, node.child2());
1815         GPRTemporary scratch(this);
1816         
1817         GPRReg baseGPR = base.gpr();
1818         GPRReg valueTagGPR = value.tagGPR();
1819         GPRReg valuePayloadGPR = value.payloadGPR();
1820         GPRReg scratchGPR = scratch.gpr();
1821         
1822         base.use();
1823         value.use();
1824
1825         cachedPutById(baseGPR, valueTagGPR, valuePayloadGPR, node.child2(), scratchGPR, node.identifierNumber(), NotDirect);
1826         
1827         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1828         break;
1829     }
1830
1831     case PutByIdDirect: {
1832         SpeculateCellOperand base(this, node.child1());
1833         JSValueOperand value(this, node.child2());
1834         GPRTemporary scratch(this);
1835         
1836         GPRReg baseGPR = base.gpr();
1837         GPRReg valueTagGPR = value.tagGPR();
1838         GPRReg valuePayloadGPR = value.payloadGPR();
1839         GPRReg scratchGPR = scratch.gpr();
1840         
1841         base.use();
1842         value.use();
1843
1844         cachedPutById(baseGPR, valueTagGPR, valuePayloadGPR, node.child2(), scratchGPR, node.identifierNumber(), Direct);
1845
1846         noResult(m_compileIndex, UseChildrenCalledExplicitly);
1847         break;
1848     }
1849
1850     case GetGlobalVar: {
1851         GPRTemporary result(this);
1852         GPRTemporary scratch(this);
1853
1854         JSVariableObject* globalObject = m_jit.codeBlock()->globalObject();
1855         m_jit.loadPtr(const_cast<WriteBarrier<Unknown>**>(globalObject->addressOfRegisters()), result.gpr());
1856         m_jit.load32(JITCompiler::tagForGlobalVar(result.gpr(), node.varNumber()), scratch.gpr());
1857         m_jit.load32(JITCompiler::payloadForGlobalVar(result.gpr(), node.varNumber()), result.gpr());
1858
1859         jsValueResult(scratch.gpr(), result.gpr(), m_compileIndex);
1860         break;
1861     }
1862
1863     case PutGlobalVar: {
1864         JSValueOperand value(this, node.child1());
1865         GPRTemporary globalObject(this);
1866         GPRTemporary scratch(this);
1867         
1868         GPRReg globalObjectReg = globalObject.gpr();
1869         GPRReg scratchReg = scratch.gpr();
1870
1871         m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectReg);
1872
1873         writeBarrier(m_jit.codeBlock()->globalObject(), value.tagGPR(), node.child1(), WriteBarrierForVariableAccess, scratchReg);
1874
1875         m_jit.loadPtr(MacroAssembler::Address(globalObjectReg, JSVariableObject::offsetOfRegisters()), scratchReg);
1876         m_jit.store32(value.tagGPR(), JITCompiler::tagForGlobalVar(scratchReg, node.varNumber()));
1877         m_jit.store32(value.payloadGPR(), JITCompiler::payloadForGlobalVar(scratchReg, node.varNumber()));
1878
1879         noResult(m_compileIndex);
1880         break;
1881     }
1882
1883     case CheckHasInstance: {
1884         SpeculateCellOperand base(this, node.child1());
1885         GPRTemporary structure(this);
1886
1887         // Speculate that base 'ImplementsDefaultHasInstance'.
1888         m_jit.loadPtr(MacroAssembler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr());
1889         speculationCheck(m_jit.branchTest8(MacroAssembler::Zero, MacroAssembler::Address(structure.gpr(), Structure::typeInfoFlagsOffset()), MacroAssembler::TrustedImm32(ImplementsDefaultHasInstance)));
1890
1891         noResult(m_compileIndex);
1892         break;
1893     }
1894
1895     case InstanceOf: {
1896         SpeculateCellOperand value(this, node.child1());
1897         // Base unused since we speculate default InstanceOf behaviour in CheckHasInstance.
1898         SpeculateCellOperand prototype(this, node.child3());
1899
1900         GPRTemporary scratch(this);
1901         GPRTemporary booleanTag(this, value);
1902
1903         GPRReg valueReg = value.gpr();
1904         GPRReg prototypeReg = prototype.gpr();
1905         GPRReg scratchReg = scratch.gpr();
1906
1907         // Check that prototype is an object.
1908         m_jit.loadPtr(MacroAssembler::Address(prototypeReg, JSCell::structureOffset()), scratchReg);
1909         speculationCheck(m_jit.branch8(MacroAssembler::NotEqual, MacroAssembler::Address(scratchReg, Structure::typeInfoTypeOffset()), MacroAssembler::TrustedImm32(ObjectType)));
1910
1911         // Initialize scratchReg with the value being checked.
1912         m_jit.move(valueReg, scratchReg);
1913
1914         // Walk up the prototype chain of the value (in scratchReg), comparing to prototypeReg.
1915         MacroAssembler::Label loop(&m_jit);
1916         m_jit.loadPtr(MacroAssembler::Address(scratchReg, JSCell::structureOffset()), scratchReg);
1917         m_jit.load32(MacroAssembler::Address(scratchReg, Structure::prototypeOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), scratchReg);
1918         MacroAssembler::Jump isInstance = m_jit.branch32(MacroAssembler::Equal, scratchReg, prototypeReg);
1919         m_jit.branchTest32(MacroAssembler::NonZero, scratchReg).linkTo(loop, &m_jit);
1920
1921         // No match - result is false.
1922         m_jit.move(MacroAssembler::TrustedImm32(0), scratchReg);
1923         MacroAssembler::Jump putResult = m_jit.jump();
1924
1925         isInstance.link(&m_jit);
1926         m_jit.move(MacroAssembler::TrustedImm32(1), scratchReg);
1927
1928         putResult.link(&m_jit);
1929         m_jit.move(TrustedImm32(JSValue::BooleanTag), booleanTag.gpr());
1930         jsValueResult(booleanTag.gpr(), scratchReg, m_compileIndex, DataFormatJSBoolean);
1931         break;
1932     }
1933
1934     case Phi:
1935         ASSERT_NOT_REACHED();
1936
1937     case Breakpoint:
1938 #if ENABLE(DEBUG_WITH_BREAKPOINT)
1939         m_jit.breakpoint();
1940 #else
1941         ASSERT_NOT_REACHED();
1942 #endif
1943         break;
1944         
1945     case Call:
1946     case Construct:
1947         emitCall(node);
1948         break;
1949
1950     case Resolve: {
1951         flushRegisters();
1952         GPRResult resultPayload(this);
1953         GPRResult2 resultTag(this);
1954         callOperation(operationResolve, resultTag.gpr(), resultPayload.gpr(), identifier(node.identifierNumber()));
1955         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
1956         break;
1957     }
1958
1959     case ResolveBase: {
1960         flushRegisters();
1961         GPRResult resultPayload(this);
1962         GPRResult2 resultTag(this);
1963         callOperation(operationResolveBase, resultTag.gpr(), resultPayload.gpr(), identifier(node.identifierNumber()));
1964         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
1965         break;
1966     }
1967
1968     case ResolveBaseStrictPut: {
1969         flushRegisters();
1970         GPRResult resultPayload(this);
1971         GPRResult2 resultTag(this);
1972         callOperation(operationResolveBaseStrictPut, resultTag.gpr(), resultPayload.gpr(), identifier(node.identifierNumber()));
1973         jsValueResult(resultTag.gpr(), resultPayload.gpr(), m_compileIndex);
1974         break;
1975     }
1976
1977     case ResolveGlobal: {
1978         GPRTemporary globalObject(this);
1979         GPRTemporary resolveInfo(this);
1980         GPRTemporary resultTag(this);
1981         GPRTemporary resultPayload(this);
1982
1983         GPRReg globalObjectGPR = globalObject.gpr();
1984         GPRReg resolveInfoGPR = resolveInfo.gpr();
1985         GPRReg resultTagGPR = resultTag.gpr();
1986         GPRReg resultPayloadGPR = resultPayload.gpr();
1987
1988         ResolveGlobalData& data = m_jit.graph().m_resolveGlobalData[node.resolveGlobalDataIndex()];
1989         GlobalResolveInfo* resolveInfoAddress = &(m_jit.codeBlock()->globalResolveInfo(data.resolveInfoIndex));
1990
1991         // Check Structure of global object
1992         m_jit.move(JITCompiler::TrustedImmPtr(m_jit.codeBlock()->globalObject()), globalObjectGPR);
1993         m_jit.move(JITCompiler::TrustedImmPtr(resolveInfoAddress), resolveInfoGPR);
1994         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, structure) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
1995         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, structure) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
1996
1997         JITCompiler::JumpList structuresNotMatch;
1998         structuresNotMatch.append(m_jit.branch32(JITCompiler::NotEqual, resultTagGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag))));
1999         structuresNotMatch.append(m_jit.branch32(JITCompiler::NotEqual, resultPayloadGPR, JITCompiler::Address(globalObjectGPR, JSCell::structureOffset() + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload))));
2000
2001         // Fast case
2002         m_jit.load32(JITCompiler::Address(globalObjectGPR, JSObject::offsetOfPropertyStorage()), resultPayloadGPR);
2003         m_jit.load32(JITCompiler::Address(resolveInfoGPR, OBJECT_OFFSETOF(GlobalResolveInfo, offset)), resolveInfoGPR);
2004         m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag)), resultTagGPR);
2005         m_jit.load32(JITCompiler::BaseIndex(resultPayloadGPR, resolveInfoGPR, JITCompiler::TimesEight, OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload)), resultPayloadGPR);
2006
2007         JITCompiler::Jump wasFast = m_jit.jump();
2008
2009         structuresNotMatch.link(&m_jit);
2010         silentSpillAllRegisters(resultTagGPR, resultPayloadGPR);
2011         m_jit.push(JITCompiler::TrustedImm32(reinterpret_cast<int>(&m_jit.codeBlock()->identifier(data.identifierNumber))));
2012         m_jit.push(resolveInfoGPR);
2013         m_jit.push(GPRInfo::callFrameRegister);
2014         JITCompiler::Call functionCall = appendCallWithExceptionCheck(operationResolveGlobal);
2015         setupResults(resultTagGPR, resultPayloadGPR);
2016         silentFillAllRegisters(resultTagGPR, resultPayloadGPR);
2017
2018         wasFast.link(&m_jit);
2019
2020         jsValueResult(resultTagGPR, resultPayloadGPR, m_compileIndex);
2021         break;
2022     }
2023
2024     case ForceOSRExit: {
2025         terminateSpeculativeExecution();
2026         break;
2027     }
2028
2029     case Phantom:
2030         // This is a no-op.
2031         noResult(m_compileIndex);
2032         break;
2033     }
2034
2035     if (node.hasResult() && node.mustGenerate())
2036         use(m_compileIndex);
2037 }
2038
2039 #endif
2040
2041 } } // namespace JSC::DFG
2042
2043 #endif