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