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