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