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