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