JSC should infer when indexed storage contains only integers or doubles
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT.h
1 /*
2  * Copyright (C) 2011, 2012 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 #ifndef DFGSpeculativeJIT_h
27 #define DFGSpeculativeJIT_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(DFG_JIT)
32
33 #include "DFGAbstractState.h"
34 #include "DFGGenerationInfo.h"
35 #include "DFGJITCompiler.h"
36 #include "DFGOSRExit.h"
37 #include "DFGOperations.h"
38 #include "DFGSilentRegisterSavePlan.h"
39 #include "DFGValueSource.h"
40 #include "MarkedAllocator.h"
41 #include "ValueRecovery.h"
42
43 namespace JSC { namespace DFG {
44
45 class GPRTemporary;
46 class JSValueOperand;
47 class SlowPathGenerator;
48 class SpeculativeJIT;
49 class SpeculateIntegerOperand;
50 class SpeculateStrictInt32Operand;
51 class SpeculateDoubleOperand;
52 class SpeculateCellOperand;
53 class SpeculateBooleanOperand;
54
55 enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandDouble, GeneratedOperandJSValue};
56
57 // === SpeculativeJIT ===
58 //
59 // The SpeculativeJIT is used to generate a fast, but potentially
60 // incomplete code path for the dataflow. When code generating
61 // we may make assumptions about operand types, dynamically check,
62 // and bail-out to an alternate code path if these checks fail.
63 // Importantly, the speculative code path cannot be reentered once
64 // a speculative check has failed. This allows the SpeculativeJIT
65 // to propagate type information (including information that has
66 // only speculatively been asserted) through the dataflow.
67 class SpeculativeJIT {
68     friend struct OSRExit;
69 private:
70     typedef JITCompiler::TrustedImm32 TrustedImm32;
71     typedef JITCompiler::Imm32 Imm32;
72     typedef JITCompiler::TrustedImmPtr TrustedImmPtr;
73     typedef JITCompiler::ImmPtr ImmPtr;
74     typedef JITCompiler::TrustedImm64 TrustedImm64;
75     typedef JITCompiler::Imm64 Imm64;
76
77     // These constants are used to set priorities for spill order for
78     // the register allocator.
79 #if USE(JSVALUE64)
80     enum SpillOrder {
81         SpillOrderConstant = 1, // no spill, and cheap fill
82         SpillOrderSpilled  = 2, // no spill
83         SpillOrderJS       = 4, // needs spill
84         SpillOrderCell     = 4, // needs spill
85         SpillOrderStorage  = 4, // needs spill
86         SpillOrderInteger  = 5, // needs spill and box
87         SpillOrderBoolean  = 5, // needs spill and box
88         SpillOrderDouble   = 6, // needs spill and convert
89     };
90 #elif USE(JSVALUE32_64)
91     enum SpillOrder {
92         SpillOrderConstant = 1, // no spill, and cheap fill
93         SpillOrderSpilled  = 2, // no spill
94         SpillOrderJS       = 4, // needs spill
95         SpillOrderStorage  = 4, // needs spill
96         SpillOrderDouble   = 4, // needs spill
97         SpillOrderInteger  = 5, // needs spill and box
98         SpillOrderCell     = 5, // needs spill and box
99         SpillOrderBoolean  = 5, // needs spill and box
100     };
101 #endif
102
103     enum UseChildrenMode { CallUseChildren, UseChildrenCalledExplicitly };
104     
105 public:
106     SpeculativeJIT(JITCompiler&);
107     ~SpeculativeJIT();
108
109     bool compile();
110     void createOSREntries();
111     void linkOSREntries(LinkBuffer&);
112
113     Node& at(NodeIndex nodeIndex)
114     {
115         return m_jit.graph()[nodeIndex];
116     }
117     Node& at(Edge nodeUse)
118     {
119         return at(nodeUse.index());
120     }
121     
122     BlockIndex nextBlock()
123     {
124         for (BlockIndex result = m_block + 1; ; result++) {
125             if (result >= m_jit.graph().m_blocks.size())
126                 return NoBlock;
127             if (m_jit.graph().m_blocks[result])
128                 return result;
129         }
130     }
131     
132     GPRReg fillInteger(NodeIndex, DataFormat& returnFormat);
133     FPRReg fillDouble(NodeIndex);
134 #if USE(JSVALUE64)
135     GPRReg fillJSValue(NodeIndex);
136 #elif USE(JSVALUE32_64)
137     bool fillJSValue(NodeIndex, GPRReg&, GPRReg&, FPRReg&);
138 #endif
139     GPRReg fillStorage(NodeIndex);
140
141     // lock and unlock GPR & FPR registers.
142     void lock(GPRReg reg)
143     {
144         m_gprs.lock(reg);
145     }
146     void lock(FPRReg reg)
147     {
148         m_fprs.lock(reg);
149     }
150     void unlock(GPRReg reg)
151     {
152         m_gprs.unlock(reg);
153     }
154     void unlock(FPRReg reg)
155     {
156         m_fprs.unlock(reg);
157     }
158
159     // Used to check whether a child node is on its last use,
160     // and its machine registers may be reused.
161     bool canReuse(NodeIndex nodeIndex)
162     {
163         VirtualRegister virtualRegister = at(nodeIndex).virtualRegister();
164         GenerationInfo& info = m_generationInfo[virtualRegister];
165         return info.canReuse();
166     }
167     bool canReuse(Edge nodeUse)
168     {
169         return canReuse(nodeUse.index());
170     }
171     GPRReg reuse(GPRReg reg)
172     {
173         m_gprs.lock(reg);
174         return reg;
175     }
176     FPRReg reuse(FPRReg reg)
177     {
178         m_fprs.lock(reg);
179         return reg;
180     }
181
182     // Allocate a gpr/fpr.
183     GPRReg allocate()
184     {
185         VirtualRegister spillMe;
186         GPRReg gpr = m_gprs.allocate(spillMe);
187         if (spillMe != InvalidVirtualRegister) {
188 #if USE(JSVALUE32_64)
189             GenerationInfo& info = m_generationInfo[spillMe];
190             ASSERT(info.registerFormat() != DataFormatJSDouble);
191             if ((info.registerFormat() & DataFormatJS))
192                 m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
193 #endif
194             spill(spillMe);
195         }
196         return gpr;
197     }
198     GPRReg allocate(GPRReg specific)
199     {
200         VirtualRegister spillMe = m_gprs.allocateSpecific(specific);
201         if (spillMe != InvalidVirtualRegister) {
202 #if USE(JSVALUE32_64)
203             GenerationInfo& info = m_generationInfo[spillMe];
204             ASSERT(info.registerFormat() != DataFormatJSDouble);
205             if ((info.registerFormat() & DataFormatJS))
206                 m_gprs.release(info.tagGPR() == specific ? info.payloadGPR() : info.tagGPR());
207 #endif
208             spill(spillMe);
209         }
210         return specific;
211     }
212     GPRReg tryAllocate()
213     {
214         return m_gprs.tryAllocate();
215     }
216     FPRReg fprAllocate()
217     {
218         VirtualRegister spillMe;
219         FPRReg fpr = m_fprs.allocate(spillMe);
220         if (spillMe != InvalidVirtualRegister)
221             spill(spillMe);
222         return fpr;
223     }
224
225     // Check whether a VirtualRegsiter is currently in a machine register.
226     // We use this when filling operands to fill those that are already in
227     // machine registers first (by locking VirtualRegsiters that are already
228     // in machine register before filling those that are not we attempt to
229     // avoid spilling values we will need immediately).
230     bool isFilled(NodeIndex nodeIndex)
231     {
232         VirtualRegister virtualRegister = at(nodeIndex).virtualRegister();
233         GenerationInfo& info = m_generationInfo[virtualRegister];
234         return info.registerFormat() != DataFormatNone;
235     }
236     bool isFilledDouble(NodeIndex nodeIndex)
237     {
238         VirtualRegister virtualRegister = at(nodeIndex).virtualRegister();
239         GenerationInfo& info = m_generationInfo[virtualRegister];
240         return info.registerFormat() == DataFormatDouble;
241     }
242
243     // Called on an operand once it has been consumed by a parent node.
244     void use(NodeIndex nodeIndex)
245     {
246         Node& node = at(nodeIndex);
247         if (!node.hasResult())
248             return;
249         VirtualRegister virtualRegister = node.virtualRegister();
250         GenerationInfo& info = m_generationInfo[virtualRegister];
251
252         // use() returns true when the value becomes dead, and any
253         // associated resources may be freed.
254         if (!info.use(*m_stream))
255             return;
256
257         // Release the associated machine registers.
258         DataFormat registerFormat = info.registerFormat();
259 #if USE(JSVALUE64)
260         if (registerFormat == DataFormatDouble)
261             m_fprs.release(info.fpr());
262         else if (registerFormat != DataFormatNone)
263             m_gprs.release(info.gpr());
264 #elif USE(JSVALUE32_64)
265         if (registerFormat == DataFormatDouble || registerFormat == DataFormatJSDouble)
266             m_fprs.release(info.fpr());
267         else if (registerFormat & DataFormatJS) {
268             m_gprs.release(info.tagGPR());
269             m_gprs.release(info.payloadGPR());
270         } else if (registerFormat != DataFormatNone)
271             m_gprs.release(info.gpr());
272 #endif
273     }
274     void use(Edge nodeUse)
275     {
276         use(nodeUse.index());
277     }
278     
279     RegisterSet usedRegisters()
280     {
281         RegisterSet result;
282         for (unsigned i = GPRInfo::numberOfRegisters; i--;) {
283             GPRReg gpr = GPRInfo::toRegister(i);
284             if (m_gprs.isInUse(gpr))
285                 result.set(gpr);
286         }
287         for (unsigned i = FPRInfo::numberOfRegisters; i--;) {
288             FPRReg fpr = FPRInfo::toRegister(i);
289             if (m_fprs.isInUse(fpr))
290                 result.set(fpr);
291         }
292         return result;
293     }
294
295     static void markCellCard(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2);
296     static void writeBarrier(MacroAssembler&, GPRReg ownerGPR, GPRReg scratchGPR1, GPRReg scratchGPR2, WriteBarrierUseKind);
297
298     void writeBarrier(GPRReg ownerGPR, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg);
299     void writeBarrier(GPRReg ownerGPR, JSCell* value, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg, GPRReg scratchGPR2 = InvalidGPRReg);
300     void writeBarrier(JSCell* owner, GPRReg valueGPR, Edge valueUse, WriteBarrierUseKind, GPRReg scratchGPR1 = InvalidGPRReg);
301
302     static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
303     {
304         return AssemblyHelpers::selectScratchGPR(preserve1, preserve2, preserve3, preserve4);
305     }
306
307     // Called by the speculative operand types, below, to fill operand to
308     // machine registers, implicitly generating speculation checks as needed.
309     GPRReg fillSpeculateInt(NodeIndex, DataFormat& returnFormat);
310     GPRReg fillSpeculateIntStrict(NodeIndex);
311     FPRReg fillSpeculateDouble(NodeIndex);
312     GPRReg fillSpeculateCell(NodeIndex, bool isForwardSpeculation = false);
313     GPRReg fillSpeculateBoolean(NodeIndex);
314     GeneratedOperandType checkGeneratedTypeForToInt32(NodeIndex);
315
316     void addSlowPathGenerator(PassOwnPtr<SlowPathGenerator>);
317     void runSlowPathGenerators();
318     
319     void compile(Node&);
320     void noticeOSRBirth(NodeIndex, Node&);
321     void compileMovHint(Node&);
322     void compile(BasicBlock&);
323
324     void checkArgumentTypes();
325
326     void clearGenerationInfo();
327
328     // These methods are used when generating 'unexpected'
329     // calls out from JIT code to C++ helper routines -
330     // they spill all live values to the appropriate
331     // slots in the JSStack without changing any state
332     // in the GenerationInfo.
333     SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source)
334     {
335         GenerationInfo& info = m_generationInfo[spillMe];
336         NodeIndex nodeIndex = info.nodeIndex();
337         Node& node = at(nodeIndex);
338         DataFormat registerFormat = info.registerFormat();
339         ASSERT(registerFormat != DataFormatNone);
340         ASSERT(registerFormat != DataFormatDouble);
341         
342         SilentSpillAction spillAction;
343         SilentFillAction fillAction;
344         
345         if (!info.needsSpill())
346             spillAction = DoNothingForSpill;
347         else {
348 #if USE(JSVALUE64)
349             ASSERT(info.gpr() == source);
350             if (registerFormat == DataFormatInteger)
351                 spillAction = Store32Payload;
352             else if (registerFormat == DataFormatCell || registerFormat == DataFormatStorage)
353                 spillAction = StorePtr;
354             else {
355                 ASSERT(registerFormat & DataFormatJS);
356                 spillAction = Store64;
357             }
358 #elif USE(JSVALUE32_64)
359             if (registerFormat & DataFormatJS) {
360                 ASSERT(info.tagGPR() == source || info.payloadGPR() == source);
361                 spillAction = source == info.tagGPR() ? Store32Tag : Store32Payload;
362             } else {
363                 ASSERT(info.gpr() == source);
364                 spillAction = Store32Payload;
365             }
366 #endif
367         }
368         
369         if (registerFormat == DataFormatInteger) {
370             ASSERT(info.gpr() == source);
371             ASSERT(isJSInteger(info.registerFormat()));
372             if (node.hasConstant()) {
373                 ASSERT(isInt32Constant(nodeIndex));
374                 fillAction = SetInt32Constant;
375             } else
376                 fillAction = Load32Payload;
377         } else if (registerFormat == DataFormatBoolean) {
378 #if USE(JSVALUE64)
379             ASSERT_NOT_REACHED();
380             fillAction = DoNothingForFill;
381 #elif USE(JSVALUE32_64)
382             ASSERT(info.gpr() == source);
383             if (node.hasConstant()) {
384                 ASSERT(isBooleanConstant(nodeIndex));
385                 fillAction = SetBooleanConstant;
386             } else
387                 fillAction = Load32Payload;
388 #endif
389         } else if (registerFormat == DataFormatCell) {
390             ASSERT(info.gpr() == source);
391             if (node.hasConstant()) {
392                 JSValue value = valueOfJSConstant(nodeIndex);
393                 ASSERT_UNUSED(value, value.isCell());
394                 fillAction = SetCellConstant;
395             } else {
396 #if USE(JSVALUE64)
397                 fillAction = LoadPtr;
398 #else
399                 fillAction = Load32Payload;
400 #endif
401             }
402         } else if (registerFormat == DataFormatStorage) {
403             ASSERT(info.gpr() == source);
404             fillAction = LoadPtr;
405         } else {
406             ASSERT(registerFormat & DataFormatJS);
407 #if USE(JSVALUE64)
408             ASSERT(info.gpr() == source);
409             if (node.hasConstant()) {
410                 if (valueOfJSConstant(nodeIndex).isCell())
411                     fillAction = SetTrustedJSConstant;
412                 else
413                     fillAction = SetJSConstant;
414             } else if (info.spillFormat() == DataFormatInteger) {
415                 ASSERT(registerFormat == DataFormatJSInteger);
416                 fillAction = Load32PayloadBoxInt;
417             } else if (info.spillFormat() == DataFormatDouble) {
418                 ASSERT(registerFormat == DataFormatJSDouble);
419                 fillAction = LoadDoubleBoxDouble;
420             } else
421                 fillAction = Load64;
422 #else
423             ASSERT(info.tagGPR() == source || info.payloadGPR() == source);
424             if (node.hasConstant())
425                 fillAction = info.tagGPR() == source ? SetJSConstantTag : SetJSConstantPayload;
426             else if (info.payloadGPR() == source)
427                 fillAction = Load32Payload;
428             else { // Fill the Tag
429                 switch (info.spillFormat()) {
430                 case DataFormatInteger:
431                     ASSERT(registerFormat == DataFormatJSInteger);
432                     fillAction = SetInt32Tag;
433                     break;
434                 case DataFormatCell:
435                     ASSERT(registerFormat == DataFormatJSCell);
436                     fillAction = SetCellTag;
437                     break;
438                 case DataFormatBoolean:
439                     ASSERT(registerFormat == DataFormatJSBoolean);
440                     fillAction = SetBooleanTag;
441                     break;
442                 default:
443                     fillAction = Load32Tag;
444                     break;
445                 }
446             }
447 #endif
448         }
449         
450         return SilentRegisterSavePlan(spillAction, fillAction, nodeIndex, source);
451     }
452     
453     SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source)
454     {
455         GenerationInfo& info = m_generationInfo[spillMe];
456         NodeIndex nodeIndex = info.nodeIndex();
457         Node& node = at(nodeIndex);
458         ASSERT(info.registerFormat() == DataFormatDouble);
459
460         SilentSpillAction spillAction;
461         SilentFillAction fillAction;
462         
463         if (!info.needsSpill())
464             spillAction = DoNothingForSpill;
465         else {
466             ASSERT(!at(info.nodeIndex()).hasConstant());
467             ASSERT(info.spillFormat() == DataFormatNone);
468             ASSERT(info.fpr() == source);
469             spillAction = StoreDouble;
470         }
471         
472 #if USE(JSVALUE64)
473         if (node.hasConstant()) {
474             ASSERT(isNumberConstant(nodeIndex));
475             fillAction = SetDoubleConstant;
476         } else if (info.spillFormat() != DataFormatNone && info.spillFormat() != DataFormatDouble) {
477             // it was already spilled previously and not as a double, which means we need unboxing.
478             ASSERT(info.spillFormat() & DataFormatJS);
479             fillAction = LoadJSUnboxDouble;
480         } else
481             fillAction = LoadDouble;
482 #elif USE(JSVALUE32_64)
483         ASSERT(info.registerFormat() == DataFormatDouble || info.registerFormat() == DataFormatJSDouble);
484         if (node.hasConstant()) {
485             ASSERT(isNumberConstant(nodeIndex));
486             fillAction = SetDoubleConstant;
487         } else
488             fillAction = LoadDouble;
489 #endif
490
491         return SilentRegisterSavePlan(spillAction, fillAction, nodeIndex, source);
492     }
493     
494     void silentSpill(const SilentRegisterSavePlan& plan)
495     {
496         switch (plan.spillAction()) {
497         case DoNothingForSpill:
498             break;
499         case Store32Tag:
500             m_jit.store32(plan.gpr(), JITCompiler::tagFor(at(plan.nodeIndex()).virtualRegister()));
501             break;
502         case Store32Payload:
503             m_jit.store32(plan.gpr(), JITCompiler::payloadFor(at(plan.nodeIndex()).virtualRegister()));
504             break;
505         case StorePtr:
506             m_jit.storePtr(plan.gpr(), JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()));
507             break;
508 #if USE(JSVALUE64)
509         case Store64:
510             m_jit.store64(plan.gpr(), JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()));
511             break;
512 #endif
513         case StoreDouble:
514             m_jit.storeDouble(plan.fpr(), JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()));
515             break;
516         default:
517             ASSERT_NOT_REACHED();
518         }
519     }
520     
521     void silentFill(const SilentRegisterSavePlan& plan, GPRReg canTrample)
522     {
523 #if USE(JSVALUE32_64)
524         UNUSED_PARAM(canTrample);
525 #endif
526         switch (plan.fillAction()) {
527         case DoNothingForFill:
528             break;
529         case SetInt32Constant:
530             m_jit.move(Imm32(valueOfInt32Constant(plan.nodeIndex())), plan.gpr());
531             break;
532         case SetBooleanConstant:
533             m_jit.move(TrustedImm32(valueOfBooleanConstant(plan.nodeIndex())), plan.gpr());
534             break;
535         case SetCellConstant:
536             m_jit.move(TrustedImmPtr(valueOfJSConstant(plan.nodeIndex()).asCell()), plan.gpr());
537             break;
538 #if USE(JSVALUE64)
539         case SetTrustedJSConstant:
540             m_jit.move(valueOfJSConstantAsImm64(plan.nodeIndex()).asTrustedImm64(), plan.gpr());
541             break;
542         case SetJSConstant:
543             m_jit.move(valueOfJSConstantAsImm64(plan.nodeIndex()), plan.gpr());
544             break;
545         case SetDoubleConstant:
546             m_jit.move(Imm64(reinterpretDoubleToInt64(valueOfNumberConstant(plan.nodeIndex()))), canTrample);
547             m_jit.move64ToDouble(canTrample, plan.fpr());
548             break;
549         case Load32PayloadBoxInt:
550             m_jit.load32(JITCompiler::payloadFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
551             m_jit.or64(GPRInfo::tagTypeNumberRegister, plan.gpr());
552             break;
553         case LoadDoubleBoxDouble:
554             m_jit.load64(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
555             m_jit.sub64(GPRInfo::tagTypeNumberRegister, plan.gpr());
556             break;
557         case LoadJSUnboxDouble:
558             m_jit.load64(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), canTrample);
559             unboxDouble(canTrample, plan.fpr());
560             break;
561 #else
562         case SetJSConstantTag:
563             m_jit.move(Imm32(valueOfJSConstant(plan.nodeIndex()).tag()), plan.gpr());
564             break;
565         case SetJSConstantPayload:
566             m_jit.move(Imm32(valueOfJSConstant(plan.nodeIndex()).payload()), plan.gpr());
567             break;
568         case SetInt32Tag:
569             m_jit.move(TrustedImm32(JSValue::Int32Tag), plan.gpr());
570             break;
571         case SetCellTag:
572             m_jit.move(TrustedImm32(JSValue::CellTag), plan.gpr());
573             break;
574         case SetBooleanTag:
575             m_jit.move(TrustedImm32(JSValue::BooleanTag), plan.gpr());
576             break;
577         case SetDoubleConstant:
578             m_jit.loadDouble(addressOfDoubleConstant(plan.nodeIndex()), plan.fpr());
579             break;
580 #endif
581         case Load32Tag:
582             m_jit.load32(JITCompiler::tagFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
583             break;
584         case Load32Payload:
585             m_jit.load32(JITCompiler::payloadFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
586             break;
587         case LoadPtr:
588             m_jit.loadPtr(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
589             break;
590 #if USE(JSVALUE64)
591         case Load64:
592             m_jit.load64(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.gpr());
593             break;
594 #endif
595         case LoadDouble:
596             m_jit.loadDouble(JITCompiler::addressFor(at(plan.nodeIndex()).virtualRegister()), plan.fpr());
597             break;
598         default:
599             ASSERT_NOT_REACHED();
600         }
601     }
602     
603     template<typename CollectionType>
604     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
605     {
606         ASSERT(plans.isEmpty());
607         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
608             GPRReg gpr = iter.regID();
609             if (iter.name() != InvalidVirtualRegister && gpr != exclude && gpr != exclude2) {
610                 SilentRegisterSavePlan plan = silentSavePlanForGPR(iter.name(), gpr);
611                 if (doSpill)
612                     silentSpill(plan);
613                 plans.append(plan);
614             }
615         }
616         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
617             if (iter.name() != InvalidVirtualRegister && iter.regID() != fprExclude) {
618                 SilentRegisterSavePlan plan = silentSavePlanForFPR(iter.name(), iter.regID());
619                 if (doSpill)
620                     silentSpill(plan);
621                 plans.append(plan);
622             }
623         }
624     }
625     template<typename CollectionType>
626     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, NoResultTag)
627     {
628         silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, InvalidFPRReg);
629     }
630     template<typename CollectionType>
631     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, FPRReg exclude)
632     {
633         silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, exclude);
634     }
635 #if USE(JSVALUE32_64)
636     template<typename CollectionType>
637     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, JSValueRegs exclude)
638     {
639         silentSpillAllRegistersImpl(doSpill, plans, exclude.tagGPR(), exclude.payloadGPR());
640     }
641 #endif
642     
643     void silentSpillAllRegisters(GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
644     {
645         silentSpillAllRegistersImpl(true, m_plans, exclude, exclude2, fprExclude);
646     }
647     void silentSpillAllRegisters(FPRReg exclude)
648     {
649         silentSpillAllRegisters(InvalidGPRReg, InvalidGPRReg, exclude);
650     }
651     
652     static GPRReg pickCanTrample(GPRReg exclude)
653     {
654         GPRReg result = GPRInfo::regT0;
655         if (result == exclude)
656             result = GPRInfo::regT1;
657         return result;
658     }
659     static GPRReg pickCanTrample(FPRReg)
660     {
661         return GPRInfo::regT0;
662     }
663     static GPRReg pickCanTrample(NoResultTag)
664     {
665         return GPRInfo::regT0;
666     }
667
668 #if USE(JSVALUE32_64)
669     static GPRReg pickCanTrample(JSValueRegs exclude)
670     {
671         GPRReg result = GPRInfo::regT0;
672         if (result == exclude.tagGPR()) {
673             result = GPRInfo::regT1;
674             if (result == exclude.payloadGPR())
675                 result = GPRInfo::regT2;
676         } else if (result == exclude.payloadGPR()) {
677             result = GPRInfo::regT1;
678             if (result == exclude.tagGPR())
679                 result = GPRInfo::regT2;
680         }
681         return result;
682     }
683 #endif
684     
685     template<typename RegisterType>
686     void silentFillAllRegisters(RegisterType exclude)
687     {
688         GPRReg canTrample = pickCanTrample(exclude);
689         
690         while (!m_plans.isEmpty()) {
691             SilentRegisterSavePlan& plan = m_plans.last();
692             silentFill(plan, canTrample);
693             m_plans.removeLast();
694         }
695     }
696
697     // These methods convert between doubles, and doubles boxed and JSValues.
698 #if USE(JSVALUE64)
699     GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
700     {
701         return m_jit.boxDouble(fpr, gpr);
702     }
703     FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
704     {
705         return m_jit.unboxDouble(gpr, fpr);
706     }
707     GPRReg boxDouble(FPRReg fpr)
708     {
709         return boxDouble(fpr, allocate());
710     }
711 #elif USE(JSVALUE32_64)
712     void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
713     {
714         m_jit.boxDouble(fpr, tagGPR, payloadGPR);
715     }
716     void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
717     {
718         m_jit.unboxDouble(tagGPR, payloadGPR, fpr, scratchFPR);
719     }
720 #endif
721
722     // Spill a VirtualRegister to the JSStack.
723     void spill(VirtualRegister spillMe)
724     {
725         GenerationInfo& info = m_generationInfo[spillMe];
726
727 #if USE(JSVALUE32_64)
728         if (info.registerFormat() == DataFormatNone) // it has been spilled. JS values which have two GPRs can reach here
729             return;
730 #endif
731         // Check the GenerationInfo to see if this value need writing
732         // to the JSStack - if not, mark it as spilled & return.
733         if (!info.needsSpill()) {
734             info.setSpilled(*m_stream, spillMe);
735             return;
736         }
737
738         DataFormat spillFormat = info.registerFormat();
739         switch (spillFormat) {
740         case DataFormatStorage: {
741             // This is special, since it's not a JS value - as in it's not visible to JS
742             // code.
743             m_jit.storePtr(info.gpr(), JITCompiler::addressFor(spillMe));
744             info.spill(*m_stream, spillMe, DataFormatStorage);
745             return;
746         }
747
748         case DataFormatInteger: {
749             m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
750             info.spill(*m_stream, spillMe, DataFormatInteger);
751             return;
752         }
753
754 #if USE(JSVALUE64)
755         case DataFormatDouble: {
756             m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
757             info.spill(*m_stream, spillMe, DataFormatDouble);
758             return;
759         }
760             
761         default:
762             // The following code handles JSValues, int32s, and cells.
763             ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
764             
765             GPRReg reg = info.gpr();
766             // We need to box int32 and cell values ...
767             // but on JSVALUE64 boxing a cell is a no-op!
768             if (spillFormat == DataFormatInteger)
769                 m_jit.or64(GPRInfo::tagTypeNumberRegister, reg);
770             
771             // Spill the value, and record it as spilled in its boxed form.
772             m_jit.store64(reg, JITCompiler::addressFor(spillMe));
773             info.spill(*m_stream, spillMe, (DataFormat)(spillFormat | DataFormatJS));
774             return;
775 #elif USE(JSVALUE32_64)
776         case DataFormatCell:
777         case DataFormatBoolean: {
778             m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
779             info.spill(*m_stream, spillMe, spillFormat);
780             return;
781         }
782
783         case DataFormatDouble:
784         case DataFormatJSDouble: {
785             // On JSVALUE32_64 boxing a double is a no-op.
786             m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
787             info.spill(*m_stream, spillMe, DataFormatJSDouble);
788             return;
789         }
790
791         default:
792             // The following code handles JSValues.
793             ASSERT(spillFormat & DataFormatJS);
794             m_jit.store32(info.tagGPR(), JITCompiler::tagFor(spillMe));
795             m_jit.store32(info.payloadGPR(), JITCompiler::payloadFor(spillMe));
796             info.spill(*m_stream, spillMe, spillFormat);
797             return;
798 #endif
799         }
800     }
801     
802     bool isStrictInt32(NodeIndex);
803     
804     bool isKnownInteger(NodeIndex);
805     bool isKnownNumeric(NodeIndex);
806     bool isKnownCell(NodeIndex);
807     
808     bool isKnownNotInteger(NodeIndex);
809     bool isKnownNotNumber(NodeIndex);
810
811     bool isKnownNotCell(NodeIndex);
812     
813     // Checks/accessors for constant values.
814     bool isConstant(NodeIndex nodeIndex) { return m_jit.graph().isConstant(nodeIndex); }
815     bool isJSConstant(NodeIndex nodeIndex) { return m_jit.graph().isJSConstant(nodeIndex); }
816     bool isInt32Constant(NodeIndex nodeIndex) { return m_jit.graph().isInt32Constant(nodeIndex); }
817     bool isDoubleConstant(NodeIndex nodeIndex) { return m_jit.graph().isDoubleConstant(nodeIndex); }
818     bool isNumberConstant(NodeIndex nodeIndex) { return m_jit.graph().isNumberConstant(nodeIndex); }
819     bool isBooleanConstant(NodeIndex nodeIndex) { return m_jit.graph().isBooleanConstant(nodeIndex); }
820     bool isFunctionConstant(NodeIndex nodeIndex) { return m_jit.graph().isFunctionConstant(nodeIndex); }
821     int32_t valueOfInt32Constant(NodeIndex nodeIndex) { return m_jit.graph().valueOfInt32Constant(nodeIndex); }
822     double valueOfNumberConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfNumberConstant(nodeIndex); }
823     int32_t valueOfNumberConstantAsInt32(NodeIndex nodeIndex)
824     {
825         if (isInt32Constant(nodeIndex))
826             return valueOfInt32Constant(nodeIndex);
827         return JSC::toInt32(valueOfNumberConstant(nodeIndex));
828     }
829 #if USE(JSVALUE32_64)
830     void* addressOfDoubleConstant(NodeIndex nodeIndex) { return m_jit.addressOfDoubleConstant(nodeIndex); }
831 #endif
832     JSValue valueOfJSConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfJSConstant(nodeIndex); }
833     bool valueOfBooleanConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfBooleanConstant(nodeIndex); }
834     JSFunction* valueOfFunctionConstant(NodeIndex nodeIndex) { return m_jit.graph().valueOfFunctionConstant(nodeIndex); }
835     bool isNullConstant(NodeIndex nodeIndex)
836     {
837         if (!isConstant(nodeIndex))
838             return false;
839         return valueOfJSConstant(nodeIndex).isNull();
840     }
841
842     Identifier* identifier(unsigned index)
843     {
844         return &m_jit.codeBlock()->identifier(index);
845     }
846
847     ResolveOperations* resolveOperations(unsigned index)
848     {
849         return m_jit.codeBlock()->resolveOperations(index);
850     }
851
852     PutToBaseOperation* putToBaseOperation(unsigned index)
853     {
854         return m_jit.codeBlock()->putToBaseOperation(index);
855     }
856
857     // Spill all VirtualRegisters back to the JSStack.
858     void flushRegisters()
859     {
860         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
861             if (iter.name() != InvalidVirtualRegister) {
862                 spill(iter.name());
863                 iter.release();
864             }
865         }
866         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
867             if (iter.name() != InvalidVirtualRegister) {
868                 spill(iter.name());
869                 iter.release();
870             }
871         }
872     }
873
874 #ifndef NDEBUG
875     // Used to ASSERT flushRegisters() has been called prior to
876     // calling out from JIT code to a C helper function.
877     bool isFlushed()
878     {
879         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
880             if (iter.name() != InvalidVirtualRegister)
881                 return false;
882         }
883         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
884             if (iter.name() != InvalidVirtualRegister)
885                 return false;
886         }
887         return true;
888     }
889 #endif
890
891 #if USE(JSVALUE64)
892     MacroAssembler::Imm64 valueOfJSConstantAsImm64(NodeIndex nodeIndex)
893     {
894         return MacroAssembler::Imm64(JSValue::encode(valueOfJSConstant(nodeIndex)));
895     }
896 #endif
897
898     // Helper functions to enable code sharing in implementations of bit/shift ops.
899     void bitOp(NodeType op, int32_t imm, GPRReg op1, GPRReg result)
900     {
901         switch (op) {
902         case BitAnd:
903             m_jit.and32(Imm32(imm), op1, result);
904             break;
905         case BitOr:
906             m_jit.or32(Imm32(imm), op1, result);
907             break;
908         case BitXor:
909             m_jit.xor32(Imm32(imm), op1, result);
910             break;
911         default:
912             ASSERT_NOT_REACHED();
913         }
914     }
915     void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
916     {
917         switch (op) {
918         case BitAnd:
919             m_jit.and32(op1, op2, result);
920             break;
921         case BitOr:
922             m_jit.or32(op1, op2, result);
923             break;
924         case BitXor:
925             m_jit.xor32(op1, op2, result);
926             break;
927         default:
928             ASSERT_NOT_REACHED();
929         }
930     }
931     void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
932     {
933         switch (op) {
934         case BitRShift:
935             m_jit.rshift32(op1, Imm32(shiftAmount), result);
936             break;
937         case BitLShift:
938             m_jit.lshift32(op1, Imm32(shiftAmount), result);
939             break;
940         case BitURShift:
941             m_jit.urshift32(op1, Imm32(shiftAmount), result);
942             break;
943         default:
944             ASSERT_NOT_REACHED();
945         }
946     }
947     void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
948     {
949         switch (op) {
950         case BitRShift:
951             m_jit.rshift32(op1, shiftAmount, result);
952             break;
953         case BitLShift:
954             m_jit.lshift32(op1, shiftAmount, result);
955             break;
956         case BitURShift:
957             m_jit.urshift32(op1, shiftAmount, result);
958             break;
959         default:
960             ASSERT_NOT_REACHED();
961         }
962     }
963     
964     // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
965     unsigned detectPeepHoleBranch()
966     {
967         BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
968
969         // Check that no intervening nodes will be generated.
970         for (unsigned index = m_indexInBlock + 1; index < block->size() - 1; ++index) {
971             NodeIndex nodeIndex = block->at(index);
972             if (at(nodeIndex).shouldGenerate())
973                 return UINT_MAX;
974         }
975
976         // Check if the lastNode is a branch on this node.
977         Node& lastNode = at(block->last());
978         return lastNode.op() == Branch && lastNode.child1().index() == m_compileIndex ? block->size() - 1 : UINT_MAX;
979     }
980     
981     void nonSpeculativeValueToNumber(Node&);
982     void nonSpeculativeValueToInt32(Node&);
983     void nonSpeculativeUInt32ToNumber(Node&);
984
985 #if USE(JSVALUE64)
986     void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
987     void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
988 #elif USE(JSVALUE32_64)
989     void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
990     void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
991 #endif
992
993     void nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert = false);
994     void nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex branchNodeIndex, bool invert = false);
995     bool nonSpeculativeCompareNull(Node&, Edge operand, bool invert = false);
996     
997     void nonSpeculativePeepholeBranch(Node&, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
998     void nonSpeculativeNonPeepholeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
999     bool nonSpeculativeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
1000     
1001     void nonSpeculativePeepholeStrictEq(Node&, NodeIndex branchNodeIndex, bool invert = false);
1002     void nonSpeculativeNonPeepholeStrictEq(Node&, bool invert = false);
1003     bool nonSpeculativeStrictEq(Node&, bool invert = false);
1004     
1005     void compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg);
1006     void compileInstanceOf(Node&);
1007     
1008     // Access to our fixed callee CallFrame.
1009     MacroAssembler::Address callFrameSlot(int slot)
1010     {
1011         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + slot) * static_cast<int>(sizeof(Register)));
1012     }
1013
1014     // Access to our fixed callee CallFrame.
1015     MacroAssembler::Address argumentSlot(int argument)
1016     {
1017         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)));
1018     }
1019
1020     MacroAssembler::Address callFrameTagSlot(int slot)
1021     {
1022         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + slot) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
1023     }
1024
1025     MacroAssembler::Address callFramePayloadSlot(int slot)
1026     {
1027         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + slot) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
1028     }
1029
1030     MacroAssembler::Address argumentTagSlot(int argument)
1031     {
1032         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
1033     }
1034
1035     MacroAssembler::Address argumentPayloadSlot(int argument)
1036     {
1037         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
1038     }
1039
1040     void emitCall(Node&);
1041     
1042     // Called once a node has completed code generation but prior to setting
1043     // its result, to free up its children. (This must happen prior to setting
1044     // the nodes result, since the node may have the same VirtualRegister as
1045     // a child, and as such will use the same GeneratioInfo).
1046     void useChildren(Node&);
1047
1048     // These method called to initialize the the GenerationInfo
1049     // to describe the result of an operation.
1050     void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger, UseChildrenMode mode = CallUseChildren)
1051     {
1052         Node& node = at(nodeIndex);
1053         if (mode == CallUseChildren)
1054             useChildren(node);
1055
1056         VirtualRegister virtualRegister = node.virtualRegister();
1057         GenerationInfo& info = m_generationInfo[virtualRegister];
1058
1059         if (format == DataFormatInteger) {
1060             m_jit.jitAssertIsInt32(reg);
1061             m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
1062             info.initInteger(nodeIndex, node.refCount(), reg);
1063         } else {
1064 #if USE(JSVALUE64)
1065             ASSERT(format == DataFormatJSInteger);
1066             m_jit.jitAssertIsJSInt32(reg);
1067             m_gprs.retain(reg, virtualRegister, SpillOrderJS);
1068             info.initJSValue(nodeIndex, node.refCount(), reg, format);
1069 #elif USE(JSVALUE32_64)
1070             ASSERT_NOT_REACHED();
1071 #endif
1072         }
1073     }
1074     void integerResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
1075     {
1076         integerResult(reg, nodeIndex, DataFormatInteger, mode);
1077     }
1078     void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1079     {
1080         if (mode == UseChildrenCalledExplicitly)
1081             return;
1082         Node& node = at(nodeIndex);
1083         useChildren(node);
1084     }
1085     void cellResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1086     {
1087         Node& node = at(nodeIndex);
1088         if (mode == CallUseChildren)
1089             useChildren(node);
1090
1091         VirtualRegister virtualRegister = node.virtualRegister();
1092         m_gprs.retain(reg, virtualRegister, SpillOrderCell);
1093         GenerationInfo& info = m_generationInfo[virtualRegister];
1094         info.initCell(nodeIndex, node.refCount(), reg);
1095     }
1096     void booleanResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1097     {
1098         Node& node = at(nodeIndex);
1099         if (mode == CallUseChildren)
1100             useChildren(node);
1101
1102         VirtualRegister virtualRegister = node.virtualRegister();
1103         m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
1104         GenerationInfo& info = m_generationInfo[virtualRegister];
1105         info.initBoolean(nodeIndex, node.refCount(), reg);
1106     }
1107 #if USE(JSVALUE64)
1108     void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
1109     {
1110         if (format == DataFormatJSInteger)
1111             m_jit.jitAssertIsJSInt32(reg);
1112         
1113         Node& node = at(nodeIndex);
1114         if (mode == CallUseChildren)
1115             useChildren(node);
1116
1117         VirtualRegister virtualRegister = node.virtualRegister();
1118         m_gprs.retain(reg, virtualRegister, SpillOrderJS);
1119         GenerationInfo& info = m_generationInfo[virtualRegister];
1120         info.initJSValue(nodeIndex, node.refCount(), reg, format);
1121     }
1122     void jsValueResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
1123     {
1124         jsValueResult(reg, nodeIndex, DataFormatJS, mode);
1125     }
1126 #elif USE(JSVALUE32_64)
1127     void jsValueResult(GPRReg tag, GPRReg payload, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
1128     {
1129         Node& node = at(nodeIndex);
1130         if (mode == CallUseChildren)
1131             useChildren(node);
1132
1133         VirtualRegister virtualRegister = node.virtualRegister();
1134         m_gprs.retain(tag, virtualRegister, SpillOrderJS);
1135         m_gprs.retain(payload, virtualRegister, SpillOrderJS);
1136         GenerationInfo& info = m_generationInfo[virtualRegister];
1137         info.initJSValue(nodeIndex, node.refCount(), tag, payload, format);
1138     }
1139     void jsValueResult(GPRReg tag, GPRReg payload, NodeIndex nodeIndex, UseChildrenMode mode)
1140     {
1141         jsValueResult(tag, payload, nodeIndex, DataFormatJS, mode);
1142     }
1143 #endif
1144     void storageResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1145     {
1146         Node& node = at(nodeIndex);
1147         if (mode == CallUseChildren)
1148             useChildren(node);
1149         
1150         VirtualRegister virtualRegister = node.virtualRegister();
1151         m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
1152         GenerationInfo& info = m_generationInfo[virtualRegister];
1153         info.initStorage(nodeIndex, node.refCount(), reg);
1154     }
1155     void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1156     {
1157         Node& node = at(nodeIndex);
1158         if (mode == CallUseChildren)
1159             useChildren(node);
1160
1161         VirtualRegister virtualRegister = node.virtualRegister();
1162         m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
1163         GenerationInfo& info = m_generationInfo[virtualRegister];
1164         info.initDouble(nodeIndex, node.refCount(), reg);
1165     }
1166     void initConstantInfo(NodeIndex nodeIndex)
1167     {
1168         ASSERT(isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex) || isJSConstant(nodeIndex));
1169         Node& node = at(nodeIndex);
1170         m_generationInfo[node.virtualRegister()].initConstant(nodeIndex, node.refCount());
1171     }
1172     
1173     // These methods add calls to C++ helper functions.
1174     // These methods are broadly value representation specific (i.e.
1175     // deal with the fact that a JSValue may be passed in one or two
1176     // machine registers, and delegate the calling convention specific
1177     // decision as to how to fill the regsiters to setupArguments* methods.
1178 #if USE(JSVALUE64)
1179     JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
1180     {
1181         m_jit.setupArgumentsExecState();
1182         return appendCallWithExceptionCheckSetResult(operation, result);
1183     }
1184     JITCompiler::Call callOperation(P_DFGOperation_EO operation, GPRReg result, GPRReg object)
1185     {
1186         m_jit.setupArgumentsWithExecState(object);
1187         return appendCallWithExceptionCheckSetResult(operation, result);
1188     }
1189     JITCompiler::Call callOperation(P_DFGOperation_EOS operation, GPRReg result, GPRReg object, size_t size)
1190     {
1191         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
1192         return appendCallWithExceptionCheckSetResult(operation, result);
1193     }
1194     JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
1195     {
1196         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
1197         return appendCallWithExceptionCheckSetResult(operation, result);
1198     }
1199     JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
1200     {
1201         m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
1202         return appendCallWithExceptionCheckSetResult(operation, result);
1203     }
1204     JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
1205     {
1206         m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
1207         return appendCallWithExceptionCheckSetResult(operation, result);
1208     }
1209     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result)
1210     {
1211         m_jit.setupArgumentsExecState();
1212         return appendCallWithExceptionCheckSetResult(operation, result);
1213     }
1214     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, void* pointer)
1215     {
1216         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1217         return appendCallWithExceptionCheckSetResult(operation, result);
1218     }
1219     JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
1220     {
1221         m_jit.setupArguments(arg1);
1222         JITCompiler::Call call = m_jit.appendCall(operation);
1223         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1224         return call;
1225     }
1226     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1227     {
1228         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1229         return appendCallWithExceptionCheckSetResult(operation, result);
1230     }
1231     JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg result, Identifier* identifier)
1232     {
1233         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
1234         return appendCallWithExceptionCheckSetResult(operation, result);
1235     }
1236     JITCompiler::Call callOperation(J_DFGOperation_EIRo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations)
1237     {
1238         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations));
1239         return appendCallWithExceptionCheckSetResult(operation, result);
1240     }
1241     JITCompiler::Call callOperation(J_DFGOperation_EIRoPtbo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1242     {
1243         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations), TrustedImmPtr(putToBaseOperations));
1244         return appendCallWithExceptionCheckSetResult(operation, result);
1245     }
1246     JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg result, GPRReg arg1)
1247     {
1248         m_jit.setupArgumentsWithExecState(arg1);
1249         return appendCallWithExceptionCheckSetResult(operation, result);
1250     }
1251     JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1252     {
1253         m_jit.setupArgumentsWithExecState(arg1, arg2);
1254         return appendCallWithExceptionCheckSetResult(operation, result);
1255     }
1256     JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure)
1257     {
1258         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1259         return appendCallWithExceptionCheckSetResult(operation, result);
1260     }
1261     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
1262     {
1263         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1264         return appendCallWithExceptionCheckSetResult(operation, result);
1265     }
1266     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
1267     {
1268         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
1269         return appendCallWithExceptionCheckSetResult(operation, result);
1270     }
1271     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1272     {
1273         m_jit.setupArgumentsWithExecState(arg1, arg2);
1274         return appendCallWithExceptionCheckSetResult(operation, result);
1275     }
1276     JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
1277     {
1278         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
1279         return appendCallWithExceptionCheckSetResult(operation, result);
1280     }
1281     JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
1282     {
1283         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
1284         return appendCallWithExceptionCheckSetResult(operation, result);
1285     }
1286     JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg result, void* pointer, size_t size)
1287     {
1288         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1289         return appendCallWithExceptionCheckSetResult(operation, result);
1290     }
1291     JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
1292     {
1293         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1294         return appendCallWithExceptionCheckSetResult(operation, result);
1295     }
1296     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
1297     {
1298         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1299         return appendCallWithExceptionCheckSetResult(operation, result);
1300     }
1301     JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
1302     {
1303         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1304         return appendCallWithExceptionCheckSetResult(operation, result);
1305     }
1306     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
1307     {
1308         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1309         return appendCallWithExceptionCheckSetResult(operation, result);
1310     }
1311     JITCompiler::Call callOperation(J_DFGOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
1312     {
1313         m_jit.setupArgumentsWithExecState(arg1, arg2);
1314         return appendCallWithExceptionCheckSetResult(operation, result);
1315     }
1316     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1317     {
1318         m_jit.setupArgumentsWithExecState(arg1, arg2);
1319         return appendCallWithExceptionCheckSetResult(operation, result);
1320     }
1321     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, GPRReg arg1)
1322     {
1323         m_jit.setupArgumentsWithExecState(arg1);
1324         return appendCallWithExceptionCheckSetResult(operation, result);
1325     }
1326     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, GPRReg arg1)
1327     {
1328         m_jit.setupArgumentsWithExecState(arg1);
1329         return appendCallWithExceptionCheckSetResult(operation, result);
1330     }
1331     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, int32_t arg1)
1332     {
1333         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1334         return appendCallWithExceptionCheckSetResult(operation, result);
1335     }
1336     JITCompiler::Call callOperation(J_DFGOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
1337     {
1338         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1339         return appendCallWithExceptionCheckSetResult(operation, result);
1340     }
1341     JITCompiler::Call callOperation(J_DFGOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1342     {
1343         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1344         return appendCallWithExceptionCheckSetResult(operation, result);
1345     }
1346     JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
1347     {
1348         m_jit.setupArgumentsExecState();
1349         return appendCallWithExceptionCheckSetResult(operation, result);
1350     }
1351     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
1352     {
1353         m_jit.setupArgumentsWithExecState(arg1);
1354         return appendCallWithExceptionCheckSetResult(operation, result);
1355     }
1356     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
1357     {
1358         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1359         return appendCallWithExceptionCheckSetResult(operation, result);
1360     }
1361     JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1362     {
1363         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1364         return appendCallWithExceptionCheckSetResult(operation, result);
1365     }
1366     JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
1367     {
1368         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1369         return appendCallWithExceptionCheckSetResult(operation, result);
1370     }
1371     JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1)
1372     {
1373         m_jit.setupArguments(arg1);
1374         return appendCallSetResult(operation, result);
1375     }
1376     JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
1377     {
1378         m_jit.setupArgumentsWithExecState(arg1);
1379         return appendCallWithExceptionCheckSetResult(operation, result);
1380     }
1381     JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
1382     {
1383         m_jit.setupArgumentsWithExecState(arg1);
1384         return appendCallWithExceptionCheckSetResult(operation, result);
1385     }
1386     JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1387     {
1388         m_jit.setupArgumentsWithExecState(arg1, arg2);
1389         return appendCallWithExceptionCheckSetResult(operation, result);
1390     }
1391     JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1392     {
1393         m_jit.setupArgumentsWithExecState(arg1, arg2);
1394         return appendCallWithExceptionCheckSetResult(operation, result);
1395     }
1396     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1397     {
1398         m_jit.setupArgumentsWithExecState(arg1, arg2);
1399         return appendCallWithExceptionCheckSetResult(operation, result);
1400     }
1401     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1402     {
1403         m_jit.setupArgumentsWithExecState(arg1, arg2);
1404         return appendCallWithExceptionCheckSetResult(operation, result);
1405     }
1406     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
1407     {
1408         m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
1409         return appendCallWithExceptionCheckSetResult(operation, result);
1410     }
1411     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
1412     {
1413         m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
1414         return appendCallWithExceptionCheckSetResult(operation, result);
1415     }
1416     JITCompiler::Call callOperation(J_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1417     {
1418         m_jit.setupArgumentsWithExecState(arg1, arg2);
1419         return appendCallWithExceptionCheckSetResult(operation, result);
1420     }
1421     JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1422     {
1423         m_jit.setupArgumentsWithExecState(arg1, arg2);
1424         return appendCallWithExceptionCheckSetResult(operation, result);
1425     }
1426     JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
1427     {
1428         m_jit.setupArgumentsWithExecState(arg1);
1429         return appendCallWithExceptionCheck(operation);
1430     }
1431     JITCompiler::Call callOperation(V_DFGOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* arg2)
1432     {
1433         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1434         return appendCallWithExceptionCheck(operation);
1435     }
1436     JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* arg3)
1437     {
1438         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arg3));
1439         return appendCallWithExceptionCheck(operation);
1440     }
1441     JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
1442     {
1443         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1444         return appendCallWithExceptionCheck(operation);
1445     }
1446     JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1447     {
1448         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1449         return appendCallWithExceptionCheck(operation);
1450     }
1451     JITCompiler::Call callOperation(V_DFGOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1452     {
1453         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1454         return appendCallWithExceptionCheck(operation);
1455     }
1456     JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1457     {
1458         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1459         return appendCallWithExceptionCheck(operation);
1460     }
1461     JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1462     {
1463         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1464         return appendCallWithExceptionCheck(operation);
1465     }
1466     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1467     {
1468         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1469         return appendCallWithExceptionCheck(operation);
1470     }
1471     JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1472     {
1473         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1474         return appendCallWithExceptionCheck(operation);
1475     }
1476     JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
1477     {
1478         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1479         return appendCallWithExceptionCheck(operation);
1480     }
1481     JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1482     {
1483         m_jit.setupArgumentsWithExecState(arg1, arg2);
1484         return appendCallWithExceptionCheck(operation);
1485     }
1486     JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
1487     {
1488         m_jit.setupArguments(TrustedImmPtr(watchpointSet));
1489         return appendCall(operation);
1490     }
1491     template<typename FunctionType, typename ArgumentType1>
1492     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1493     {
1494         return callOperation(operation, arg1);
1495     }
1496     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1497     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1498     {
1499         return callOperation(operation, arg1, arg2);
1500     }
1501     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1502     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1503     {
1504         return callOperation(operation, arg1, arg2, arg3);
1505     }
1506     JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1)
1507     {
1508         m_jit.setupArgumentsWithExecState(arg1);
1509         return appendCallWithExceptionCheckSetResult(operation, result);
1510     }
1511     JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1512     {
1513         m_jit.setupArguments(arg1, arg2);
1514         return appendCallSetResult(operation, result);
1515     }
1516     JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1517     {
1518         m_jit.setupArguments(arg1, arg2);
1519         return appendCallSetResult(operation, result);
1520     }
1521 #else
1522
1523 // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
1524 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1525 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
1526 #define EABI_32BIT_DUMMY_ARG      TrustedImm32(0),
1527 #else
1528 #define EABI_32BIT_DUMMY_ARG
1529 #endif
1530
1531     JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
1532     {
1533         m_jit.setupArgumentsExecState();
1534         return appendCallWithExceptionCheckSetResult(operation, result);
1535     }
1536     JITCompiler::Call callOperation(P_DFGOperation_EO operation, GPRReg result, GPRReg arg1)
1537     {
1538         m_jit.setupArgumentsWithExecState(arg1);
1539         return appendCallWithExceptionCheckSetResult(operation, result);
1540     }
1541     JITCompiler::Call callOperation(P_DFGOperation_EOS operation, GPRReg result, GPRReg arg1, size_t arg2)
1542     {
1543         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1544         return appendCallWithExceptionCheckSetResult(operation, result);
1545     }
1546     JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
1547     {
1548         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1549         return appendCallWithExceptionCheckSetResult(operation, result);
1550     }
1551     JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
1552     {
1553         m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
1554         return appendCallWithExceptionCheckSetResult(operation, result);
1555     }
1556     JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
1557     {
1558         m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
1559         return appendCallWithExceptionCheckSetResult(operation, result);
1560     }
1561     JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
1562     {
1563         prepareForExternalCall();
1564         m_jit.setupArguments(arg1);
1565         JITCompiler::Call call = m_jit.appendCall(operation);
1566         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1567         return call;
1568     }
1569     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
1570     {
1571         m_jit.setupArgumentsExecState();
1572         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1573     }
1574     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
1575     {
1576         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1577         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1578     }
1579     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
1580     {
1581         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1582         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1583     }
1584     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1585     {
1586         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1587         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1588     }
1589     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1590     {
1591         m_jit.setupArgumentsWithExecState(arg1);
1592         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1593     }
1594     JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier)
1595     {
1596         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
1597         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1598     }
1599     JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1600     {
1601         m_jit.setupArgumentsWithExecState(arg1);
1602         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1603     }
1604     JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1605     {
1606         m_jit.setupArgumentsWithExecState(arg1, arg2);
1607         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1608     }
1609     JITCompiler::Call callOperation(P_DFGOperation_ESt operation, GPRReg result, Structure* structure)
1610     {
1611         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1612         return appendCallWithExceptionCheckSetResult(operation, result);
1613     }
1614     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
1615     {
1616         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1617         return appendCallWithExceptionCheckSetResult(operation, result);
1618     }
1619     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
1620     {
1621         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
1622         return appendCallWithExceptionCheckSetResult(operation, result);
1623     }
1624     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1625     {
1626         m_jit.setupArgumentsWithExecState(arg1, arg2);
1627         return appendCallWithExceptionCheckSetResult(operation, result);
1628     }
1629     JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
1630     {
1631         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
1632         return appendCallWithExceptionCheckSetResult(operation, result);
1633     }
1634     JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
1635     {
1636         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
1637         return appendCallWithExceptionCheckSetResult(operation, result);
1638     }
1639     JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
1640     {
1641         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1642         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1643     }
1644     JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
1645     {
1646         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1647         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1648     }
1649     JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
1650     {
1651         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
1652         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1653     }
1654     JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1655     {
1656         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1657         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1658     }
1659     JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, Identifier* identifier)
1660     {
1661         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1662         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1663     }
1664     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, Identifier* identifier)
1665     {
1666         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(identifier));
1667         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1668     }
1669     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1Tag, GPRReg arg1Payload, Identifier* identifier)
1670     {
1671         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(identifier));
1672         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1673     }
1674     JITCompiler::Call callOperation(J_DFGOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2)
1675     {
1676         m_jit.setupArgumentsWithExecState(arg1, arg2);
1677         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1678     }
1679     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1680     {
1681         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1682         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1683     }
1684     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1685     {
1686         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1687         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1688     }
1689     JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
1690     {
1691         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1692         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1693     }
1694     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1695     {
1696         m_jit.setupArgumentsWithExecState(arg1);
1697         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1698     }
1699     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
1700     {
1701         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1702         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1703     }
1704     JITCompiler::Call callOperation(J_DFGOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1705     {
1706         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1707         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1708     }
1709     JITCompiler::Call callOperation(J_DFGOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
1710     {
1711         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1712         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1713     }
1714     JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
1715     {
1716         m_jit.setupArgumentsExecState();
1717         return appendCallWithExceptionCheckSetResult(operation, result);
1718     }
1719     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
1720     {
1721         m_jit.setupArgumentsWithExecState(arg1);
1722         return appendCallWithExceptionCheckSetResult(operation, result);
1723     }
1724     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
1725     {
1726         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1727         return appendCallWithExceptionCheckSetResult(operation, result);
1728     }
1729     JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1730     {
1731         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1732         return appendCallWithExceptionCheckSetResult(operation, result);
1733     }
1734     JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
1735     {
1736         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1737         return appendCallWithExceptionCheckSetResult(operation, result);
1738     }
1739     JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1740     {
1741         m_jit.setupArguments(arg1Payload, arg1Tag);
1742         return appendCallSetResult(operation, result);
1743     }
1744     JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1745     {
1746         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1747         return appendCallWithExceptionCheckSetResult(operation, result);
1748     }
1749     JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1750     {
1751         m_jit.setupArgumentsWithExecState(arg1, arg2);
1752         return appendCallWithExceptionCheckSetResult(operation, result);
1753     }
1754     JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1755     {
1756         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1757         return appendCallWithExceptionCheckSetResult(operation, result);
1758     }
1759     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1760     {
1761         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1762         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1763     }
1764     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
1765     {
1766         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag));
1767         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1768     }
1769     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
1770     {
1771         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag);
1772         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1773     }
1774
1775     JITCompiler::Call callOperation(J_DFGOperation_EIRo operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier, ResolveOperations* operations)
1776     {
1777         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations));
1778         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1779     }
1780
1781     JITCompiler::Call callOperation(J_DFGOperation_EIRoPtbo operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1782     {
1783         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations), TrustedImmPtr(putToBaseOperations));
1784         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1785     }
1786
1787     JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
1788     {
1789         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
1790         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1791     }
1792     JITCompiler::Call callOperation(J_DFGOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1793     {
1794         m_jit.setupArgumentsWithExecState(arg1, arg2);
1795         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1796     }
1797     JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
1798     {
1799         m_jit.setupArgumentsWithExecState(arg1);
1800         return appendCallWithExceptionCheck(operation);
1801     }
1802     JITCompiler::Call callOperation(V_DFGOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
1803     {
1804         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1805         return appendCallWithExceptionCheck(operation);
1806     }
1807     JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
1808     {
1809         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1810         return appendCallWithExceptionCheck(operation);
1811     }
1812     JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
1813     {
1814         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
1815         return appendCallWithExceptionCheck(operation);
1816     }
1817     JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, Identifier* identifier)
1818     {
1819         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(identifier));
1820         return appendCallWithExceptionCheck(operation);
1821     }
1822     JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1823     {
1824         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1825         return appendCallWithExceptionCheck(operation);
1826     }
1827     JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
1828     {
1829         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1830         return appendCallWithExceptionCheck(operation);
1831     }
1832     JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1833     {
1834         m_jit.setupArgumentsWithExecState(arg1, arg2);
1835         return appendCallWithExceptionCheck(operation);
1836     }
1837     JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1838     {
1839         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1840         return appendCallWithExceptionCheck(operation);
1841     }
1842     JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1843     {
1844         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1845         return appendCallWithExceptionCheck(operation);
1846     }
1847     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1848     {
1849         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1850         return appendCallWithExceptionCheck(operation);
1851     }
1852     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
1853     {
1854         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1855         return appendCallWithExceptionCheck(operation);
1856     }
1857     JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
1858     {
1859         m_jit.setupArguments(TrustedImmPtr(watchpointSet));
1860         return appendCall(operation);
1861     }
1862     template<typename FunctionType, typename ArgumentType1>
1863     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1864     {
1865         return callOperation(operation, arg1);
1866     }
1867     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1868     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1869     {
1870         return callOperation(operation, arg1, arg2);
1871     }
1872     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1873     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1874     {
1875         return callOperation(operation, arg1, arg2, arg3);
1876     }
1877     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4>
1878     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4)
1879     {
1880         return callOperation(operation, arg1, arg2, arg3, arg4);
1881     }
1882     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1883     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1884     {
1885         return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
1886     }
1887
1888     JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1889     {
1890         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1891         return appendCallWithExceptionCheckSetResult(operation, result);
1892     }
1893
1894     JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1895     {
1896         m_jit.setupArguments(arg1, arg2);
1897         return appendCallSetResult(operation, result);
1898     }
1899     JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1900     {
1901         m_jit.setupArguments(arg1, arg2);
1902         return appendCallSetResult(operation, result);
1903     }
1904
1905 #undef EABI_32BIT_DUMMY_ARG
1906     
1907     template<typename FunctionType>
1908     JITCompiler::Call callOperation(
1909         FunctionType operation, JSValueRegs result)
1910     {
1911         return callOperation(operation, result.tagGPR(), result.payloadGPR());
1912     }
1913     template<typename FunctionType, typename ArgumentType1>
1914     JITCompiler::Call callOperation(
1915         FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
1916     {
1917         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
1918     }
1919     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1920     JITCompiler::Call callOperation(
1921         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1922     {
1923         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1924     }
1925     template<
1926         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1927         typename ArgumentType3>
1928     JITCompiler::Call callOperation(
1929         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1930         ArgumentType3 arg3)
1931     {
1932         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1933     }
1934     template<
1935         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1936         typename ArgumentType3, typename ArgumentType4>
1937     JITCompiler::Call callOperation(
1938         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1939         ArgumentType3 arg3, ArgumentType4 arg4)
1940     {
1941         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1942     }
1943     template<
1944         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1945         typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1946     JITCompiler::Call callOperation(
1947         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1948         ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1949     {
1950         return callOperation(
1951             operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1952     }
1953 #endif
1954     
1955 #if !defined(NDEBUG) && !CPU(ARM)
1956     void prepareForExternalCall()
1957     {
1958         // We're about to call out to a "native" helper function. The helper
1959         // function is expected to set topCallFrame itself with the ExecState
1960         // that is passed to it.
1961         //
1962         // We explicitly trash topCallFrame here so that we'll know if some of
1963         // the helper functions are not setting topCallFrame when they should
1964         // be doing so. Note: the previous value in topcallFrame was not valid
1965         // anyway since it was not being updated by JIT'ed code by design.
1966
1967         for (unsigned i = 0; i < sizeof(void*) / 4; i++)
1968             m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.globalData()->topCallFrame) + i * 4);
1969     }
1970 #else
1971     void prepareForExternalCall() { }
1972 #endif
1973
1974     // These methods add call instructions, with optional exception checks & setting results.
1975     JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
1976     {
1977         prepareForExternalCall();
1978         CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
1979         CallBeginToken token;
1980         m_jit.beginCall(codeOrigin, token);
1981         JITCompiler::Call call = m_jit.appendCall(function);
1982         m_jit.addExceptionCheck(call, codeOrigin, token);
1983         return call;
1984     }
1985     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
1986     {
1987         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1988         m_jit.move(GPRInfo::returnValueGPR, result);
1989         return call;
1990     }
1991     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1992     {
1993         prepareForExternalCall();
1994         JITCompiler::Call call = m_jit.appendCall(function);
1995         m_jit.move(GPRInfo::returnValueGPR, result);
1996         return call;
1997     }
1998     JITCompiler::Call appendCall(const FunctionPtr& function)
1999     {
2000         prepareForExternalCall();
2001         return m_jit.appendCall(function);
2002     }
2003     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
2004     {
2005         JITCompiler::Call call = appendCallWithExceptionCheck(function);
2006         m_jit.setupResults(result1, result2);
2007         return call;
2008     }
2009 #if CPU(X86)
2010     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
2011     {
2012         JITCompiler::Call call = appendCallWithExceptionCheck(function);
2013         m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
2014         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
2015         return call;
2016     }
2017     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
2018     {
2019         JITCompiler::Call call = m_jit.appendCall(function);
2020         m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
2021         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
2022         return call;
2023     }
2024 #elif CPU(ARM)
2025 #if CPU(ARM_HARDFP)
2026     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
2027     {
2028         JITCompiler::Call call = appendCallWithExceptionCheck(function);
2029         m_jit.moveDouble(result, FPRInfo::argumentFPR0);
2030         return call;
2031     }
2032     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
2033     {
2034         JITCompiler::Call call = m_jit.appendCall(function);
2035         m_jit.moveDouble(result, FPRInfo::argumentFPR0);
2036         return call;
2037     }
2038 #else
2039         JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
2040     {
2041         JITCompiler::Call call = appendCallWithExceptionCheck(function);
2042         m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
2043         return call;
2044     }
2045     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
2046     {
2047         JITCompiler::Call call = m_jit.appendCall(function);
2048         m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
2049         return call;
2050     }
2051 #endif // CPU(ARM_HARDFP)
2052 #else
2053     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
2054     {
2055         JITCompiler::Call call = appendCallWithExceptionCheck(function);
2056         m_jit.moveDouble(FPRInfo::returnValueFPR, result);
2057         return call;
2058     }
2059     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
2060     {
2061         JITCompiler::Call call = m_jit.appendCall(function);
2062         m_jit.moveDouble(FPRInfo::returnValueFPR, result);
2063         return call;
2064     }
2065 #endif
2066     
2067     void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BlockIndex destination)
2068     {
2069         if (!haveEdgeCodeToEmit(destination))
2070             return addBranch(m_jit.branchDouble(cond, left, right), destination);
2071         
2072         JITCompiler::Jump notTaken = m_jit.branchDouble(JITCompiler::invert(cond), left, right);
2073         emitEdgeCode(destination);
2074         addBranch(m_jit.jump(), destination);
2075         notTaken.link(&m_jit);
2076     }
2077     
2078     void branchDoubleNonZero(FPRReg value, FPRReg scratch, BlockIndex destination)
2079     {
2080         if (!haveEdgeCodeToEmit(destination))
2081             return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
2082         
2083         JITCompiler::Jump notTaken = m_jit.branchDoubleZeroOrNaN(value, scratch);
2084         emitEdgeCode(destination);
2085         addBranch(m_jit.jump(), destination);
2086         notTaken.link(&m_jit);
2087     }
2088     
2089     template<typename T, typename U>
2090     void branch32(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
2091     {
2092         if (!haveEdgeCodeToEmit(destination))
2093             return addBranch(m_jit.branch32(cond, left, right), destination);
2094         
2095         JITCompiler::Jump notTaken = m_jit.branch32(JITCompiler::invert(cond), left, right);
2096         emitEdgeCode(destination);
2097         addBranch(m_jit.jump(), destination);
2098         notTaken.link(&m_jit);
2099     }
2100     
2101     template<typename T, typename U>
2102     void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
2103     {
2104         ASSERT(JITCompiler::isInvertible(cond));
2105         
2106         if (!haveEdgeCodeToEmit(destination))
2107             return addBranch(m_jit.branchTest32(cond, value, mask), destination);
2108         
2109         JITCompiler::Jump notTaken = m_jit.branchTest32(JITCompiler::invert(cond), value, mask);
2110         emitEdgeCode(destination);
2111         addBranch(m_jit.jump(), destination);
2112         notTaken.link(&m_jit);
2113     }
2114     
2115     template<typename T>
2116     void branchTest32(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
2117     {
2118         ASSERT(JITCompiler::isInvertible(cond));
2119         
2120         if (!haveEdgeCodeToEmit(destination))
2121             return addBranch(m_jit.branchTest32(cond, value), destination);
2122         
2123         JITCompiler::Jump notTaken = m_jit.branchTest32(JITCompiler::invert(cond), value);
2124         emitEdgeCode(destination);
2125         addBranch(m_jit.jump(), destination);
2126         notTaken.link(&m_jit);
2127     }
2128     
2129 #if USE(JSVALUE64)
2130     template<typename T, typename U>
2131     void branch64(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
2132     {
2133         if (!haveEdgeCodeToEmit(destination))
2134             return addBranch(m_jit.branch64(cond, left, right), destination);
2135         
2136         JITCompiler::Jump notTaken = m_jit.branch64(JITCompiler::invert(cond), left, right);
2137         emitEdgeCode(destination);
2138         addBranch(m_jit.jump(), destination);
2139         notTaken.link(&m_jit);
2140     }
2141 #endif
2142     
2143     template<typename T, typename U>
2144     void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
2145     {
2146         if (!haveEdgeCodeToEmit(destination))
2147             return addBranch(m_jit.branchPtr(cond, left, right), destination);
2148         
2149         JITCompiler::Jump notTaken = m_jit.branchPtr(JITCompiler::invert(cond), left, right);
2150         emitEdgeCode(destination);
2151         addBranch(m_jit.jump(), destination);
2152         notTaken.link(&m_jit);
2153     }
2154     
2155     template<typename T, typename U>
2156     void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
2157     {
2158         ASSERT(JITCompiler::isInvertible(cond));
2159         
2160         if (!haveEdgeCodeToEmit(destination))
2161             return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
2162         
2163         JITCompiler::Jump notTaken = m_jit.branchTestPtr(JITCompiler::invert(cond), value, mask);
2164         emitEdgeCode(destination);
2165         addBranch(m_jit.jump(), destination);
2166         notTaken.link(&m_jit);
2167     }
2168     
2169     template<typename T>
2170     void branchTestPtr(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
2171     {
2172         ASSERT(JITCompiler::isInvertible(cond));
2173         
2174         if (!haveEdgeCodeToEmit(destination))
2175             return addBranch(m_jit.branchTestPtr(cond, value), destination);
2176         
2177         JITCompiler::Jump notTaken = m_jit.branchTestPtr(JITCompiler::invert(cond), value);
2178         emitEdgeCode(destination);
2179         addBranch(m_jit.jump(), destination);
2180         notTaken.link(&m_jit);
2181     }
2182     
2183     template<typename T, typename U>
2184     void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
2185     {
2186         ASSERT(JITCompiler::isInvertible(cond));
2187         
2188         if (!haveEdgeCodeToEmit(destination))
2189             return addBranch(m_jit.branchTest8(cond, value, mask), destination);
2190         
2191         JITCompiler::Jump notTaken = m_jit.branchTest8(JITCompiler::invert(cond), value, mask);
2192         emitEdgeCode(destination);
2193         addBranch(m_jit.jump(), destination);
2194         notTaken.link(&m_jit);
2195     }
2196     
2197     template<typename T>
2198     void branchTest8(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
2199     {
2200         ASSERT(JITCompiler::isInvertible(cond));
2201         
2202         if (!haveEdgeCodeToEmit(destination))
2203             return addBranch(m_jit.branchTest8(cond, value), destination);
2204         
2205         JITCompiler::Jump notTaken = m_jit.branchTest8(JITCompiler::invert(cond), value);
2206         emitEdgeCode(destination);
2207         addBranch(m_jit.jump(), destination);
2208         notTaken.link(&m_jit);
2209     }
2210     
2211     enum FallThroughMode {
2212         AtFallThroughPoint,
2213         ForceJump
2214     };
2215     void jump(BlockIndex destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
2216     {
2217         if (haveEdgeCodeToEmit(destination))
2218             emitEdgeCode(destination);
2219         if (destination == nextBlock()
2220             && fallThroughMode == AtFallThroughPoint)
2221             return;
2222         addBranch(m_jit.jump(), destination);
2223     }
2224     
2225     inline bool haveEdgeCodeToEmit(BlockIndex)
2226     {
2227         return DFG_ENABLE_EDGE_CODE_VERIFICATION;
2228     }
2229     void emitEdgeCode(BlockIndex destination)
2230     {
2231         if (!DFG_ENABLE_EDGE_CODE_VERIFICATION)
2232             return;
2233         m_jit.move(TrustedImm32(destination), GPRInfo::regT0);
2234     }
2235
2236     void addBranch(const MacroAssembler::Jump& jump, BlockIndex destination)
2237     {
2238         m_branches.append(BranchRecord(jump, destination));
2239     }
2240
2241     void linkBranches()
2242     {
2243         for (size_t i = 0; i < m_branches.size(); ++i) {
2244             BranchRecord& branch = m_branches[i];
2245             branch.jump.linkTo(m_blockHeads[branch.destination], &m_jit);
2246         }
2247     }
2248
2249     BasicBlock* block()
2250     {
2251         return m_jit.graph().m_blocks[m_block].get();
2252     }
2253
2254 #ifndef NDEBUG
2255     void dump(const char* label = 0);
2256 #endif
2257
2258 #if DFG_ENABLE(CONSISTENCY_CHECK)
2259     void checkConsistency();
2260 #else
2261     void checkConsistency() { }
2262 #endif
2263
2264     bool isInteger(NodeIndex nodeIndex)
2265     {
2266         Node& node = at(nodeIndex);
2267         if (node.hasInt32Result())
2268             return true;
2269
2270         if (isInt32Constant(nodeIndex))
2271             return true;
2272
2273         VirtualRegister virtualRegister = node.virtualRegister();
2274         GenerationInfo& info = m_generationInfo[virtualRegister];
2275         
2276         return info.isJSInteger();
2277     }
2278     
2279     bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
2280     bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
2281     void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
2282     void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition);
2283     void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex);
2284     void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, NodeIndex branchNodeIndex);
2285     void compileObjectEquality(Node&);
2286     void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
2287     void compileValueAdd(Node&);
2288     void compileNonStringCellOrOtherLogicalNot(Edge value, bool needSpeculationCheck);
2289     void compileLogicalNot(Node&);
2290     void emitNonStringCellOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck);
2291     void emitBranch(Node&);
2292     
2293     void compileIntegerCompare(Node&, MacroAssembler::RelationalCondition);
2294     void compileDoubleCompare(Node&, MacroAssembler::DoubleCondition);
2295     
2296     bool compileStrictEqForConstant(Node&, Edge value, JSValue constant);
2297     
2298     bool compileStrictEq(Node&);
2299     
2300     void compileAllocatePropertyStorage(Node&);
2301     void compileReallocatePropertyStorage(Node&);
2302     
2303 #if USE(JSVALUE32_64)
2304     template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
2305     void compileContiguousPutByVal(Node&, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
2306 #endif
2307     void compileDoublePutByVal(Node&, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
2308     bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
2309     {
2310         return arrayMode.mayStoreToHole();
2311     }
2312     GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
2313     GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node& node)
2314     {
2315         return temporaryRegisterForPutByVal(temporary, node.arrayMode());
2316     }
2317     
2318     void compileGetCharCodeAt(Node&);
2319     void compileGetByValOnString(Node&);
2320
2321     void compileGetByValOnArguments(Node&);
2322     void compileGetArgumentsLength(Node&);
2323     
2324     void compileGetArrayLength(Node&);
2325     
2326     void compileValueToInt32(Node&);
2327     void compileUInt32ToNumber(Node&);
2328     void compileDoubleAsInt32(Node&);
2329     void compileInt32ToDouble(Node&);
2330     void compileAdd(Node&);
2331     void compileArithSub(Node&);
2332     void compileArithNegate(Node&);
2333     void compileArithMul(Node&);
2334 #if CPU(X86) || CPU(X86_64)
2335     void compileIntegerArithDivForX86(Node&);
2336 #endif
2337     void compileArithMod(Node&);
2338     void compileSoftModulo(Node&);
2339     void compileGetIndexedPropertyStorage(Node&);
2340     void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySignedness);
2341     void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
2342     void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize);
2343     void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize);
2344     void compileNewFunctionNoCheck(Node&);
2345     void compileNewFunctionExpression(Node&);
2346     bool compileRegExpExec(Node&);
2347     
2348     // size can be an immediate or a register, and must be in bytes. If size is a register,
2349     // it must be a different register than resultGPR. Emits code that place a pointer to
2350     // the end of the allocation. The returned jump is the jump to the slow path.
2351     template<typename SizeType>
2352     MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
2353     {
2354         CopiedAllocator* copiedAllocator = &m_jit.globalData()->heap.storageAllocator();
2355         
2356         m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
2357         MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
2358 #if 0
2359         MacroAssembler::Jump done = m_jit.jump();
2360         slowPath1.link(&m_jit);
2361         m_jit.breakpoint();
2362         MacroAssembler::Jump slowPath = m_jit.jump();
2363         done.link(&m_jit);
2364 #endif
2365         m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
2366         m_jit.negPtr(resultGPR);
2367         m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
2368         
2369         return slowPath;
2370     }
2371     
2372     // It is NOT okay for the structure and the scratch register to be the same thing because if they are then the Structure will 
2373     // get clobbered. 
2374     template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType, typename StorageType> 
2375     void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, StorageType storage, size_t size, MacroAssembler::JumpList& slowPath)
2376     {
2377         MarkedAllocator* allocator = 0;
2378         if (destructorType == MarkedBlock::Normal)
2379             allocator = &m_jit.globalData()->heap.allocatorForObjectWithNormalDestructor(size);
2380         else if (destructorType == MarkedBlock::ImmortalStructure)
2381             allocator = &m_jit.globalData()->heap.allocatorForObjectWithImmortalStructureDestructor(size);
2382         else
2383             allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(size);
2384
2385         m_jit.loadPtr(&allocator->m_freeList.head, resultGPR);
2386         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2387         
2388         // The object is half-allocated: we have what we know is a fresh object, but
2389         // it's still on the GC's free list.
2390         m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
2391         m_jit.storePtr(scratchGPR, &allocator->m_freeList.head);
2392
2393         // Initialize the object's Structure.
2394         m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSCell::structureOffset()));
2395         
2396         // Initialize the object's property storage pointer.
2397         m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
2398     }
2399
2400     template<typename T>
2401     void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2402     {
2403         return emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None>(structure, resultGPR, scratchGPR, TrustedImmPtr(0), JSFinalObject::allocationSize(INLINE_STORAGE_CAPACITY), slowPath);
2404     }
2405     
2406     void emitAllocateJSArray(Structure*, GPRReg resultGPR, GPRReg storageGPR, unsigned numElements);
2407
2408 #if USE(JSVALUE64) 
2409     JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp);
2410 #elif USE(JSVALUE32_64)
2411     JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result);
2412 #endif
2413
2414     // Add a speculation check without additional recovery.
2415     void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail);
2416     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
2417     // Add a set of speculation checks without additional recovery.
2418     void speculationCheck(ExitKind, JSValueSource, NodeIndex, const MacroAssembler::JumpList& jumpsToFail);
2419     void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
2420     // Add a speculation check with additional recovery.
2421     void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2422     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2423     // Use this like you would use speculationCheck(), except that you don't pass it a jump
2424     // (because you don't have to execute a branch; that's kind of the whole point), and you
2425     // must register the returned Watchpoint with something relevant. In general, this should
2426     // be used with extreme care. Use speculationCheck() unless you've got an amazing reason
2427     // not to.
2428     JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, NodeIndex);
2429     // The default for speculation watchpoints is that they're uncounted, because the
2430     // act of firing a watchpoint invalidates it. So, future recompilations will not
2431     // attempt to set this watchpoint again.
2432     JumpReplacementWatchpoint* speculationWatchpoint(ExitKind = UncountableWatchpoint);
2433     
2434     // It is generally a good idea to not use this directly.
2435     void convertLastOSRExitToForward(const ValueRecovery& = ValueRecovery());
2436     
2437     // Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies
2438     // that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck().
2439     void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
2440     void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
2441     void speculationCheckWithConditionalDirection(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, bool isForward);
2442     // Called when we statically determine that a speculation will fail.
2443     void terminateSpeculativeExecution(ExitKind, JSValueRegs, NodeIndex);
2444     void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2445     void terminateSpeculativeExecutionWithConditionalDirection(ExitKind, JSValueRegs, NodeIndex, bool isForward);
2446     // Issue a forward speculation watchpoint, which will exit to the next instruction rather
2447     // than the current one.
2448     JumpReplacementWatchpoint* forwardSpeculationWatchpoint(ExitKind = UncountableWatchpoint);
2449     JumpReplacementWatchpoint* speculationWatchpointWithConditionalDirection(ExitKind, bool isForward);
2450     
2451     const TypedArrayDescriptor* typedArrayDescriptor(ArrayMode);
2452     
2453     JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType, bool invert);
2454     JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, bool invert = false);
2455     void checkArray(Node&);
2456     void arrayify(Node&, GPRReg baseReg, GPRReg propertyReg);
2457     void arrayify(Node&);
2458     
2459     template<bool strict>
2460     GPRReg fillSpeculateIntInternal(NodeIndex, DataFormat& returnFormat);
2461     
2462     // It is possible, during speculative generation, to reach a situation in which we
2463     // can statically determine a speculation will fail (for example, when two nodes
2464     // will make conflicting speculations about the same operand). In such cases this
2465     // flag is cleared, indicating no further code generation should take place.
2466     bool m_compileOkay;
2467     
2468     // Tracking for which nodes are currently holding the values of arguments and bytecode
2469     // operand-indexed variables.
2470     
2471     ValueSource valueSourceForOperand(int operand)
2472     {
2473         return valueSourceReferenceForOperand(operand);
2474     }
2475     
2476     void setNodeIndexForOperand(NodeIndex nodeIndex, int operand)
2477     {
2478         valueSourceReferenceForOperand(operand) = ValueSource(nodeIndex);
2479     }
2480     
2481     // Call this with care, since it both returns a reference into an array
2482     // and potentially resizes the array. So it would not be right to call this
2483     // twice and then perform operands on both references, since the one from
2484     // the first call may no longer be valid.
2485     ValueSource& valueSourceReferenceForOperand(int operand)
2486     {
2487         if (operandIsArgument(operand)) {
2488             int argument = operandToArgument(operand);
2489             return m_arguments[argument];
2490         }
2491         
2492         if ((unsigned)operand >= m_variables.size())
2493             m_variables.resize(operand + 1);
2494         
2495         return m_variables[operand];
2496     }
2497     
2498     void recordSetLocal(int operand, ValueSource valueSource)
2499     {
2500         valueSourceReferenceForOperand(operand) = valueSource;
2501         m_stream->appendAndLog(VariableEvent::setLocal(operand, valueSource.dataFormat()));
2502     }
2503     
2504     // The JIT, while also provides MacroAssembler functionality.
2505     JITCompiler& m_jit;
2506
2507     // The current node being generated.
2508     BlockIndex m_block;
2509     NodeIndex m_compileIndex;
2510     unsigned m_indexInBlock;
2511     // Virtual and physical register maps.
2512     Vector<GenerationInfo, 32> m_generationInfo;
2513     RegisterBank<GPRInfo> m_gprs;
2514     RegisterBank<FPRInfo> m_fprs;
2515
2516     Vector<MacroAssembler::Label> m_blockHeads;
2517     Vector<MacroAssembler::Label> m_osrEntryHeads;
2518     
2519     struct BranchRecord {
2520         BranchRecord(MacroAssembler::Jump jump, BlockIndex destination)
2521             : jump(jump)
2522             , destination(destination)
2523         {
2524         }
2525
2526         MacroAssembler::Jump jump;
2527         BlockIndex destination;
2528     };
2529     Vector<BranchRecord, 8> m_branches;
2530
2531     Vector<ValueSource, 0> m_arguments;
2532     Vector<ValueSource, 0> m_variables;
2533     int m_lastSetOperand;
2534     CodeOrigin m_codeOriginForOSR;
2535     
2536     AbstractState m_state;
2537     
2538     VariableEventStream* m_stream;
2539     MinifiedGraph* m_minifiedGraph;
2540     
2541     bool m_isCheckingArgumentTypes;
2542     
2543     Vector<SlowPathGenerator*, 8> m_slowPathGenerators; // doesn't use OwnPtr<> because I don't want to include DFGSlowPathGenerator.h
2544     Vector<SilentRegisterSavePlan> m_plans;
2545     
2546     ValueRecovery computeValueRecoveryFor(const ValueSource&);
2547
2548     ValueRecovery computeValueRecoveryFor(int operand)
2549     {
2550         return computeValueRecoveryFor(valueSourceForOperand(operand));
2551     }
2552 };
2553
2554
2555 // === Operand types ===
2556 //
2557 // IntegerOperand, DoubleOperand and JSValueOperand.
2558 //
2559 // These classes are used to lock the operands to a node into machine
2560 // registers. These classes implement of pattern of locking a value
2561 // into register at the point of construction only if it is already in
2562 // registers, and otherwise loading it lazily at the point it is first
2563 // used. We do so in order to attempt to avoid spilling one operand
2564 // in order to make space available for another.
2565
2566 class IntegerOperand {
2567 public:
2568     explicit IntegerOperand(SpeculativeJIT* jit, Edge use)
2569         : m_jit(jit)
2570         , m_index(use.index())
2571         , m_gprOrInvalid(InvalidGPRReg)
2572 #ifndef NDEBUG
2573         , m_format(DataFormatNone)
2574 #endif
2575     {
2576         ASSERT(m_jit);
2577         ASSERT(use.useKind() != DoubleUse);
2578         if (jit->isFilled(m_index))
2579             gpr();
2580     }
2581
2582     ~IntegerOperand()
2583     {
2584         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2585         m_jit->unlock(m_gprOrInvalid);
2586     }
2587
2588     NodeIndex index() const
2589     {
2590         return m_index;
2591     }
2592
2593     DataFormat format()
2594     {
2595         gpr(); // m_format is set when m_gpr is locked.
2596         ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
2597         return m_format;
2598     }
2599
2600     GPRReg gpr()
2601     {
2602         if (m_gprOrInvalid == InvalidGPRReg)
2603             m_gprOrInvalid = m_jit->fillInteger(index(), m_format);
2604         return m_gprOrInvalid;
2605     }
2606     
2607     void use()
2608     {
2609         m_jit->use(m_index);
2610     }
2611
2612 private:
2613     SpeculativeJIT* m_jit;
2614     NodeIndex m_index;
2615     GPRReg m_gprOrInvalid;
2616     DataFormat m_format;
2617 };
2618
2619 class DoubleOperand {
2620 public:
2621     explicit DoubleOperand(SpeculativeJIT* jit, Edge use)
2622         : m_jit(jit)
2623         , m_index(use.index())
2624         , m_fprOrInvalid(InvalidFPRReg)
2625     {
2626         ASSERT(m_jit);
2627         
2628         // This is counter-intuitive but correct. DoubleOperand is intended to
2629         // be used only when you're a node that is happy to accept an untyped
2630         // value, but will special-case for doubles (using DoubleOperand) if the
2631         // value happened to already be represented as a double. The implication
2632         // is that you will not try to force the value to become a double if it
2633         // is not one already.
2634         ASSERT(use.useKind() != DoubleUse);
2635         
2636         if (jit->isFilledDouble(m_index))
2637             fpr();
2638     }
2639
2640     ~DoubleOperand()
2641     {
2642         ASSERT(m_fprOrInvalid != InvalidFPRReg);
2643         m_jit->unlock(m_fprOrInvalid);
2644     }
2645
2646     NodeIndex index() const
2647     {
2648         return m_index;
2649     }
2650
2651     FPRReg fpr()
2652     {
2653         if (m_fprOrInvalid == InvalidFPRReg)
2654             m_fprOrInvalid = m_jit->fillDouble(index());
2655         return m_fprOrInvalid;
2656     }
2657     
2658     void use()
2659     {
2660         m_jit->use(m_index);
2661     }
2662
2663 private:
2664     SpeculativeJIT* m_jit;
2665     NodeIndex m_index;
2666     FPRReg m_fprOrInvalid;
2667 };
2668
2669 class JSValueOperand {
2670 public:
2671     explicit JSValueOperand(SpeculativeJIT* jit, Edge use)
2672         : m_jit(jit)
2673         , m_index(use.index())
2674 #if USE(JSVALUE64)
2675         , m_gprOrInvalid(InvalidGPRReg)
2676 #elif USE(JSVALUE32_64)
2677         , m_isDouble(false)
2678 #endif
2679     {
2680         ASSERT(m_jit);
2681         ASSERT(use.useKind() != DoubleUse);
2682 #if USE(JSVALUE64)
2683         if (jit->isFilled(m_index))
2684             gpr();
2685 #elif USE(JSVALUE32_64)
2686         m_register.pair.tagGPR = InvalidGPRReg;
2687         m_register.pair.payloadGPR = InvalidGPRReg;
2688         if (jit->isFilled(m_index))
2689             fill();
2690 #endif
2691     }
2692
2693     ~JSValueOperand()
2694     {
2695 #if USE(JSVALUE64)
2696         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2697         m_jit->unlock(m_gprOrInvalid);
2698 #elif USE(JSVALUE32_64)
2699         if (m_isDouble) {
2700             ASSERT(m_register.fpr != InvalidFPRReg);
2701             m_jit->unlock(m_register.fpr);
2702         } else {
2703             ASSERT(m_register.pair.tagGPR != InvalidGPRReg && m_register.pair.payloadGPR != InvalidGPRReg);
2704             m_jit->unlock(m_register.pair.tagGPR);
2705             m_jit->unlock(m_register.pair.payloadGPR);
2706         }
2707 #endif
2708     }
2709
2710     NodeIndex index() const
2711     {
2712         return m_index;
2713     }
2714
2715 #if USE(JSVALUE64)
2716     GPRReg gpr()
2717     {
2718         if (m_gprOrInvalid == InvalidGPRReg)
2719             m_gprOrInvalid = m_jit->fillJSValue(index());
2720         return m_gprOrInvalid;
2721     }
2722     JSValueRegs jsValueRegs()
2723     {
2724         return JSValueRegs(gpr());
2725     }
2726 #elif USE(JSVALUE32_64)
2727     bool isDouble() { return m_isDouble; }
2728
2729     void fill()
2730     {
2731         if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
2732             m_isDouble = !m_jit->fillJSValue(index(), m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
2733     }
2734
2735     GPRReg tagGPR()
2736     {
2737         fill();
2738         ASSERT(!m_isDouble);
2739         return m_register.pair.tagGPR;
2740     }
2741
2742     GPRReg payloadGPR()
2743     {
2744         fill();
2745         ASSERT(!m_isDouble);
2746         return m_register.pair.payloadGPR;
2747     }
2748
2749     JSValueRegs jsValueRegs()
2750     {
2751         return JSValueRegs(tagGPR(), payloadGPR());
2752     }
2753
2754     FPRReg fpr()
2755     {
2756         fill();
2757         ASSERT(m_isDouble);
2758         return m_register.fpr;
2759     }
2760 #endif
2761
2762     void use()
2763     {
2764         m_jit->use(m_index);
2765     }
2766
2767 private:
2768     SpeculativeJIT* m_jit;
2769     NodeIndex m_index;
2770 #if USE(JSVALUE64)
2771     GPRReg m_gprOrInvalid;
2772 #elif USE(JSVALUE32_64)
2773     union {
2774         struct {
2775             GPRReg tagGPR;
2776             GPRReg payloadGPR;
2777         } pair;
2778         FPRReg fpr;
2779     } m_register;
2780     bool m_isDouble;
2781 #endif
2782 };
2783
2784 class StorageOperand {
2785 public:
2786     explicit StorageOperand(SpeculativeJIT* jit, Edge use)
2787         : m_jit(jit)
2788         , m_index(use.index())
2789         , m_gprOrInvalid(InvalidGPRReg)
2790     {
2791         ASSERT(m_jit);
2792         ASSERT(use.useKind() != DoubleUse);
2793         if (jit->isFilled(m_index))
2794             gpr();
2795     }
2796     
2797     ~StorageOperand()
2798     {
2799         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2800         m_jit->unlock(m_gprOrInvalid);
2801     }
2802     
2803     NodeIndex index() const
2804     {
2805         return m_index;
2806     }
2807     
2808     GPRReg gpr()
2809     {
2810         if (m_gprOrInvalid == InvalidGPRReg)
2811             m_gprOrInvalid = m_jit->fillStorage(index());
2812         return m_gprOrInvalid;
2813     }
2814     
2815     void use()
2816     {
2817         m_jit->use(m_index);
2818     }
2819     
2820 private:
2821     SpeculativeJIT* m_jit;
2822     NodeIndex m_index;
2823     GPRReg m_gprOrInvalid;
2824 };
2825
2826
2827 // === Temporaries ===
2828 //
2829 // These classes are used to allocate temporary registers.
2830 // A mechanism is provided to attempt to reuse the registers
2831 // currently allocated to child nodes whose value is consumed
2832 // by, and not live after, this operation.
2833
2834 class GPRTemporary {
2835 public:
2836     GPRTemporary();
2837     GPRTemporary(SpeculativeJIT*);
2838     GPRTemporary(SpeculativeJIT*, GPRReg specific);
2839     GPRTemporary(SpeculativeJIT*, SpeculateIntegerOperand&);
2840     GPRTemporary(SpeculativeJIT*, SpeculateIntegerOperand&, SpeculateIntegerOperand&);
2841     GPRTemporary(SpeculativeJIT*, SpeculateStrictInt32Operand&);
2842     GPRTemporary(SpeculativeJIT*, IntegerOperand&);
2843     GPRTemporary(SpeculativeJIT*, IntegerOperand&, IntegerOperand&);
2844     GPRTemporary(SpeculativeJIT*, SpeculateCellOperand&);
2845     GPRTemporary(SpeculativeJIT*, SpeculateBooleanOperand&);
2846 #if USE(JSVALUE64)
2847     GPRTemporary(SpeculativeJIT*, JSValueOperand&);
2848 #elif USE(JSVALUE32_64)
2849     GPRTemporary(SpeculativeJIT*, JSValueOperand&, bool tag = true);
2850 #endif
2851     GPRTemporary(SpeculativeJIT*, StorageOperand&);
2852
2853     void adopt(GPRTemporary&);
2854
2855     ~GPRTemporary()
2856     {
2857         if (m_jit && m_gpr != InvalidGPRReg)
2858             m_jit->unlock(gpr());
2859     }
2860
2861     GPRReg gpr()
2862     {
2863         return m_gpr;
2864     }
2865
2866 private:
2867     SpeculativeJIT* m_jit;
2868     GPRReg m_gpr;
2869 };
2870
2871 class FPRTemporary {
2872 public:
2873     FPRTemporary(SpeculativeJIT*);
2874     FPRTemporary(SpeculativeJIT*, DoubleOperand&);
2875     FPRTemporary(SpeculativeJIT*, DoubleOperand&, DoubleOperand&);
2876     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2877     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2878 #if USE(JSVALUE32_64)
2879     FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2880 #endif
2881
2882     ~FPRTemporary()
2883     {
2884         m_jit->unlock(fpr());
2885     }
2886
2887     FPRReg fpr() const
2888     {
2889         ASSERT(m_fpr != InvalidFPRReg);
2890         return m_fpr;
2891     }
2892
2893 protected:
2894     FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2895         : m_jit(jit)
2896         , m_fpr(lockedFPR)
2897     {
2898     }
2899
2900 private:
2901     SpeculativeJIT* m_jit;
2902     FPRReg m_fpr;
2903 };
2904
2905
2906 // === Results ===
2907 //
2908 // These classes lock the result of a call to a C++ helper function.
2909
2910 class GPRResult : public GPRTemporary {
2911 public:
2912     GPRResult(SpeculativeJIT* jit)
2913         : GPRTemporary(jit, GPRInfo::returnValueGPR)
2914     {
2915     }
2916 };
2917
2918 #if USE(JSVALUE32_64)
2919 class GPRResult2 : public GPRTemporary {
2920 public:
2921     GPRResult2(SpeculativeJIT* jit)
2922         : GPRTemporary(jit, GPRInfo::returnValueGPR2)
2923     {
2924     }
2925 };
2926 #endif
2927
2928 class FPRResult : public FPRTemporary {
2929 public:
2930     FPRResult(SpeculativeJIT* jit)
2931         : FPRTemporary(jit, lockedResult(jit))
2932     {
2933     }
2934
2935 private:
2936     static FPRReg lockedResult(SpeculativeJIT* jit)
2937     {
2938         jit->lock(FPRInfo::returnValueFPR);
2939         return FPRInfo::returnValueFPR;
2940     }
2941 };
2942
2943
2944 // === Speculative Operand types ===
2945 //
2946 // SpeculateIntegerOperand, SpeculateStrictInt32Operand and SpeculateCellOperand.
2947 //
2948 // These are used to lock the operands to a node into machine registers within the
2949 // SpeculativeJIT. The classes operate like those above, however these will
2950 // perform a speculative check for a more restrictive type than we can statically
2951 // determine the operand to have. If the operand does not have the requested type,
2952 // a bail-out to the non-speculative path will be taken.
2953
2954 class SpeculateIntegerOperand {
2955 public:
2956     explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge use)
2957         : m_jit(jit)
2958         , m_index(use.index())
2959         , m_gprOrInvalid(InvalidGPRReg)
2960 #ifndef NDEBUG
2961         , m_format(DataFormatNone)
2962 #endif
2963     {
2964         ASSERT(m_jit);
2965         ASSERT(use.useKind() != DoubleUse);
2966         if (jit->isFilled(m_index))
2967             gpr();
2968     }
2969
2970     ~SpeculateIntegerOperand()
2971     {
2972         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2973         m_jit->unlock(m_gprOrInvalid);
2974     }
2975
2976     NodeIndex index() const
2977     {
2978         return m_index;
2979     }
2980
2981     DataFormat format()
2982     {
2983         gpr(); // m_format is set when m_gpr is locked.
2984         ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
2985         return m_format;
2986     }
2987
2988     GPRReg gpr()
2989     {
2990         if (m_gprOrInvalid == InvalidGPRReg)
2991             m_gprOrInvalid = m_jit->fillSpeculateInt(index(), m_format);
2992         return m_gprOrInvalid;
2993     }
2994     
2995     void use()
2996     {
2997         m_jit->use(m_index);
2998     }
2999
3000 private:
3001     SpeculativeJIT* m_jit;
3002     NodeIndex m_index;
3003     GPRReg m_gprOrInvalid;
3004     DataFormat m_format;
3005 };
3006
3007 class SpeculateStrictInt32Operand {
3008 public:
3009     explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge use)
3010         : m_jit(jit)
3011         , m_index(use.index())
3012         , m_gprOrInvalid(InvalidGPRReg)
3013     {
3014         ASSERT(m_jit);
3015         ASSERT(use.useKind() != DoubleUse);
3016         if (jit->isFilled(m_index))
3017             gpr();
3018     }
3019
3020     ~SpeculateStrictInt32Operand()
3021     {
3022         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3023         m_jit->unlock(m_gprOrInvalid);
3024     }
3025
3026     NodeIndex index() const
3027     {
3028         return m_index;
3029     }
3030
3031     GPRReg gpr()
3032     {
3033         if (m_gprOrInvalid == InvalidGPRReg)
3034             m_gprOrInvalid = m_jit->fillSpeculateIntStrict(index());
3035         return m_gprOrInvalid;
3036     }
3037     
3038     void use()
3039     {
3040         m_jit->use(m_index);
3041     }
3042
3043 private:
3044     SpeculativeJIT* m_jit;
3045     NodeIndex m_index;
3046     GPRReg m_gprOrInvalid;
3047 };
3048
3049 class SpeculateDoubleOperand {
3050 public:
3051     explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge use)
3052         : m_jit(jit)
3053         , m_index(use.index())
3054         , m_fprOrInvalid(InvalidFPRReg)
3055     {
3056         ASSERT(m_jit);
3057         ASSERT(use.useKind() == DoubleUse);
3058         if (jit->isFilled(m_index))
3059             fpr();
3060     }
3061
3062     ~SpeculateDoubleOperand()
3063     {
3064         ASSERT(m_fprOrInvalid != InvalidFPRReg);
3065         m_jit->unlock(m_fprOrInvalid);
3066     }
3067
3068     NodeIndex index() const
3069     {
3070         return m_index;
3071     }
3072
3073     FPRReg fpr()
3074     {
3075         if (m_fprOrInvalid == InvalidFPRReg)
3076             m_fprOrInvalid = m_jit->fillSpeculateDouble(index());
3077         return m_fprOrInvalid;
3078     }
3079     
3080     void use()
3081     {
3082         m_jit->use(m_index);
3083     }
3084
3085 private:
3086     SpeculativeJIT* m_jit;
3087     NodeIndex m_index;
3088     FPRReg m_fprOrInvalid;
3089 };
3090
3091 class SpeculateCellOperand {
3092 public:
3093     explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge use, bool isForwardSpeculation = false)
3094         : m_jit(jit)
3095         , m_index(use.index())
3096         , m_gprOrInvalid(InvalidGPRReg)
3097         , m_isForwardSpeculation(isForwardSpeculation)
3098     {
3099         ASSERT(m_jit);
3100         ASSERT(use.useKind() != DoubleUse);
3101         if (jit->isFilled(m_index))
3102             gpr();
3103     }
3104
3105     ~SpeculateCellOperand()
3106     {
3107         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3108         m_jit->unlock(m_gprOrInvalid);
3109     }
3110
3111     NodeIndex index() const
3112     {
3113         return m_index;
3114     }
3115
3116     GPRReg gpr()
3117     {
3118         if (m_gprOrInvalid == InvalidGPRReg)
3119             m_gprOrInvalid = m_jit->fillSpeculateCell(index(), m_isForwardSpeculation);
3120         return m_gprOrInvalid;
3121     }
3122     
3123     void use()
3124     {
3125         m_jit->use(m_index);
3126     }
3127
3128 private:
3129     SpeculativeJIT* m_jit;
3130     NodeIndex m_index;
3131     GPRReg m_gprOrInvalid;
3132     bool m_isForwardSpeculation;
3133 };
3134
3135 class SpeculateBooleanOperand {
3136 public:
3137     explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge use)
3138         : m_jit(jit)
3139         , m_index(use.index())
3140         , m_gprOrInvalid(InvalidGPRReg)
3141     {
3142         ASSERT(m_jit);
3143         ASSERT(use.useKind() != DoubleUse);
3144         if (jit->isFilled(m_index))
3145             gpr();
3146     }
3147     
3148     ~SpeculateBooleanOperand()
3149     {
3150         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3151         m_jit->unlock(m_gprOrInvalid);
3152     }
3153     
3154     NodeIndex index() const
3155     {
3156         return m_index;
3157     }
3158     
3159     GPRReg gpr()
3160     {
3161         if (m_gprOrInvalid == InvalidGPRReg)
3162             m_gprOrInvalid = m_jit->fillSpeculateBoolean(index());
3163         return m_gprOrInvalid;
3164     }
3165     
3166     void use()
3167     {
3168         m_jit->use(m_index);
3169     }
3170
3171 private:
3172     SpeculativeJIT* m_jit;
3173     NodeIndex m_index;
3174     GPRReg m_gprOrInvalid;
3175 };
3176
3177 } } // namespace JSC::DFG
3178
3179 #endif
3180 #endif
3181