ca75826569f1f3e168bcfe51488c09701b67067e
[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
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(P_DFGOperation_ESt operation, GPRReg result, Structure* structure)
925     {
926         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
927         return appendCallWithExceptionCheckSetResult(operation, result);
928     }
929     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
930     {
931         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
932         return appendCallWithExceptionCheckSetResult(operation, result);
933     }
934     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
935     {
936         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
937         return appendCallWithExceptionCheckSetResult(operation, result);
938     }
939     JITCompiler::Call callOperation(P_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
940     {
941         m_jit.setupArgumentsWithExecState(arg1, arg2);
942         return appendCallWithExceptionCheckSetResult(operation, result);
943     }
944     JITCompiler::Call callOperation(P_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
945     {
946         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
947         return appendCallWithExceptionCheckSetResult(operation, result);
948     }
949     JITCompiler::Call callOperation(P_DFGOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
950     {
951         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
952         return appendCallWithExceptionCheckSetResult(operation, result);
953     }
954
955     JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
956     {
957         m_jit.setupArgumentsExecState();
958         return appendCallWithExceptionCheckSetResult(operation, result);
959     }
960     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
961     {
962         m_jit.setupArgumentsWithExecState(arg1);
963         return appendCallWithExceptionCheckSetResult(operation, result);
964     }
965     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
966     {
967         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
968         return appendCallWithExceptionCheckSetResult(operation, result);
969     }
970     JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
971     {
972         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
973         return appendCallWithExceptionCheckSetResult(operation, result);
974     }
975     JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
976     {
977         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
978         return appendCallWithExceptionCheckSetResult(operation, result);
979     }
980     JITCompiler::Call callOperation(C_DFGOperation_ESt operation, GPRReg result, Structure* structure)
981     {
982         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
983         return appendCallWithExceptionCheckSetResult(operation, result);
984     }
985     JITCompiler::Call callOperation(C_DFGOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
986     {
987         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
988         return appendCallWithExceptionCheckSetResult(operation, result);
989     }
990     JITCompiler::Call callOperation(C_DFGOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
991     {
992         m_jit.setupArgumentsWithExecState(arg1, arg2);
993         return appendCallWithExceptionCheckSetResult(operation, result);
994     }
995     JITCompiler::Call callOperation(C_DFGOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
996     {
997         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
998         return appendCallWithExceptionCheckSetResult(operation, result);
999     }
1000
1001     JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1002     {
1003         m_jit.setupArgumentsWithExecState(arg1, arg2);
1004         return appendCallWithExceptionCheckSetResult(operation, result);
1005     }
1006
1007     JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
1008     {
1009         m_jit.setupArgumentsWithExecState(arg1);
1010         return appendCallWithExceptionCheck(operation);
1011     }
1012
1013     JITCompiler::Call callOperation(V_DFGOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
1014     {
1015         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1016         return appendCallWithExceptionCheck(operation);
1017     }
1018     JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
1019     {
1020         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1021         return appendCallWithExceptionCheck(operation);
1022     }
1023
1024     JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
1025     {
1026         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1027         return appendCallWithExceptionCheck(operation);
1028     }
1029
1030     JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1031     {
1032         m_jit.setupArgumentsWithExecState(arg1, arg2);
1033         return appendCallWithExceptionCheck(operation);
1034     }
1035
1036     JITCompiler::Call callOperation(V_DFGOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1037     {
1038         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1039         return appendCallWithExceptionCheck(operation);
1040     }
1041
1042     JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
1043     {
1044         m_jit.setupArguments(TrustedImmPtr(watchpointSet));
1045         return appendCall(operation);
1046     }
1047
1048     template<typename FunctionType, typename ArgumentType1>
1049     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1050     {
1051         return callOperation(operation, arg1);
1052     }
1053     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1054     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1055     {
1056         return callOperation(operation, arg1, arg2);
1057     }
1058     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1059     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1060     {
1061         return callOperation(operation, arg1, arg2, arg3);
1062     }
1063     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4>
1064     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4)
1065     {
1066         return callOperation(operation, arg1, arg2, arg3, arg4);
1067     }
1068     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1069     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1070     {
1071         return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
1072     }
1073
1074     JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1075     {
1076         m_jit.setupArguments(arg1, arg2);
1077         return appendCallSetResult(operation, result);
1078     }
1079     JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1080     {
1081         m_jit.setupArguments(arg1, arg2);
1082         return appendCallSetResult(operation, result);
1083     }
1084     JITCompiler::Call callOperation(Str_DFGOperation_EJss operation, GPRReg result, GPRReg arg1)
1085     {
1086         m_jit.setupArgumentsWithExecState(arg1);
1087         return appendCallWithExceptionCheckSetResult(operation, result);
1088     }
1089     JITCompiler::Call callOperation(C_DFGOperation_EZ operation, GPRReg result, GPRReg arg1)
1090     {
1091         m_jit.setupArgumentsWithExecState(arg1);
1092         return appendCallWithExceptionCheckSetResult(operation, result);
1093     }
1094
1095 #if USE(JSVALUE64)
1096     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result)
1097     {
1098         m_jit.setupArgumentsExecState();
1099         return appendCallWithExceptionCheckSetResult(operation, result);
1100     }
1101     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, void* pointer)
1102     {
1103         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1104         return appendCallWithExceptionCheckSetResult(operation, result);
1105     }
1106     JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
1107     {
1108         m_jit.setupArguments(arg1);
1109         JITCompiler::Call call = m_jit.appendCall(operation);
1110         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1111         return call;
1112     }
1113     JITCompiler::Call callOperation(Z_DFGOperation_ZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1114     {
1115         m_jit.setupArguments(arg1, arg2);
1116         JITCompiler::Call call = m_jit.appendCall(operation);
1117         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1118         return call;
1119     }
1120     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1121     {
1122         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1123         return appendCallWithExceptionCheckSetResult(operation, result);
1124     }
1125     JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg result, Identifier* identifier)
1126     {
1127         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
1128         return appendCallWithExceptionCheckSetResult(operation, result);
1129     }
1130     JITCompiler::Call callOperation(J_DFGOperation_EIRo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations)
1131     {
1132         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations));
1133         return appendCallWithExceptionCheckSetResult(operation, result);
1134     }
1135     JITCompiler::Call callOperation(J_DFGOperation_EIRoPtbo operation, GPRReg result, Identifier* identifier, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1136     {
1137         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations), TrustedImmPtr(putToBaseOperations));
1138         return appendCallWithExceptionCheckSetResult(operation, result);
1139     }
1140     JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg result, GPRReg arg1)
1141     {
1142         m_jit.setupArgumentsWithExecState(arg1);
1143         return appendCallWithExceptionCheckSetResult(operation, result);
1144     }
1145     JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1146     {
1147         m_jit.setupArgumentsWithExecState(arg1, arg2);
1148         return appendCallWithExceptionCheckSetResult(operation, result);
1149     }
1150     JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg result, void* pointer, size_t size)
1151     {
1152         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1153         return appendCallWithExceptionCheckSetResult(operation, result);
1154     }
1155     JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
1156     {
1157         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1158         return appendCallWithExceptionCheckSetResult(operation, result);
1159     }
1160     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
1161     {
1162         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1163         return appendCallWithExceptionCheckSetResult(operation, result);
1164     }
1165     JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
1166     {
1167         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1168         return appendCallWithExceptionCheckSetResult(operation, result);
1169     }
1170     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
1171     {
1172         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1173         return appendCallWithExceptionCheckSetResult(operation, result);
1174     }
1175     JITCompiler::Call callOperation(J_DFGOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
1176     {
1177         m_jit.setupArgumentsWithExecState(arg1, arg2);
1178         return appendCallWithExceptionCheckSetResult(operation, result);
1179     }
1180     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1181     {
1182         m_jit.setupArgumentsWithExecState(arg1, arg2);
1183         return appendCallWithExceptionCheckSetResult(operation, result);
1184     }
1185     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, GPRReg arg1)
1186     {
1187         m_jit.setupArgumentsWithExecState(arg1);
1188         return appendCallWithExceptionCheckSetResult(operation, result);
1189     }
1190     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, GPRReg arg1)
1191     {
1192         m_jit.setupArgumentsWithExecState(arg1);
1193         return appendCallWithExceptionCheckSetResult(operation, result);
1194     }
1195     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, int32_t arg1)
1196     {
1197         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1198         return appendCallWithExceptionCheckSetResult(operation, result);
1199     }
1200     JITCompiler::Call callOperation(J_DFGOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
1201     {
1202         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1203         return appendCallWithExceptionCheckSetResult(operation, result);
1204     }
1205     JITCompiler::Call callOperation(J_DFGOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1206     {
1207         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1208         return appendCallWithExceptionCheckSetResult(operation, result);
1209     }
1210
1211
1212     JITCompiler::Call callOperation(C_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
1213     {
1214         m_jit.setupArgumentsWithExecState(arg1);
1215         return appendCallWithExceptionCheckSetResult(operation, result);
1216     }
1217     JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1)
1218     {
1219         m_jit.setupArguments(arg1);
1220         return appendCallSetResult(operation, result);
1221     }
1222     JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
1223     {
1224         m_jit.setupArgumentsWithExecState(arg1);
1225         return appendCallWithExceptionCheckSetResult(operation, result);
1226     }
1227     JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
1228     {
1229         m_jit.setupArgumentsWithExecState(arg1);
1230         return appendCallWithExceptionCheckSetResult(operation, result);
1231     }
1232     JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1233     {
1234         m_jit.setupArgumentsWithExecState(arg1, arg2);
1235         return appendCallWithExceptionCheckSetResult(operation, result);
1236     }
1237
1238     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1239     {
1240         m_jit.setupArgumentsWithExecState(arg1, arg2);
1241         return appendCallWithExceptionCheckSetResult(operation, result);
1242     }
1243     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1244     {
1245         m_jit.setupArgumentsWithExecState(arg1, arg2);
1246         return appendCallWithExceptionCheckSetResult(operation, result);
1247     }
1248     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
1249     {
1250         m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
1251         return appendCallWithExceptionCheckSetResult(operation, result);
1252     }
1253     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
1254     {
1255         m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
1256         return appendCallWithExceptionCheckSetResult(operation, result);
1257     }
1258     JITCompiler::Call callOperation(J_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1259     {
1260         m_jit.setupArgumentsWithExecState(arg1, arg2);
1261         return appendCallWithExceptionCheckSetResult(operation, result);
1262     }
1263     JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1264     {
1265         m_jit.setupArgumentsWithExecState(arg1, arg2);
1266         return appendCallWithExceptionCheckSetResult(operation, result);
1267     }
1268
1269     JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
1270     {
1271         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1272         return appendCallWithExceptionCheck(operation);
1273     }
1274     JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1275     {
1276         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1277         return appendCallWithExceptionCheck(operation);
1278     }
1279     JITCompiler::Call callOperation(V_DFGOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1280     {
1281         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1282         return appendCallWithExceptionCheck(operation);
1283     }
1284     JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1285     {
1286         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1287         return appendCallWithExceptionCheck(operation);
1288     }
1289
1290     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1291     {
1292         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1293         return appendCallWithExceptionCheck(operation);
1294     }
1295     JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1296     {
1297         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1298         return appendCallWithExceptionCheck(operation);
1299     }
1300
1301     JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1)
1302     {
1303         m_jit.setupArgumentsWithExecState(arg1);
1304         return appendCallWithExceptionCheckSetResult(operation, result);
1305     }
1306
1307 #else // USE(JSVALUE32_64)
1308
1309 // 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]).
1310 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1311 #if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
1312 #define EABI_32BIT_DUMMY_ARG      TrustedImm32(0),
1313 #else
1314 #define EABI_32BIT_DUMMY_ARG
1315 #endif
1316
1317     JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
1318     {
1319         prepareForExternalCall();
1320         m_jit.setupArguments(arg1);
1321         JITCompiler::Call call = m_jit.appendCall(operation);
1322         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1323         return call;
1324     }
1325     JITCompiler::Call callOperation(Z_DFGOperation_ZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1326     {
1327         m_jit.setupArguments(arg1, arg2);
1328         JITCompiler::Call call = m_jit.appendCall(operation);
1329         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1330         return call;
1331     }
1332     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
1333     {
1334         m_jit.setupArgumentsExecState();
1335         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1336     }
1337     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
1338     {
1339         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1340         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1341     }
1342     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
1343     {
1344         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1345         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1346     }
1347     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1348     {
1349         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1350         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1351     }
1352     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1353     {
1354         m_jit.setupArgumentsWithExecState(arg1);
1355         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1356     }
1357     JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier)
1358     {
1359         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
1360         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1361     }
1362     JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1363     {
1364         m_jit.setupArgumentsWithExecState(arg1);
1365         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1366     }
1367     JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1368     {
1369         m_jit.setupArgumentsWithExecState(arg1, arg2);
1370         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1371     }
1372     JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
1373     {
1374         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1375         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1376     }
1377     JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
1378     {
1379         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1380         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1381     }
1382     JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
1383     {
1384         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
1385         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1386     }
1387     JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1388     {
1389         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1390         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1391     }
1392
1393     JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, Identifier* identifier)
1394     {
1395         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1396         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1397     }
1398     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, Identifier* identifier)
1399     {
1400         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(identifier));
1401         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1402     }
1403     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1Tag, GPRReg arg1Payload, Identifier* identifier)
1404     {
1405         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(identifier));
1406         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1407     }
1408     JITCompiler::Call callOperation(J_DFGOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2)
1409     {
1410         m_jit.setupArgumentsWithExecState(arg1, arg2);
1411         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1412     }
1413     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1414     {
1415         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1416         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1417     }
1418     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1419     {
1420         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1421         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1422     }
1423     JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
1424     {
1425         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1426         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1427     }
1428     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1429     {
1430         m_jit.setupArgumentsWithExecState(arg1);
1431         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1432     }
1433     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
1434     {
1435         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1436         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1437     }
1438     JITCompiler::Call callOperation(J_DFGOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1439     {
1440         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1441         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1442     }
1443     JITCompiler::Call callOperation(J_DFGOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
1444     {
1445         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1446         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1447     }
1448
1449
1450     JITCompiler::Call callOperation(C_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1451     {
1452         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1453         return appendCallWithExceptionCheckSetResult(operation, result);
1454     }
1455     JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1456     {
1457         m_jit.setupArguments(arg1Payload, arg1Tag);
1458         return appendCallSetResult(operation, result);
1459     }
1460     JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1461     {
1462         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1463         return appendCallWithExceptionCheckSetResult(operation, result);
1464     }
1465
1466     JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1467     {
1468         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1469         return appendCallWithExceptionCheckSetResult(operation, result);
1470     }
1471     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1472     {
1473         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1474         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1475     }
1476     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
1477     {
1478         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag));
1479         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1480     }
1481     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
1482     {
1483         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag);
1484         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1485     }
1486
1487     JITCompiler::Call callOperation(J_DFGOperation_EIRo operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier, ResolveOperations* operations)
1488     {
1489         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations));
1490         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1491     }
1492
1493     JITCompiler::Call callOperation(J_DFGOperation_EIRoPtbo operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier, ResolveOperations* operations, PutToBaseOperation* putToBaseOperations)
1494     {
1495         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier), TrustedImmPtr(operations), TrustedImmPtr(putToBaseOperations));
1496         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1497     }
1498
1499     JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
1500     {
1501         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
1502         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1503     }
1504     JITCompiler::Call callOperation(J_DFGOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1505     {
1506         m_jit.setupArgumentsWithExecState(arg1, arg2);
1507         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1508     }
1509
1510     JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
1511     {
1512         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
1513         return appendCallWithExceptionCheck(operation);
1514     }
1515     JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, Identifier* identifier)
1516     {
1517         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(identifier));
1518         return appendCallWithExceptionCheck(operation);
1519     }
1520     JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1521     {
1522         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1523         return appendCallWithExceptionCheck(operation);
1524     }
1525
1526     JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1527     {
1528         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1529         return appendCallWithExceptionCheck(operation);
1530     }
1531
1532     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1533     {
1534         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1535         return appendCallWithExceptionCheck(operation);
1536     }
1537     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
1538     {
1539         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1540         return appendCallWithExceptionCheck(operation);
1541     }
1542
1543     JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1544     {
1545         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1546         return appendCallWithExceptionCheckSetResult(operation, result);
1547     }
1548
1549 #undef EABI_32BIT_DUMMY_ARG
1550     
1551     template<typename FunctionType>
1552     JITCompiler::Call callOperation(
1553         FunctionType operation, JSValueRegs result)
1554     {
1555         return callOperation(operation, result.tagGPR(), result.payloadGPR());
1556     }
1557     template<typename FunctionType, typename ArgumentType1>
1558     JITCompiler::Call callOperation(
1559         FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
1560     {
1561         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
1562     }
1563     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1564     JITCompiler::Call callOperation(
1565         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1566     {
1567         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1568     }
1569     template<
1570         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1571         typename ArgumentType3>
1572     JITCompiler::Call callOperation(
1573         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1574         ArgumentType3 arg3)
1575     {
1576         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1577     }
1578     template<
1579         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1580         typename ArgumentType3, typename ArgumentType4>
1581     JITCompiler::Call callOperation(
1582         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1583         ArgumentType3 arg3, ArgumentType4 arg4)
1584     {
1585         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1586     }
1587     template<
1588         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1589         typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1590     JITCompiler::Call callOperation(
1591         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1592         ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1593     {
1594         return callOperation(
1595             operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1596     }
1597 #endif // USE(JSVALUE32_64)
1598     
1599 #if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS)
1600     void prepareForExternalCall()
1601     {
1602         // We're about to call out to a "native" helper function. The helper
1603         // function is expected to set topCallFrame itself with the ExecState
1604         // that is passed to it.
1605         //
1606         // We explicitly trash topCallFrame here so that we'll know if some of
1607         // the helper functions are not setting topCallFrame when they should
1608         // be doing so. Note: the previous value in topcallFrame was not valid
1609         // anyway since it was not being updated by JIT'ed code by design.
1610
1611         for (unsigned i = 0; i < sizeof(void*) / 4; i++)
1612             m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.vm()->topCallFrame) + i * 4);
1613     }
1614 #else
1615     void prepareForExternalCall() { }
1616 #endif
1617
1618     // These methods add call instructions, with optional exception checks & setting results.
1619     JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
1620     {
1621         prepareForExternalCall();
1622         CodeOrigin codeOrigin = m_currentNode->codeOrigin;
1623         CallBeginToken token;
1624         m_jit.beginCall(codeOrigin, token);
1625         JITCompiler::Call call = m_jit.appendCall(function);
1626         m_jit.addExceptionCheck(call, codeOrigin, token);
1627         return call;
1628     }
1629     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
1630     {
1631         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1632         m_jit.move(GPRInfo::returnValueGPR, result);
1633         return call;
1634     }
1635     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1636     {
1637         prepareForExternalCall();
1638         JITCompiler::Call call = m_jit.appendCall(function);
1639         m_jit.move(GPRInfo::returnValueGPR, result);
1640         return call;
1641     }
1642     JITCompiler::Call appendCall(const FunctionPtr& function)
1643     {
1644         prepareForExternalCall();
1645         return m_jit.appendCall(function);
1646     }
1647     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
1648     {
1649         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1650         m_jit.setupResults(result1, result2);
1651         return call;
1652     }
1653 #if CPU(X86)
1654     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1655     {
1656         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1657         m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1658         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1659         return call;
1660     }
1661     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1662     {
1663         JITCompiler::Call call = m_jit.appendCall(function);
1664         m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1665         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1666         return call;
1667     }
1668 #elif CPU(ARM)
1669 #if CPU(ARM_HARDFP)
1670     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1671     {
1672         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1673         m_jit.moveDouble(result, FPRInfo::argumentFPR0);
1674         return call;
1675     }
1676     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1677     {
1678         JITCompiler::Call call = m_jit.appendCall(function);
1679         m_jit.moveDouble(result, FPRInfo::argumentFPR0);
1680         return call;
1681     }
1682 #else
1683         JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1684     {
1685         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1686         m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1687         return call;
1688     }
1689     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1690     {
1691         JITCompiler::Call call = m_jit.appendCall(function);
1692         m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1693         return call;
1694     }
1695 #endif // CPU(ARM_HARDFP)
1696 #else
1697     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1698     {
1699         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1700         m_jit.moveDouble(FPRInfo::returnValueFPR, result);
1701         return call;
1702     }
1703     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1704     {
1705         JITCompiler::Call call = m_jit.appendCall(function);
1706         m_jit.moveDouble(FPRInfo::returnValueFPR, result);
1707         return call;
1708     }
1709 #endif
1710     
1711     void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BlockIndex destination)
1712     {
1713         if (!haveEdgeCodeToEmit(destination))
1714             return addBranch(m_jit.branchDouble(cond, left, right), destination);
1715         
1716         JITCompiler::Jump notTaken = m_jit.branchDouble(JITCompiler::invert(cond), left, right);
1717         emitEdgeCode(destination);
1718         addBranch(m_jit.jump(), destination);
1719         notTaken.link(&m_jit);
1720     }
1721     
1722     void branchDoubleNonZero(FPRReg value, FPRReg scratch, BlockIndex destination)
1723     {
1724         if (!haveEdgeCodeToEmit(destination))
1725             return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
1726         
1727         JITCompiler::Jump notTaken = m_jit.branchDoubleZeroOrNaN(value, scratch);
1728         emitEdgeCode(destination);
1729         addBranch(m_jit.jump(), destination);
1730         notTaken.link(&m_jit);
1731     }
1732     
1733     template<typename T, typename U>
1734     void branch32(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
1735     {
1736         if (!haveEdgeCodeToEmit(destination))
1737             return addBranch(m_jit.branch32(cond, left, right), destination);
1738         
1739         JITCompiler::Jump notTaken = m_jit.branch32(JITCompiler::invert(cond), left, right);
1740         emitEdgeCode(destination);
1741         addBranch(m_jit.jump(), destination);
1742         notTaken.link(&m_jit);
1743     }
1744     
1745     template<typename T, typename U>
1746     void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
1747     {
1748         ASSERT(JITCompiler::isInvertible(cond));
1749         
1750         if (!haveEdgeCodeToEmit(destination))
1751             return addBranch(m_jit.branchTest32(cond, value, mask), destination);
1752         
1753         JITCompiler::Jump notTaken = m_jit.branchTest32(JITCompiler::invert(cond), value, mask);
1754         emitEdgeCode(destination);
1755         addBranch(m_jit.jump(), destination);
1756         notTaken.link(&m_jit);
1757     }
1758     
1759     template<typename T>
1760     void branchTest32(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
1761     {
1762         ASSERT(JITCompiler::isInvertible(cond));
1763         
1764         if (!haveEdgeCodeToEmit(destination))
1765             return addBranch(m_jit.branchTest32(cond, value), destination);
1766         
1767         JITCompiler::Jump notTaken = m_jit.branchTest32(JITCompiler::invert(cond), value);
1768         emitEdgeCode(destination);
1769         addBranch(m_jit.jump(), destination);
1770         notTaken.link(&m_jit);
1771     }
1772     
1773 #if USE(JSVALUE64)
1774     template<typename T, typename U>
1775     void branch64(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
1776     {
1777         if (!haveEdgeCodeToEmit(destination))
1778             return addBranch(m_jit.branch64(cond, left, right), destination);
1779         
1780         JITCompiler::Jump notTaken = m_jit.branch64(JITCompiler::invert(cond), left, right);
1781         emitEdgeCode(destination);
1782         addBranch(m_jit.jump(), destination);
1783         notTaken.link(&m_jit);
1784     }
1785 #endif
1786     
1787     template<typename T, typename U>
1788     void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
1789     {
1790         if (!haveEdgeCodeToEmit(destination))
1791             return addBranch(m_jit.branchPtr(cond, left, right), destination);
1792         
1793         JITCompiler::Jump notTaken = m_jit.branchPtr(JITCompiler::invert(cond), left, right);
1794         emitEdgeCode(destination);
1795         addBranch(m_jit.jump(), destination);
1796         notTaken.link(&m_jit);
1797     }
1798     
1799     template<typename T, typename U>
1800     void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
1801     {
1802         ASSERT(JITCompiler::isInvertible(cond));
1803         
1804         if (!haveEdgeCodeToEmit(destination))
1805             return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
1806         
1807         JITCompiler::Jump notTaken = m_jit.branchTestPtr(JITCompiler::invert(cond), value, mask);
1808         emitEdgeCode(destination);
1809         addBranch(m_jit.jump(), destination);
1810         notTaken.link(&m_jit);
1811     }
1812     
1813     template<typename T>
1814     void branchTestPtr(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
1815     {
1816         ASSERT(JITCompiler::isInvertible(cond));
1817         
1818         if (!haveEdgeCodeToEmit(destination))
1819             return addBranch(m_jit.branchTestPtr(cond, value), destination);
1820         
1821         JITCompiler::Jump notTaken = m_jit.branchTestPtr(JITCompiler::invert(cond), value);
1822         emitEdgeCode(destination);
1823         addBranch(m_jit.jump(), destination);
1824         notTaken.link(&m_jit);
1825     }
1826     
1827     template<typename T, typename U>
1828     void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
1829     {
1830         ASSERT(JITCompiler::isInvertible(cond));
1831         
1832         if (!haveEdgeCodeToEmit(destination))
1833             return addBranch(m_jit.branchTest8(cond, value, mask), destination);
1834         
1835         JITCompiler::Jump notTaken = m_jit.branchTest8(JITCompiler::invert(cond), value, mask);
1836         emitEdgeCode(destination);
1837         addBranch(m_jit.jump(), destination);
1838         notTaken.link(&m_jit);
1839     }
1840     
1841     template<typename T>
1842     void branchTest8(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
1843     {
1844         ASSERT(JITCompiler::isInvertible(cond));
1845         
1846         if (!haveEdgeCodeToEmit(destination))
1847             return addBranch(m_jit.branchTest8(cond, value), destination);
1848         
1849         JITCompiler::Jump notTaken = m_jit.branchTest8(JITCompiler::invert(cond), value);
1850         emitEdgeCode(destination);
1851         addBranch(m_jit.jump(), destination);
1852         notTaken.link(&m_jit);
1853     }
1854     
1855     enum FallThroughMode {
1856         AtFallThroughPoint,
1857         ForceJump
1858     };
1859     void jump(BlockIndex destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
1860     {
1861         if (haveEdgeCodeToEmit(destination))
1862             emitEdgeCode(destination);
1863         if (destination == nextBlock()
1864             && fallThroughMode == AtFallThroughPoint)
1865             return;
1866         addBranch(m_jit.jump(), destination);
1867     }
1868     
1869     inline bool haveEdgeCodeToEmit(BlockIndex)
1870     {
1871         return DFG_ENABLE_EDGE_CODE_VERIFICATION;
1872     }
1873     void emitEdgeCode(BlockIndex destination)
1874     {
1875         if (!DFG_ENABLE_EDGE_CODE_VERIFICATION)
1876             return;
1877         m_jit.move(TrustedImm32(destination), GPRInfo::regT0);
1878     }
1879
1880     void addBranch(const MacroAssembler::Jump& jump, BlockIndex destination)
1881     {
1882         m_branches.append(BranchRecord(jump, destination));
1883     }
1884
1885     void linkBranches()
1886     {
1887         for (size_t i = 0; i < m_branches.size(); ++i) {
1888             BranchRecord& branch = m_branches[i];
1889             branch.jump.linkTo(m_blockHeads[branch.destination], &m_jit);
1890         }
1891     }
1892
1893     BasicBlock* block()
1894     {
1895         return m_jit.graph().m_blocks[m_block].get();
1896     }
1897
1898 #ifndef NDEBUG
1899     void dump(const char* label = 0);
1900 #endif
1901
1902 #if DFG_ENABLE(CONSISTENCY_CHECK)
1903     void checkConsistency();
1904 #else
1905     void checkConsistency() { }
1906 #endif
1907
1908     bool isInteger(Node* node)
1909     {
1910         if (node->hasInt32Result())
1911             return true;
1912
1913         if (isInt32Constant(node))
1914             return true;
1915
1916         VirtualRegister virtualRegister = node->virtualRegister();
1917         GenerationInfo& info = m_generationInfo[virtualRegister];
1918         
1919         return info.isJSInteger();
1920     }
1921     
1922     bool compare(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
1923     bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
1924     void compilePeepHoleIntegerBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
1925     void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
1926     void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
1927     void compilePeepHoleObjectEquality(Node*, Node* branchNode);
1928     void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
1929     void compileObjectEquality(Node*);
1930     void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
1931     void compileValueAdd(Node*);
1932     void compileObjectOrOtherLogicalNot(Edge value);
1933     void compileLogicalNot(Node*);
1934     void compileStringEquality(Node*);
1935     void emitObjectOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken);
1936     void emitBranch(Node*);
1937     
1938     void compileToStringOnCell(Node*);
1939     void compileNewStringObject(Node*);
1940     
1941     void compileIntegerCompare(Node*, MacroAssembler::RelationalCondition);
1942     void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
1943     void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
1944     
1945     bool compileStrictEqForConstant(Node*, Edge value, JSValue constant);
1946     
1947     bool compileStrictEq(Node*);
1948     
1949     void compileAllocatePropertyStorage(Node*);
1950     void compileReallocatePropertyStorage(Node*);
1951     
1952 #if USE(JSVALUE32_64)
1953     template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
1954     void compileContiguousPutByVal(Node*, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
1955 #endif
1956     void compileDoublePutByVal(Node*, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
1957     bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
1958     {
1959         return arrayMode.mayStoreToHole();
1960     }
1961     GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
1962     GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node* node)
1963     {
1964         return temporaryRegisterForPutByVal(temporary, node->arrayMode());
1965     }
1966     
1967     void compileGetCharCodeAt(Node*);
1968     void compileGetByValOnString(Node*);
1969     void compileFromCharCode(Node*); 
1970
1971     void compileGetByValOnArguments(Node*);
1972     void compileGetArgumentsLength(Node*);
1973     
1974     void compileGetArrayLength(Node*);
1975     
1976     void compileValueToInt32(Node*);
1977     void compileUInt32ToNumber(Node*);
1978     void compileDoubleAsInt32(Node*);
1979     void compileInt32ToDouble(Node*);
1980     void compileAdd(Node*);
1981     void compileMakeRope(Node*);
1982     void compileArithSub(Node*);
1983     void compileArithNegate(Node*);
1984     void compileArithMul(Node*);
1985     void compileArithIMul(Node*);
1986 #if CPU(X86) || CPU(X86_64)
1987     void compileIntegerArithDivForX86(Node*);
1988 #elif ENABLE(ARM_INTEGER_DIV)
1989     void compileIntegerArithDivForARM(Node*);
1990 #endif
1991     void compileArithMod(Node*);
1992     void compileSoftModulo(Node*);
1993     void compileGetIndexedPropertyStorage(Node*);
1994     void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node*, size_t elementSize, TypedArraySignedness);
1995     void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node*, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
1996     void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node*, size_t elementSize);
1997     void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node*, size_t elementSize);
1998     void compileNewFunctionNoCheck(Node*);
1999     void compileNewFunctionExpression(Node*);
2000     bool compileRegExpExec(Node*);
2001     
2002     // size can be an immediate or a register, and must be in bytes. If size is a register,
2003     // it must be a different register than resultGPR. Emits code that place a pointer to
2004     // the end of the allocation. The returned jump is the jump to the slow path.
2005     template<typename SizeType>
2006     MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
2007     {
2008         CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
2009         
2010         m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
2011         MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
2012         m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
2013         m_jit.negPtr(resultGPR);
2014         m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
2015         
2016         return slowPath;
2017     }
2018     
2019     // Allocator for a cell of a specific size.
2020     template <typename StructureType> // StructureType can be GPR or ImmPtr.
2021     void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2022         GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2023     {
2024         m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
2025         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2026         
2027         // The object is half-allocated: we have what we know is a fresh object, but
2028         // it's still on the GC's free list.
2029         m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
2030         m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()));
2031
2032         // Initialize the object's Structure.
2033         m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSCell::structureOffset()));
2034     }
2035
2036     // Allocator for an object of a specific size.
2037     template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2038     void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2039         StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2040     {
2041         emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath);
2042         
2043         // Initialize the object's property storage pointer.
2044         m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
2045     }
2046
2047     // Convenience allocator for a buit-in object.
2048     template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2049     void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
2050         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2051     {
2052         MarkedAllocator* allocator = 0;
2053         size_t size = ClassType::allocationSize(0);
2054         if (ClassType::needsDestruction && ClassType::hasImmortalStructure)
2055             allocator = &m_jit.vm()->heap.allocatorForObjectWithImmortalStructureDestructor(size);
2056         else if (ClassType::needsDestruction)
2057             allocator = &m_jit.vm()->heap.allocatorForObjectWithNormalDestructor(size);
2058         else
2059             allocator = &m_jit.vm()->heap.allocatorForObjectWithoutDestructor(size);
2060         m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
2061         emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
2062     }
2063
2064     void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
2065
2066 #if USE(JSVALUE64) 
2067     JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp);
2068 #elif USE(JSVALUE32_64)
2069     JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result);
2070 #endif
2071     
2072     // Add a backward speculation check.
2073     void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
2074     void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
2075
2076     // Add a speculation check without additional recovery.
2077     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
2078     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
2079     // Add a speculation check without additional recovery, and with a promise to supply a jump later.
2080     OSRExitJumpPlaceholder backwardSpeculationCheck(ExitKind, JSValueSource, Node*);
2081     OSRExitJumpPlaceholder backwardSpeculationCheck(ExitKind, JSValueSource, Edge);
2082     // Add a set of speculation checks without additional recovery.
2083     void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
2084     void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
2085     // Add a speculation check with additional recovery.
2086     void backwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2087     void backwardSpeculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2088     // Use this like you would use speculationCheck(), except that you don't pass it a jump
2089     // (because you don't have to execute a branch; that's kind of the whole point), and you
2090     // must register the returned Watchpoint with something relevant. In general, this should
2091     // be used with extreme care. Use speculationCheck() unless you've got an amazing reason
2092     // not to.
2093     JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, Node*);
2094     // The default for speculation watchpoints is that they're uncounted, because the
2095     // act of firing a watchpoint invalidates it. So, future recompilations will not
2096     // attempt to set this watchpoint again.
2097     JumpReplacementWatchpoint* speculationWatchpoint(ExitKind = UncountableWatchpoint);
2098     
2099     // It is generally a good idea to not use this directly.
2100     void convertLastOSRExitToForward(const ValueRecovery& = ValueRecovery());
2101     
2102     // Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies
2103     // that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck().
2104     void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
2105     void forwardSpeculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
2106     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2107     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2108     // Called when we statically determine that a speculation will fail.
2109     void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
2110     void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2111     
2112     // Helpers for performing type checks on an edge stored in the given registers.
2113     bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_state.forNode(edge).m_type & ~typesPassedThrough; }
2114     void backwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
2115     void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
2116     void forwardTypeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, const ValueRecovery&);
2117
2118     void speculateInt32(Edge);
2119     void speculateNumber(Edge);
2120     void speculateRealNumber(Edge);
2121     void speculateBoolean(Edge);
2122     void speculateCell(Edge);
2123     void speculateObject(Edge);
2124     void speculateObjectOrOther(Edge);
2125     void speculateString(Edge);
2126     template<typename StructureLocationType>
2127     void speculateStringObjectForStructure(Edge, StructureLocationType);
2128     void speculateStringObject(Edge, GPRReg);
2129     void speculateStringObject(Edge);
2130     void speculateStringOrStringObject(Edge);
2131     void speculateNotCell(Edge);
2132     void speculateOther(Edge);
2133     void speculate(Node*, Edge);
2134     
2135     const TypedArrayDescriptor* typedArrayDescriptor(ArrayMode);
2136     
2137     JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType);
2138     JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode);
2139     void checkArray(Node*);
2140     void arrayify(Node*, GPRReg baseReg, GPRReg propertyReg);
2141     void arrayify(Node*);
2142     
2143     template<bool strict>
2144     GPRReg fillSpeculateIntInternal(Edge, DataFormat& returnFormat);
2145     
2146     // It is possible, during speculative generation, to reach a situation in which we
2147     // can statically determine a speculation will fail (for example, when two nodes
2148     // will make conflicting speculations about the same operand). In such cases this
2149     // flag is cleared, indicating no further code generation should take place.
2150     bool m_compileOkay;
2151     
2152     // Tracking for which nodes are currently holding the values of arguments and bytecode
2153     // operand-indexed variables.
2154     
2155     ValueSource valueSourceForOperand(int operand)
2156     {
2157         return valueSourceReferenceForOperand(operand);
2158     }
2159     
2160     void setNodeForOperand(Node* node, int operand)
2161     {
2162         valueSourceReferenceForOperand(operand) = ValueSource(MinifiedID(node));
2163     }
2164     
2165     // Call this with care, since it both returns a reference into an array
2166     // and potentially resizes the array. So it would not be right to call this
2167     // twice and then perform operands on both references, since the one from
2168     // the first call may no longer be valid.
2169     ValueSource& valueSourceReferenceForOperand(int operand)
2170     {
2171         if (operandIsArgument(operand)) {
2172             int argument = operandToArgument(operand);
2173             return m_arguments[argument];
2174         }
2175         
2176         if ((unsigned)operand >= m_variables.size())
2177             m_variables.resize(operand + 1);
2178         
2179         return m_variables[operand];
2180     }
2181     
2182     void recordSetLocal(int operand, ValueSource valueSource)
2183     {
2184         valueSourceReferenceForOperand(operand) = valueSource;
2185         m_stream->appendAndLog(VariableEvent::setLocal(operand, valueSource.dataFormat()));
2186     }
2187     
2188     // The JIT, while also provides MacroAssembler functionality.
2189     JITCompiler& m_jit;
2190
2191     // The current node being generated.
2192     BlockIndex m_block;
2193     Node* m_currentNode;
2194     SpeculationDirection m_speculationDirection;
2195 #if !ASSERT_DISABLED
2196     bool m_canExit;
2197 #endif
2198     unsigned m_indexInBlock;
2199     // Virtual and physical register maps.
2200     Vector<GenerationInfo, 32> m_generationInfo;
2201     RegisterBank<GPRInfo> m_gprs;
2202     RegisterBank<FPRInfo> m_fprs;
2203
2204     Vector<MacroAssembler::Label> m_blockHeads;
2205     Vector<MacroAssembler::Label> m_osrEntryHeads;
2206     
2207     struct BranchRecord {
2208         BranchRecord(MacroAssembler::Jump jump, BlockIndex destination)
2209             : jump(jump)
2210             , destination(destination)
2211         {
2212         }
2213
2214         MacroAssembler::Jump jump;
2215         BlockIndex destination;
2216     };
2217     Vector<BranchRecord, 8> m_branches;
2218
2219     Vector<ValueSource, 0> m_arguments;
2220     Vector<ValueSource, 0> m_variables;
2221     int m_lastSetOperand;
2222     CodeOrigin m_codeOriginForOSR;
2223     
2224     AbstractState m_state;
2225     
2226     VariableEventStream* m_stream;
2227     MinifiedGraph* m_minifiedGraph;
2228     
2229     bool m_isCheckingArgumentTypes;
2230     
2231     Vector<OwnPtr<SlowPathGenerator>, 8> m_slowPathGenerators;
2232     Vector<SilentRegisterSavePlan> m_plans;
2233     
2234     ValueRecovery computeValueRecoveryFor(const ValueSource&);
2235
2236     ValueRecovery computeValueRecoveryFor(int operand)
2237     {
2238         return computeValueRecoveryFor(valueSourceForOperand(operand));
2239     }
2240 };
2241
2242
2243 // === Operand types ===
2244 //
2245 // IntegerOperand and JSValueOperand.
2246 //
2247 // These classes are used to lock the operands to a node into machine
2248 // registers. These classes implement of pattern of locking a value
2249 // into register at the point of construction only if it is already in
2250 // registers, and otherwise loading it lazily at the point it is first
2251 // used. We do so in order to attempt to avoid spilling one operand
2252 // in order to make space available for another.
2253
2254 class IntegerOperand {
2255 public:
2256     explicit IntegerOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2257         : m_jit(jit)
2258         , m_edge(edge)
2259         , m_gprOrInvalid(InvalidGPRReg)
2260 #ifndef NDEBUG
2261         , m_format(DataFormatNone)
2262 #endif
2263     {
2264         ASSERT(m_jit);
2265         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == KnownInt32Use);
2266         if (jit->isFilled(edge.node()))
2267             gpr();
2268     }
2269
2270     ~IntegerOperand()
2271     {
2272         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2273         m_jit->unlock(m_gprOrInvalid);
2274     }
2275
2276     Edge edge() const
2277     {
2278         return m_edge;
2279     }
2280     
2281     Node* node() const
2282     {
2283         return edge().node();
2284     }
2285
2286     DataFormat format()
2287     {
2288         gpr(); // m_format is set when m_gpr is locked.
2289         ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
2290         return m_format;
2291     }
2292
2293     GPRReg gpr()
2294     {
2295         if (m_gprOrInvalid == InvalidGPRReg)
2296             m_gprOrInvalid = m_jit->fillInteger(m_edge, m_format);
2297         return m_gprOrInvalid;
2298     }
2299     
2300     void use()
2301     {
2302         m_jit->use(node());
2303     }
2304
2305 private:
2306     SpeculativeJIT* m_jit;
2307     Edge m_edge;
2308     GPRReg m_gprOrInvalid;
2309     DataFormat m_format;
2310 };
2311
2312 class JSValueOperand {
2313 public:
2314     explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2315         : m_jit(jit)
2316         , m_edge(edge)
2317 #if USE(JSVALUE64)
2318         , m_gprOrInvalid(InvalidGPRReg)
2319 #elif USE(JSVALUE32_64)
2320         , m_isDouble(false)
2321 #endif
2322     {
2323         ASSERT(m_jit);
2324         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
2325 #if USE(JSVALUE64)
2326         if (jit->isFilled(node()))
2327             gpr();
2328 #elif USE(JSVALUE32_64)
2329         m_register.pair.tagGPR = InvalidGPRReg;
2330         m_register.pair.payloadGPR = InvalidGPRReg;
2331         if (jit->isFilled(node()))
2332             fill();
2333 #endif
2334     }
2335
2336     ~JSValueOperand()
2337     {
2338 #if USE(JSVALUE64)
2339         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2340         m_jit->unlock(m_gprOrInvalid);
2341 #elif USE(JSVALUE32_64)
2342         if (m_isDouble) {
2343             ASSERT(m_register.fpr != InvalidFPRReg);
2344             m_jit->unlock(m_register.fpr);
2345         } else {
2346             ASSERT(m_register.pair.tagGPR != InvalidGPRReg && m_register.pair.payloadGPR != InvalidGPRReg);
2347             m_jit->unlock(m_register.pair.tagGPR);
2348             m_jit->unlock(m_register.pair.payloadGPR);
2349         }
2350 #endif
2351     }
2352     
2353     Edge edge() const
2354     {
2355         return m_edge;
2356     }
2357
2358     Node* node() const
2359     {
2360         return edge().node();
2361     }
2362
2363 #if USE(JSVALUE64)
2364     GPRReg gpr()
2365     {
2366         if (m_gprOrInvalid == InvalidGPRReg)
2367             m_gprOrInvalid = m_jit->fillJSValue(m_edge);
2368         return m_gprOrInvalid;
2369     }
2370     JSValueRegs jsValueRegs()
2371     {
2372         return JSValueRegs(gpr());
2373     }
2374 #elif USE(JSVALUE32_64)
2375     bool isDouble() { return m_isDouble; }
2376
2377     void fill()
2378     {
2379         if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
2380             m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
2381     }
2382
2383     GPRReg tagGPR()
2384     {
2385         fill();
2386         ASSERT(!m_isDouble);
2387         return m_register.pair.tagGPR;
2388     }
2389
2390     GPRReg payloadGPR()
2391     {
2392         fill();
2393         ASSERT(!m_isDouble);
2394         return m_register.pair.payloadGPR;
2395     }
2396
2397     JSValueRegs jsValueRegs()
2398     {
2399         return JSValueRegs(tagGPR(), payloadGPR());
2400     }
2401
2402     FPRReg fpr()
2403     {
2404         fill();
2405         ASSERT(m_isDouble);
2406         return m_register.fpr;
2407     }
2408 #endif
2409
2410     void use()
2411     {
2412         m_jit->use(node());
2413     }
2414
2415 private:
2416     SpeculativeJIT* m_jit;
2417     Edge m_edge;
2418 #if USE(JSVALUE64)
2419     GPRReg m_gprOrInvalid;
2420 #elif USE(JSVALUE32_64)
2421     union {
2422         struct {
2423             GPRReg tagGPR;
2424             GPRReg payloadGPR;
2425         } pair;
2426         FPRReg fpr;
2427     } m_register;
2428     bool m_isDouble;
2429 #endif
2430 };
2431
2432 class StorageOperand {
2433 public:
2434     explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
2435         : m_jit(jit)
2436         , m_edge(edge)
2437         , m_gprOrInvalid(InvalidGPRReg)
2438     {
2439         ASSERT(m_jit);
2440         ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
2441         if (jit->isFilled(node()))
2442             gpr();
2443     }
2444     
2445     ~StorageOperand()
2446     {
2447         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2448         m_jit->unlock(m_gprOrInvalid);
2449     }
2450     
2451     Edge edge() const
2452     {
2453         return m_edge;
2454     }
2455     
2456     Node* node() const
2457     {
2458         return edge().node();
2459     }
2460     
2461     GPRReg gpr()
2462     {
2463         if (m_gprOrInvalid == InvalidGPRReg)
2464             m_gprOrInvalid = m_jit->fillStorage(edge());
2465         return m_gprOrInvalid;
2466     }
2467     
2468     void use()
2469     {
2470         m_jit->use(node());
2471     }
2472     
2473 private:
2474     SpeculativeJIT* m_jit;
2475     Edge m_edge;
2476     GPRReg m_gprOrInvalid;
2477 };
2478
2479
2480 // === Temporaries ===
2481 //
2482 // These classes are used to allocate temporary registers.
2483 // A mechanism is provided to attempt to reuse the registers
2484 // currently allocated to child nodes whose value is consumed
2485 // by, and not live after, this operation.
2486
2487 class GPRTemporary {
2488 public:
2489     GPRTemporary();
2490     GPRTemporary(SpeculativeJIT*);
2491     GPRTemporary(SpeculativeJIT*, GPRReg specific);
2492     GPRTemporary(SpeculativeJIT*, SpeculateIntegerOperand&);
2493     GPRTemporary(SpeculativeJIT*, SpeculateIntegerOperand&, SpeculateIntegerOperand&);
2494     GPRTemporary(SpeculativeJIT*, SpeculateStrictInt32Operand&);
2495     GPRTemporary(SpeculativeJIT*, IntegerOperand&);
2496     GPRTemporary(SpeculativeJIT*, IntegerOperand&, IntegerOperand&);
2497     GPRTemporary(SpeculativeJIT*, SpeculateCellOperand&);
2498     GPRTemporary(SpeculativeJIT*, SpeculateBooleanOperand&);
2499 #if USE(JSVALUE64)
2500     GPRTemporary(SpeculativeJIT*, JSValueOperand&);
2501 #elif USE(JSVALUE32_64)
2502     GPRTemporary(SpeculativeJIT*, JSValueOperand&, bool tag = true);
2503 #endif
2504     GPRTemporary(SpeculativeJIT*, StorageOperand&);
2505
2506     void adopt(GPRTemporary&);
2507
2508     ~GPRTemporary()
2509     {
2510         if (m_jit && m_gpr != InvalidGPRReg)
2511             m_jit->unlock(gpr());
2512     }
2513
2514     GPRReg gpr()
2515     {
2516         return m_gpr;
2517     }
2518
2519 private:
2520     SpeculativeJIT* m_jit;
2521     GPRReg m_gpr;
2522 };
2523
2524 class FPRTemporary {
2525 public:
2526     FPRTemporary(SpeculativeJIT*);
2527     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2528     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2529 #if USE(JSVALUE32_64)
2530     FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2531 #endif
2532
2533     ~FPRTemporary()
2534     {
2535         m_jit->unlock(fpr());
2536     }
2537
2538     FPRReg fpr() const
2539     {
2540         ASSERT(m_fpr != InvalidFPRReg);
2541         return m_fpr;
2542     }
2543
2544 protected:
2545     FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2546         : m_jit(jit)
2547         , m_fpr(lockedFPR)
2548     {
2549     }
2550
2551 private:
2552     SpeculativeJIT* m_jit;
2553     FPRReg m_fpr;
2554 };
2555
2556
2557 // === Results ===
2558 //
2559 // These classes lock the result of a call to a C++ helper function.
2560
2561 class GPRResult : public GPRTemporary {
2562 public:
2563     GPRResult(SpeculativeJIT* jit)
2564         : GPRTemporary(jit, GPRInfo::returnValueGPR)
2565     {
2566     }
2567 };
2568
2569 #if USE(JSVALUE32_64)
2570 class GPRResult2 : public GPRTemporary {
2571 public:
2572     GPRResult2(SpeculativeJIT* jit)
2573         : GPRTemporary(jit, GPRInfo::returnValueGPR2)
2574     {
2575     }
2576 };
2577 #endif
2578
2579 class FPRResult : public FPRTemporary {
2580 public:
2581     FPRResult(SpeculativeJIT* jit)
2582         : FPRTemporary(jit, lockedResult(jit))
2583     {
2584     }
2585
2586 private:
2587     static FPRReg lockedResult(SpeculativeJIT* jit)
2588     {
2589         jit->lock(FPRInfo::returnValueFPR);
2590         return FPRInfo::returnValueFPR;
2591     }
2592 };
2593
2594
2595 // === Speculative Operand types ===
2596 //
2597 // SpeculateIntegerOperand, SpeculateStrictInt32Operand and SpeculateCellOperand.
2598 //
2599 // These are used to lock the operands to a node into machine registers within the
2600 // SpeculativeJIT. The classes operate like those above, however these will
2601 // perform a speculative check for a more restrictive type than we can statically
2602 // determine the operand to have. If the operand does not have the requested type,
2603 // a bail-out to the non-speculative path will be taken.
2604
2605 class SpeculateIntegerOperand {
2606 public:
2607     explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2608         : m_jit(jit)
2609         , m_edge(edge)
2610         , m_gprOrInvalid(InvalidGPRReg)
2611 #ifndef NDEBUG
2612         , m_format(DataFormatNone)
2613 #endif
2614     {
2615         ASSERT(m_jit);
2616         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2617         if (jit->isFilled(node()))
2618             gpr();
2619     }
2620
2621     ~SpeculateIntegerOperand()
2622     {
2623         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2624         m_jit->unlock(m_gprOrInvalid);
2625     }
2626     
2627     Edge edge() const
2628     {
2629         return m_edge;
2630     }
2631
2632     Node* node() const
2633     {
2634         return edge().node();
2635     }
2636
2637     DataFormat format()
2638     {
2639         gpr(); // m_format is set when m_gpr is locked.
2640         ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
2641         return m_format;
2642     }
2643
2644     GPRReg gpr()
2645     {
2646         if (m_gprOrInvalid == InvalidGPRReg)
2647             m_gprOrInvalid = m_jit->fillSpeculateInt(edge(), m_format);
2648         return m_gprOrInvalid;
2649     }
2650     
2651     void use()
2652     {
2653         m_jit->use(node());
2654     }
2655
2656 private:
2657     SpeculativeJIT* m_jit;
2658     Edge m_edge;
2659     GPRReg m_gprOrInvalid;
2660     DataFormat m_format;
2661 };
2662
2663 class SpeculateStrictInt32Operand {
2664 public:
2665     explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2666         : m_jit(jit)
2667         , m_edge(edge)
2668         , m_gprOrInvalid(InvalidGPRReg)
2669     {
2670         ASSERT(m_jit);
2671         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2672         if (jit->isFilled(node()))
2673             gpr();
2674     }
2675
2676     ~SpeculateStrictInt32Operand()
2677     {
2678         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2679         m_jit->unlock(m_gprOrInvalid);
2680     }
2681     
2682     Edge edge() const
2683     {
2684         return m_edge;
2685     }
2686
2687     Node* node() const
2688     {
2689         return edge().node();
2690     }
2691
2692     GPRReg gpr()
2693     {
2694         if (m_gprOrInvalid == InvalidGPRReg)
2695             m_gprOrInvalid = m_jit->fillSpeculateIntStrict(edge());
2696         return m_gprOrInvalid;
2697     }
2698     
2699     void use()
2700     {
2701         m_jit->use(node());
2702     }
2703
2704 private:
2705     SpeculativeJIT* m_jit;
2706     Edge m_edge;
2707     GPRReg m_gprOrInvalid;
2708 };
2709
2710 class SpeculateDoubleOperand {
2711 public:
2712     explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2713         : m_jit(jit)
2714         , m_edge(edge)
2715         , m_fprOrInvalid(InvalidFPRReg)
2716     {
2717         ASSERT(m_jit);
2718         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == NumberUse || edge.useKind() == KnownNumberUse || edge.useKind() == RealNumberUse));
2719         if (jit->isFilled(node()))
2720             fpr();
2721     }
2722
2723     ~SpeculateDoubleOperand()
2724     {
2725         ASSERT(m_fprOrInvalid != InvalidFPRReg);
2726         m_jit->unlock(m_fprOrInvalid);
2727     }
2728     
2729     Edge edge() const
2730     {
2731         return m_edge;
2732     }
2733
2734     Node* node() const
2735     {
2736         return edge().node();
2737     }
2738
2739     FPRReg fpr()
2740     {
2741         if (m_fprOrInvalid == InvalidFPRReg)
2742             m_fprOrInvalid = m_jit->fillSpeculateDouble(edge());
2743         return m_fprOrInvalid;
2744     }
2745     
2746     void use()
2747     {
2748         m_jit->use(node());
2749     }
2750
2751 private:
2752     SpeculativeJIT* m_jit;
2753     Edge m_edge;
2754     FPRReg m_fprOrInvalid;
2755 };
2756
2757 class SpeculateCellOperand {
2758 public:
2759     explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2760         : m_jit(jit)
2761         , m_edge(edge)
2762         , m_gprOrInvalid(InvalidGPRReg)
2763     {
2764         ASSERT(m_jit);
2765         if (!edge)
2766             return;
2767         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));
2768         if (jit->isFilled(node()))
2769             gpr();
2770     }
2771
2772     ~SpeculateCellOperand()
2773     {
2774         if (!m_edge)
2775             return;
2776         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2777         m_jit->unlock(m_gprOrInvalid);
2778     }
2779     
2780     Edge edge() const
2781     {
2782         return m_edge;
2783     }
2784
2785     Node* node() const
2786     {
2787         return edge().node();
2788     }
2789
2790     GPRReg gpr()
2791     {
2792         ASSERT(m_edge);
2793         if (m_gprOrInvalid == InvalidGPRReg)
2794             m_gprOrInvalid = m_jit->fillSpeculateCell(edge());
2795         return m_gprOrInvalid;
2796     }
2797     
2798     void use()
2799     {
2800         ASSERT(m_edge);
2801         m_jit->use(node());
2802     }
2803
2804 private:
2805     SpeculativeJIT* m_jit;
2806     Edge m_edge;
2807     GPRReg m_gprOrInvalid;
2808 };
2809
2810 class SpeculateBooleanOperand {
2811 public:
2812     explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2813         : m_jit(jit)
2814         , m_edge(edge)
2815         , m_gprOrInvalid(InvalidGPRReg)
2816     {
2817         ASSERT(m_jit);
2818         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse);
2819         if (jit->isFilled(node()))
2820             gpr();
2821     }
2822     
2823     ~SpeculateBooleanOperand()
2824     {
2825         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2826         m_jit->unlock(m_gprOrInvalid);
2827     }
2828     
2829     Edge edge() const
2830     {
2831         return m_edge;
2832     }
2833     
2834     Node* node() const
2835     {
2836         return edge().node();
2837     }
2838     
2839     GPRReg gpr()
2840     {
2841         if (m_gprOrInvalid == InvalidGPRReg)
2842             m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge());
2843         return m_gprOrInvalid;
2844     }
2845     
2846     void use()
2847     {
2848         m_jit->use(node());
2849     }
2850
2851 private:
2852     SpeculativeJIT* m_jit;
2853     Edge m_edge;
2854     GPRReg m_gprOrInvalid;
2855 };
2856
2857 template<typename StructureLocationType>
2858 void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
2859 {
2860     Structure* stringObjectStructure =
2861         m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure();
2862     Structure* stringPrototypeStructure = stringObjectStructure->storedPrototype().asCell()->structure();
2863     ASSERT(stringPrototypeStructure->transitionWatchpointSetIsStillValid());
2864     
2865     if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure()))) {
2866         speculationCheck(
2867             NotStringObject, JSValueRegs(), 0,
2868             m_jit.branchPtr(
2869                 JITCompiler::NotEqual, structureLocation, TrustedImmPtr(stringObjectStructure)));
2870     }
2871     stringPrototypeStructure->addTransitionWatchpoint(speculationWatchpoint(NotStringObject));
2872 }
2873
2874 #define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
2875         if (!needsTypeCheck((edge), (typesPassedThrough)))              \
2876             break;                                                      \
2877         typeCheck((source), (edge), (typesPassedThrough), (jumpToFail)); \
2878     } while (0)
2879
2880 } } // namespace JSC::DFG
2881
2882 #endif
2883 #endif
2884