[ES6] "super" and "this" should be lexically bound inside an arrow function and shoul...
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT.h
1 /*
2  * Copyright (C) 2011-2015 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 #if ENABLE(DFG_JIT)
30
31 #include "DFGAbstractInterpreter.h"
32 #include "DFGGenerationInfo.h"
33 #include "DFGInPlaceAbstractState.h"
34 #include "DFGJITCompiler.h"
35 #include "DFGOSRExit.h"
36 #include "DFGOSRExitJumpPlaceholder.h"
37 #include "DFGSilentRegisterSavePlan.h"
38 #include "DFGValueSource.h"
39 #include "JITOperations.h"
40 #include "MarkedAllocator.h"
41 #include "PutKind.h"
42 #include "ValueRecovery.h"
43 #include "VirtualRegister.h"
44
45 namespace JSC { namespace DFG {
46
47 class GPRTemporary;
48 class JSValueOperand;
49 class SlowPathGenerator;
50 class SpeculativeJIT;
51 class SpeculateInt32Operand;
52 class SpeculateStrictInt32Operand;
53 class SpeculateDoubleOperand;
54 class SpeculateCellOperand;
55 class SpeculateBooleanOperand;
56
57 enum GeneratedOperandType { GeneratedOperandTypeUnknown, GeneratedOperandInteger, GeneratedOperandJSValue};
58
59 inline GPRReg extractResult(GPRReg result) { return result; }
60 #if USE(JSVALUE64)
61 inline GPRReg extractResult(JSValueRegs result) { return result.gpr(); }
62 #else
63 inline JSValueRegs extractResult(JSValueRegs result) { return result; }
64 #endif
65 inline NoResultTag extractResult(NoResultTag) { return NoResult; }
66
67 // === SpeculativeJIT ===
68 //
69 // The SpeculativeJIT is used to generate a fast, but potentially
70 // incomplete code path for the dataflow. When code generating
71 // we may make assumptions about operand types, dynamically check,
72 // and bail-out to an alternate code path if these checks fail.
73 // Importantly, the speculative code path cannot be reentered once
74 // a speculative check has failed. This allows the SpeculativeJIT
75 // to propagate type information (including information that has
76 // only speculatively been asserted) through the dataflow.
77 class SpeculativeJIT {
78     WTF_MAKE_FAST_ALLOCATED;
79
80     friend struct OSRExit;
81 private:
82     typedef JITCompiler::TrustedImm32 TrustedImm32;
83     typedef JITCompiler::Imm32 Imm32;
84     typedef JITCompiler::TrustedImmPtr TrustedImmPtr;
85     typedef JITCompiler::ImmPtr ImmPtr;
86     typedef JITCompiler::TrustedImm64 TrustedImm64;
87     typedef JITCompiler::Imm64 Imm64;
88
89     // These constants are used to set priorities for spill order for
90     // the register allocator.
91 #if USE(JSVALUE64)
92     enum SpillOrder {
93         SpillOrderConstant = 1, // no spill, and cheap fill
94         SpillOrderSpilled  = 2, // no spill
95         SpillOrderJS       = 4, // needs spill
96         SpillOrderCell     = 4, // needs spill
97         SpillOrderStorage  = 4, // needs spill
98         SpillOrderInteger  = 5, // needs spill and box
99         SpillOrderBoolean  = 5, // needs spill and box
100         SpillOrderDouble   = 6, // needs spill and convert
101     };
102 #elif USE(JSVALUE32_64)
103     enum SpillOrder {
104         SpillOrderConstant = 1, // no spill, and cheap fill
105         SpillOrderSpilled  = 2, // no spill
106         SpillOrderJS       = 4, // needs spill
107         SpillOrderStorage  = 4, // needs spill
108         SpillOrderDouble   = 4, // needs spill
109         SpillOrderInteger  = 5, // needs spill and box
110         SpillOrderCell     = 5, // needs spill and box
111         SpillOrderBoolean  = 5, // needs spill and box
112     };
113 #endif
114
115     enum UseChildrenMode { CallUseChildren, UseChildrenCalledExplicitly };
116     
117 public:
118     SpeculativeJIT(JITCompiler&);
119     ~SpeculativeJIT();
120
121     bool compile();
122     
123     void createOSREntries();
124     void linkOSREntries(LinkBuffer&);
125
126     BasicBlock* nextBlock()
127     {
128         for (BlockIndex resultIndex = m_block->index + 1; ; resultIndex++) {
129             if (resultIndex >= m_jit.graph().numBlocks())
130                 return 0;
131             if (BasicBlock* result = m_jit.graph().block(resultIndex))
132                 return result;
133         }
134     }
135     
136 #if USE(JSVALUE64)
137     GPRReg fillJSValue(Edge);
138 #elif USE(JSVALUE32_64)
139     bool fillJSValue(Edge, GPRReg&, GPRReg&, FPRReg&);
140 #endif
141     GPRReg fillStorage(Edge);
142
143     // lock and unlock GPR & FPR registers.
144     void lock(GPRReg reg)
145     {
146         m_gprs.lock(reg);
147     }
148     void lock(FPRReg reg)
149     {
150         m_fprs.lock(reg);
151     }
152     void unlock(GPRReg reg)
153     {
154         m_gprs.unlock(reg);
155     }
156     void unlock(FPRReg reg)
157     {
158         m_fprs.unlock(reg);
159     }
160
161     // Used to check whether a child node is on its last use,
162     // and its machine registers may be reused.
163     bool canReuse(Node* node)
164     {
165         return generationInfo(node).useCount() == 1;
166     }
167     bool canReuse(Node* nodeA, Node* nodeB)
168     {
169         return nodeA == nodeB && generationInfo(nodeA).useCount() == 2;
170     }
171     bool canReuse(Edge nodeUse)
172     {
173         return canReuse(nodeUse.node());
174     }
175     GPRReg reuse(GPRReg reg)
176     {
177         m_gprs.lock(reg);
178         return reg;
179     }
180     FPRReg reuse(FPRReg reg)
181     {
182         m_fprs.lock(reg);
183         return reg;
184     }
185
186     // Allocate a gpr/fpr.
187     GPRReg allocate()
188     {
189 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
190         m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
191 #endif
192         VirtualRegister spillMe;
193         GPRReg gpr = m_gprs.allocate(spillMe);
194         if (spillMe.isValid()) {
195 #if USE(JSVALUE32_64)
196             GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
197             if ((info.registerFormat() & DataFormatJS))
198                 m_gprs.release(info.tagGPR() == gpr ? info.payloadGPR() : info.tagGPR());
199 #endif
200             spill(spillMe);
201         }
202         return gpr;
203     }
204     GPRReg allocate(GPRReg specific)
205     {
206 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
207         m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
208 #endif
209         VirtualRegister spillMe = m_gprs.allocateSpecific(specific);
210         if (spillMe.isValid()) {
211 #if USE(JSVALUE32_64)
212             GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
213             RELEASE_ASSERT(info.registerFormat() != DataFormatJSDouble);
214             if ((info.registerFormat() & DataFormatJS))
215                 m_gprs.release(info.tagGPR() == specific ? info.payloadGPR() : info.tagGPR());
216 #endif
217             spill(spillMe);
218         }
219         return specific;
220     }
221     GPRReg tryAllocate()
222     {
223         return m_gprs.tryAllocate();
224     }
225     FPRReg fprAllocate()
226     {
227 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
228         m_jit.addRegisterAllocationAtOffset(m_jit.debugOffset());
229 #endif
230         VirtualRegister spillMe;
231         FPRReg fpr = m_fprs.allocate(spillMe);
232         if (spillMe.isValid())
233             spill(spillMe);
234         return fpr;
235     }
236
237     // Check whether a VirtualRegsiter is currently in a machine register.
238     // We use this when filling operands to fill those that are already in
239     // machine registers first (by locking VirtualRegsiters that are already
240     // in machine register before filling those that are not we attempt to
241     // avoid spilling values we will need immediately).
242     bool isFilled(Node* node)
243     {
244         return generationInfo(node).registerFormat() != DataFormatNone;
245     }
246     bool isFilledDouble(Node* node)
247     {
248         return generationInfo(node).registerFormat() == DataFormatDouble;
249     }
250
251     // Called on an operand once it has been consumed by a parent node.
252     void use(Node* node)
253     {
254         if (!node->hasResult())
255             return;
256         GenerationInfo& info = generationInfo(node);
257
258         // use() returns true when the value becomes dead, and any
259         // associated resources may be freed.
260         if (!info.use(*m_stream))
261             return;
262
263         // Release the associated machine registers.
264         DataFormat registerFormat = info.registerFormat();
265 #if USE(JSVALUE64)
266         if (registerFormat == DataFormatDouble)
267             m_fprs.release(info.fpr());
268         else if (registerFormat != DataFormatNone)
269             m_gprs.release(info.gpr());
270 #elif USE(JSVALUE32_64)
271         if (registerFormat == DataFormatDouble)
272             m_fprs.release(info.fpr());
273         else if (registerFormat & DataFormatJS) {
274             m_gprs.release(info.tagGPR());
275             m_gprs.release(info.payloadGPR());
276         } else if (registerFormat != DataFormatNone)
277             m_gprs.release(info.gpr());
278 #endif
279     }
280     void use(Edge nodeUse)
281     {
282         use(nodeUse.node());
283     }
284     
285     RegisterSet usedRegisters();
286     
287     bool masqueradesAsUndefinedWatchpointIsStillValid(const CodeOrigin& codeOrigin)
288     {
289         return m_jit.graph().masqueradesAsUndefinedWatchpointIsStillValid(codeOrigin);
290     }
291     bool masqueradesAsUndefinedWatchpointIsStillValid()
292     {
293         return masqueradesAsUndefinedWatchpointIsStillValid(m_currentNode->origin.semantic);
294     }
295
296     void storeToWriteBarrierBuffer(GPRReg cell, GPRReg scratch1, GPRReg scratch2);
297
298     void writeBarrier(GPRReg owner, GPRReg scratch1, GPRReg scratch2);
299
300     void writeBarrier(GPRReg owner, GPRReg value, Edge valueUse, GPRReg scratch1, GPRReg scratch2);
301
302     void compileStoreBarrier(Node*);
303
304     static GPRReg selectScratchGPR(GPRReg preserve1 = InvalidGPRReg, GPRReg preserve2 = InvalidGPRReg, GPRReg preserve3 = InvalidGPRReg, GPRReg preserve4 = InvalidGPRReg)
305     {
306         return AssemblyHelpers::selectScratchGPR(preserve1, preserve2, preserve3, preserve4);
307     }
308
309     // Called by the speculative operand types, below, to fill operand to
310     // machine registers, implicitly generating speculation checks as needed.
311     GPRReg fillSpeculateInt32(Edge, DataFormat& returnFormat);
312     GPRReg fillSpeculateInt32Strict(Edge);
313     GPRReg fillSpeculateInt52(Edge, DataFormat desiredFormat);
314     FPRReg fillSpeculateDouble(Edge);
315     GPRReg fillSpeculateCell(Edge);
316     GPRReg fillSpeculateBoolean(Edge);
317     GeneratedOperandType checkGeneratedTypeForToInt32(Node*);
318
319     void addSlowPathGenerator(std::unique_ptr<SlowPathGenerator>);
320     void runSlowPathGenerators();
321     
322     void compile(Node*);
323     void noticeOSRBirth(Node*);
324     void bail(AbortReason);
325     void compileCurrentBlock();
326
327     void checkArgumentTypes();
328
329     void clearGenerationInfo();
330
331     // These methods are used when generating 'unexpected'
332     // calls out from JIT code to C++ helper routines -
333     // they spill all live values to the appropriate
334     // slots in the JSStack without changing any state
335     // in the GenerationInfo.
336     SilentRegisterSavePlan silentSavePlanForGPR(VirtualRegister spillMe, GPRReg source);
337     SilentRegisterSavePlan silentSavePlanForFPR(VirtualRegister spillMe, FPRReg source);
338     void silentSpill(const SilentRegisterSavePlan&);
339     void silentFill(const SilentRegisterSavePlan&, GPRReg canTrample);
340     
341     template<typename CollectionType>
342     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
343     {
344         ASSERT(plans.isEmpty());
345         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
346             GPRReg gpr = iter.regID();
347             if (iter.name().isValid() && gpr != exclude && gpr != exclude2) {
348                 SilentRegisterSavePlan plan = silentSavePlanForGPR(iter.name(), gpr);
349                 if (doSpill)
350                     silentSpill(plan);
351                 plans.append(plan);
352             }
353         }
354         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
355             if (iter.name().isValid() && iter.regID() != fprExclude) {
356                 SilentRegisterSavePlan plan = silentSavePlanForFPR(iter.name(), iter.regID());
357                 if (doSpill)
358                     silentSpill(plan);
359                 plans.append(plan);
360             }
361         }
362     }
363     template<typename CollectionType>
364     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, NoResultTag)
365     {
366         silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, InvalidFPRReg);
367     }
368     template<typename CollectionType>
369     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, FPRReg exclude)
370     {
371         silentSpillAllRegistersImpl(doSpill, plans, InvalidGPRReg, InvalidGPRReg, exclude);
372     }
373 #if USE(JSVALUE32_64)
374     template<typename CollectionType>
375     void silentSpillAllRegistersImpl(bool doSpill, CollectionType& plans, JSValueRegs exclude)
376     {
377         silentSpillAllRegistersImpl(doSpill, plans, exclude.tagGPR(), exclude.payloadGPR());
378     }
379 #endif
380     
381     void silentSpillAllRegisters(GPRReg exclude, GPRReg exclude2 = InvalidGPRReg, FPRReg fprExclude = InvalidFPRReg)
382     {
383         silentSpillAllRegistersImpl(true, m_plans, exclude, exclude2, fprExclude);
384     }
385     void silentSpillAllRegisters(FPRReg exclude)
386     {
387         silentSpillAllRegisters(InvalidGPRReg, InvalidGPRReg, exclude);
388     }
389     void silentSpillAllRegisters(JSValueRegs exclude)
390     {
391 #if USE(JSVALUE64)
392         silentSpillAllRegisters(exclude.payloadGPR());
393 #else
394         silentSpillAllRegisters(exclude.payloadGPR(), exclude.tagGPR());
395 #endif
396     }
397     
398     static GPRReg pickCanTrample(GPRReg exclude)
399     {
400         GPRReg result = GPRInfo::regT0;
401         if (result == exclude)
402             result = GPRInfo::regT1;
403         return result;
404     }
405     static GPRReg pickCanTrample(FPRReg)
406     {
407         return GPRInfo::regT0;
408     }
409     static GPRReg pickCanTrample(NoResultTag)
410     {
411         return GPRInfo::regT0;
412     }
413
414 #if USE(JSVALUE64)
415     static GPRReg pickCanTrample(JSValueRegs exclude)
416     {
417         return pickCanTrample(exclude.payloadGPR());
418     }
419 #else
420     static GPRReg pickCanTrample(JSValueRegs exclude)
421     {
422         GPRReg result = GPRInfo::regT0;
423         if (result == exclude.tagGPR()) {
424             result = GPRInfo::regT1;
425             if (result == exclude.payloadGPR())
426                 result = GPRInfo::regT2;
427         } else if (result == exclude.payloadGPR()) {
428             result = GPRInfo::regT1;
429             if (result == exclude.tagGPR())
430                 result = GPRInfo::regT2;
431         }
432         return result;
433     }
434 #endif
435     
436     template<typename RegisterType>
437     void silentFillAllRegisters(RegisterType exclude)
438     {
439         GPRReg canTrample = pickCanTrample(exclude);
440         
441         while (!m_plans.isEmpty()) {
442             SilentRegisterSavePlan& plan = m_plans.last();
443             silentFill(plan, canTrample);
444             m_plans.removeLast();
445         }
446     }
447
448     // These methods convert between doubles, and doubles boxed and JSValues.
449 #if USE(JSVALUE64)
450     GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
451     {
452         return m_jit.boxDouble(fpr, gpr);
453     }
454     FPRReg unboxDouble(GPRReg gpr, FPRReg fpr)
455     {
456         return m_jit.unboxDouble(gpr, fpr);
457     }
458     GPRReg boxDouble(FPRReg fpr)
459     {
460         return boxDouble(fpr, allocate());
461     }
462     
463     void boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat);
464 #elif USE(JSVALUE32_64)
465     void boxDouble(FPRReg fpr, GPRReg tagGPR, GPRReg payloadGPR)
466     {
467         m_jit.boxDouble(fpr, tagGPR, payloadGPR);
468     }
469     void unboxDouble(GPRReg tagGPR, GPRReg payloadGPR, FPRReg fpr, FPRReg scratchFPR)
470     {
471         m_jit.unboxDouble(tagGPR, payloadGPR, fpr, scratchFPR);
472     }
473 #endif
474     void boxDouble(FPRReg fpr, JSValueRegs regs)
475     {
476         m_jit.boxDouble(fpr, regs);
477     }
478
479     // Spill a VirtualRegister to the JSStack.
480     void spill(VirtualRegister spillMe)
481     {
482         GenerationInfo& info = generationInfoFromVirtualRegister(spillMe);
483
484 #if USE(JSVALUE32_64)
485         if (info.registerFormat() == DataFormatNone) // it has been spilled. JS values which have two GPRs can reach here
486             return;
487 #endif
488         // Check the GenerationInfo to see if this value need writing
489         // to the JSStack - if not, mark it as spilled & return.
490         if (!info.needsSpill()) {
491             info.setSpilled(*m_stream, spillMe);
492             return;
493         }
494
495         DataFormat spillFormat = info.registerFormat();
496         switch (spillFormat) {
497         case DataFormatStorage: {
498             // This is special, since it's not a JS value - as in it's not visible to JS
499             // code.
500             m_jit.storePtr(info.gpr(), JITCompiler::addressFor(spillMe));
501             info.spill(*m_stream, spillMe, DataFormatStorage);
502             return;
503         }
504
505         case DataFormatInt32: {
506             m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
507             info.spill(*m_stream, spillMe, DataFormatInt32);
508             return;
509         }
510
511 #if USE(JSVALUE64)
512         case DataFormatDouble: {
513             m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
514             info.spill(*m_stream, spillMe, DataFormatDouble);
515             return;
516         }
517
518         case DataFormatInt52:
519         case DataFormatStrictInt52: {
520             m_jit.store64(info.gpr(), JITCompiler::addressFor(spillMe));
521             info.spill(*m_stream, spillMe, spillFormat);
522             return;
523         }
524             
525         default:
526             // The following code handles JSValues, int32s, and cells.
527             RELEASE_ASSERT(spillFormat == DataFormatCell || spillFormat & DataFormatJS);
528             
529             GPRReg reg = info.gpr();
530             // We need to box int32 and cell values ...
531             // but on JSVALUE64 boxing a cell is a no-op!
532             if (spillFormat == DataFormatInt32)
533                 m_jit.or64(GPRInfo::tagTypeNumberRegister, reg);
534             
535             // Spill the value, and record it as spilled in its boxed form.
536             m_jit.store64(reg, JITCompiler::addressFor(spillMe));
537             info.spill(*m_stream, spillMe, (DataFormat)(spillFormat | DataFormatJS));
538             return;
539 #elif USE(JSVALUE32_64)
540         case DataFormatCell:
541         case DataFormatBoolean: {
542             m_jit.store32(info.gpr(), JITCompiler::payloadFor(spillMe));
543             info.spill(*m_stream, spillMe, spillFormat);
544             return;
545         }
546
547         case DataFormatDouble: {
548             // On JSVALUE32_64 boxing a double is a no-op.
549             m_jit.storeDouble(info.fpr(), JITCompiler::addressFor(spillMe));
550             info.spill(*m_stream, spillMe, DataFormatDouble);
551             return;
552         }
553
554         default:
555             // The following code handles JSValues.
556             RELEASE_ASSERT(spillFormat & DataFormatJS);
557             m_jit.store32(info.tagGPR(), JITCompiler::tagFor(spillMe));
558             m_jit.store32(info.payloadGPR(), JITCompiler::payloadFor(spillMe));
559             info.spill(*m_stream, spillMe, spillFormat);
560             return;
561 #endif
562         }
563     }
564     
565     bool isKnownInteger(Node* node) { return m_state.forNode(node).isType(SpecInt32); }
566     bool isKnownCell(Node* node) { return m_state.forNode(node).isType(SpecCell); }
567     
568     bool isKnownNotInteger(Node* node) { return !(m_state.forNode(node).m_type & SpecInt32); }
569     bool isKnownNotNumber(Node* node) { return !(m_state.forNode(node).m_type & SpecFullNumber); }
570     bool isKnownNotCell(Node* node) { return !(m_state.forNode(node).m_type & SpecCell); }
571     bool isKnownNotOther(Node* node) { return !(m_state.forNode(node).m_type & SpecOther); }
572     
573     UniquedStringImpl* identifierUID(unsigned index)
574     {
575         return m_jit.graph().identifiers()[index];
576     }
577
578     // Spill all VirtualRegisters back to the JSStack.
579     void flushRegisters()
580     {
581         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
582             if (iter.name().isValid()) {
583                 spill(iter.name());
584                 iter.release();
585             }
586         }
587         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
588             if (iter.name().isValid()) {
589                 spill(iter.name());
590                 iter.release();
591             }
592         }
593     }
594
595     // Used to ASSERT flushRegisters() has been called prior to
596     // calling out from JIT code to a C helper function.
597     bool isFlushed()
598     {
599         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
600             if (iter.name().isValid())
601                 return false;
602         }
603         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
604             if (iter.name().isValid())
605                 return false;
606         }
607         return true;
608     }
609
610 #if USE(JSVALUE64)
611     static MacroAssembler::Imm64 valueOfJSConstantAsImm64(Node* node)
612     {
613         return MacroAssembler::Imm64(JSValue::encode(node->asJSValue()));
614     }
615 #endif
616
617     // Helper functions to enable code sharing in implementations of bit/shift ops.
618     void bitOp(NodeType op, int32_t imm, GPRReg op1, GPRReg result)
619     {
620         switch (op) {
621         case BitAnd:
622             m_jit.and32(Imm32(imm), op1, result);
623             break;
624         case BitOr:
625             m_jit.or32(Imm32(imm), op1, result);
626             break;
627         case BitXor:
628             m_jit.xor32(Imm32(imm), op1, result);
629             break;
630         default:
631             RELEASE_ASSERT_NOT_REACHED();
632         }
633     }
634     void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
635     {
636         switch (op) {
637         case BitAnd:
638             m_jit.and32(op1, op2, result);
639             break;
640         case BitOr:
641             m_jit.or32(op1, op2, result);
642             break;
643         case BitXor:
644             m_jit.xor32(op1, op2, result);
645             break;
646         default:
647             RELEASE_ASSERT_NOT_REACHED();
648         }
649     }
650     void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
651     {
652         switch (op) {
653         case BitRShift:
654             m_jit.rshift32(op1, Imm32(shiftAmount), result);
655             break;
656         case BitLShift:
657             m_jit.lshift32(op1, Imm32(shiftAmount), result);
658             break;
659         case BitURShift:
660             m_jit.urshift32(op1, Imm32(shiftAmount), result);
661             break;
662         default:
663             RELEASE_ASSERT_NOT_REACHED();
664         }
665     }
666     void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
667     {
668         switch (op) {
669         case BitRShift:
670             m_jit.rshift32(op1, shiftAmount, result);
671             break;
672         case BitLShift:
673             m_jit.lshift32(op1, shiftAmount, result);
674             break;
675         case BitURShift:
676             m_jit.urshift32(op1, shiftAmount, result);
677             break;
678         default:
679             RELEASE_ASSERT_NOT_REACHED();
680         }
681     }
682     
683     // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
684     unsigned detectPeepHoleBranch()
685     {
686         // Check that no intervening nodes will be generated.
687         for (unsigned index = m_indexInBlock + 1; index < m_block->size() - 1; ++index) {
688             Node* node = m_block->at(index);
689             if (!node->shouldGenerate())
690                 continue;
691             // Check if it's a Phantom that can be safely ignored.
692             if (node->op() == Phantom && !node->child1())
693                 continue;
694             return UINT_MAX;
695         }
696
697         // Check if the lastNode is a branch on this node.
698         Node* lastNode = m_block->terminal();
699         return lastNode->op() == Branch && lastNode->child1() == m_currentNode ? m_block->size() - 1 : UINT_MAX;
700     }
701     
702     void compileMovHint(Node*);
703     void compileMovHintAndCheck(Node*);
704
705 #if USE(JSVALUE64)
706     void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
707     void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
708 #elif USE(JSVALUE32_64)
709     void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
710     void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
711 #endif
712     
713     void compileIn(Node*);
714     
715     void compileBaseValueStoreBarrier(Edge& baseEdge, Edge& valueEdge);
716
717     void nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand);
718     void nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode);
719     
720     void nonSpeculativePeepholeBranch(Node*, Node* branchNode, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
721     void nonSpeculativeNonPeepholeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
722     bool nonSpeculativeCompare(Node*, MacroAssembler::RelationalCondition, S_JITOperation_EJJ helperFunction);
723     
724     void nonSpeculativePeepholeStrictEq(Node*, Node* branchNode, bool invert = false);
725     void nonSpeculativeNonPeepholeStrictEq(Node*, bool invert = false);
726     bool nonSpeculativeStrictEq(Node*, bool invert = false);
727     
728     void compileInstanceOfForObject(Node*, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg, GPRReg scratch2Reg);
729     void compileInstanceOf(Node*);
730     
731     void emitCall(Node*);
732     
733     // Called once a node has completed code generation but prior to setting
734     // its result, to free up its children. (This must happen prior to setting
735     // the nodes result, since the node may have the same VirtualRegister as
736     // a child, and as such will use the same GeneratioInfo).
737     void useChildren(Node*);
738
739     // These method called to initialize the the GenerationInfo
740     // to describe the result of an operation.
741     void int32Result(GPRReg reg, Node* node, DataFormat format = DataFormatInt32, UseChildrenMode mode = CallUseChildren)
742     {
743         if (mode == CallUseChildren)
744             useChildren(node);
745
746         VirtualRegister virtualRegister = node->virtualRegister();
747         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
748
749         if (format == DataFormatInt32) {
750             m_jit.jitAssertIsInt32(reg);
751             m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
752             info.initInt32(node, node->refCount(), reg);
753         } else {
754 #if USE(JSVALUE64)
755             RELEASE_ASSERT(format == DataFormatJSInt32);
756             m_jit.jitAssertIsJSInt32(reg);
757             m_gprs.retain(reg, virtualRegister, SpillOrderJS);
758             info.initJSValue(node, node->refCount(), reg, format);
759 #elif USE(JSVALUE32_64)
760             RELEASE_ASSERT_NOT_REACHED();
761 #endif
762         }
763     }
764     void int32Result(GPRReg reg, Node* node, UseChildrenMode mode)
765     {
766         int32Result(reg, node, DataFormatInt32, mode);
767     }
768     void int52Result(GPRReg reg, Node* node, DataFormat format, UseChildrenMode mode = CallUseChildren)
769     {
770         if (mode == CallUseChildren)
771             useChildren(node);
772
773         VirtualRegister virtualRegister = node->virtualRegister();
774         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
775
776         m_gprs.retain(reg, virtualRegister, SpillOrderJS);
777         info.initInt52(node, node->refCount(), reg, format);
778     }
779     void int52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
780     {
781         int52Result(reg, node, DataFormatInt52, mode);
782     }
783     void strictInt52Result(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
784     {
785         int52Result(reg, node, DataFormatStrictInt52, mode);
786     }
787     void noResult(Node* node, UseChildrenMode mode = CallUseChildren)
788     {
789         if (mode == UseChildrenCalledExplicitly)
790             return;
791         useChildren(node);
792     }
793     void cellResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
794     {
795         if (mode == CallUseChildren)
796             useChildren(node);
797
798         VirtualRegister virtualRegister = node->virtualRegister();
799         m_gprs.retain(reg, virtualRegister, SpillOrderCell);
800         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
801         info.initCell(node, node->refCount(), reg);
802     }
803     void blessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
804     {
805 #if USE(JSVALUE64)
806         jsValueResult(reg, node, DataFormatJSBoolean, mode);
807 #else
808         booleanResult(reg, node, mode);
809 #endif
810     }
811     void unblessedBooleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
812     {
813 #if USE(JSVALUE64)
814         blessBoolean(reg);
815 #endif
816         blessedBooleanResult(reg, node, mode);
817     }
818 #if USE(JSVALUE64)
819     void jsValueResult(GPRReg reg, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
820     {
821         if (format == DataFormatJSInt32)
822             m_jit.jitAssertIsJSInt32(reg);
823         
824         if (mode == CallUseChildren)
825             useChildren(node);
826
827         VirtualRegister virtualRegister = node->virtualRegister();
828         m_gprs.retain(reg, virtualRegister, SpillOrderJS);
829         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
830         info.initJSValue(node, node->refCount(), reg, format);
831     }
832     void jsValueResult(GPRReg reg, Node* node, UseChildrenMode mode)
833     {
834         jsValueResult(reg, node, DataFormatJS, mode);
835     }
836 #elif USE(JSVALUE32_64)
837     void booleanResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
838     {
839         if (mode == CallUseChildren)
840             useChildren(node);
841
842         VirtualRegister virtualRegister = node->virtualRegister();
843         m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
844         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
845         info.initBoolean(node, node->refCount(), reg);
846     }
847     void jsValueResult(GPRReg tag, GPRReg payload, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
848     {
849         if (mode == CallUseChildren)
850             useChildren(node);
851
852         VirtualRegister virtualRegister = node->virtualRegister();
853         m_gprs.retain(tag, virtualRegister, SpillOrderJS);
854         m_gprs.retain(payload, virtualRegister, SpillOrderJS);
855         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
856         info.initJSValue(node, node->refCount(), tag, payload, format);
857     }
858     void jsValueResult(GPRReg tag, GPRReg payload, Node* node, UseChildrenMode mode)
859     {
860         jsValueResult(tag, payload, node, DataFormatJS, mode);
861     }
862 #endif
863     void jsValueResult(JSValueRegs regs, Node* node, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
864     {
865 #if USE(JSVALUE64)
866         jsValueResult(regs.gpr(), node, format, mode);
867 #else
868         jsValueResult(regs.tagGPR(), regs.payloadGPR(), node, format, mode);
869 #endif
870     }
871     void storageResult(GPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
872     {
873         if (mode == CallUseChildren)
874             useChildren(node);
875         
876         VirtualRegister virtualRegister = node->virtualRegister();
877         m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
878         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
879         info.initStorage(node, node->refCount(), reg);
880     }
881     void doubleResult(FPRReg reg, Node* node, UseChildrenMode mode = CallUseChildren)
882     {
883         if (mode == CallUseChildren)
884             useChildren(node);
885
886         VirtualRegister virtualRegister = node->virtualRegister();
887         m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
888         GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
889         info.initDouble(node, node->refCount(), reg);
890     }
891     void initConstantInfo(Node* node)
892     {
893         ASSERT(node->hasConstant());
894         generationInfo(node).initConstant(node, node->refCount());
895     }
896     
897     // These methods add calls to C++ helper functions.
898     // These methods are broadly value representation specific (i.e.
899     // deal with the fact that a JSValue may be passed in one or two
900     // machine registers, and delegate the calling convention specific
901     // decision as to how to fill the regsiters to setupArguments* methods.
902
903     JITCompiler::Call callOperation(V_JITOperation_E operation)
904     {
905         m_jit.setupArgumentsExecState();
906         return appendCall(operation);
907     }
908     JITCompiler::Call callOperation(P_JITOperation_E operation, GPRReg result)
909     {
910         m_jit.setupArgumentsExecState();
911         return appendCallSetResult(operation, result);
912     }
913     JITCompiler::Call callOperation(P_JITOperation_EC operation, GPRReg result, GPRReg cell)
914     {
915         m_jit.setupArgumentsWithExecState(cell);
916         return appendCallSetResult(operation, result);
917     }
918     JITCompiler::Call callOperation(P_JITOperation_EO operation, GPRReg result, GPRReg object)
919     {
920         m_jit.setupArgumentsWithExecState(object);
921         return appendCallSetResult(operation, result);
922     }
923     JITCompiler::Call callOperation(P_JITOperation_EOS operation, GPRReg result, GPRReg object, size_t size)
924     {
925         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
926         return appendCallSetResult(operation, result);
927     }
928     JITCompiler::Call callOperation(P_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
929     {
930         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
931         return appendCallSetResult(operation, result);
932     }
933     JITCompiler::Call callOperation(C_JITOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
934     {
935         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(static_cast<size_t>(size)));
936         return appendCallSetResult(operation, result);
937     }
938     JITCompiler::Call callOperation(P_JITOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
939     {
940         m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
941         return appendCallSetResult(operation, result);
942     }
943     JITCompiler::Call callOperation(P_JITOperation_ES operation, GPRReg result, size_t size)
944     {
945         m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
946         return appendCallSetResult(operation, result);
947     }
948     JITCompiler::Call callOperation(P_JITOperation_ESJss operation, GPRReg result, size_t index, GPRReg arg1)
949     {
950         m_jit.setupArgumentsWithExecState(TrustedImmPtr(index), arg1);
951         return appendCallSetResult(operation, result);
952     }
953     JITCompiler::Call callOperation(P_JITOperation_ESt operation, GPRReg result, Structure* structure)
954     {
955         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
956         return appendCallSetResult(operation, result);
957     }
958     JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
959     {
960         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
961         return appendCallSetResult(operation, result);
962     }
963     JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
964     {
965         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
966         return appendCallSetResult(operation, result);
967     }
968     JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
969     {
970         m_jit.setupArgumentsWithExecState(arg1, arg2);
971         return appendCallSetResult(operation, result);
972     }
973     JITCompiler::Call callOperation(P_JITOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
974     {
975         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
976         return appendCallSetResult(operation, result);
977     }
978     JITCompiler::Call callOperation(P_JITOperation_EStSS operation, GPRReg result, Structure* structure, size_t index, size_t size)
979     {
980         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(index), TrustedImmPtr(size));
981         return appendCallSetResult(operation, result);
982     }
983     JITCompiler::Call callOperation(C_JITOperation_E operation, GPRReg result)
984     {
985         m_jit.setupArgumentsExecState();
986         return appendCallSetResult(operation, result);
987     }
988     JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, GPRReg arg1)
989     {
990         m_jit.setupArgumentsWithExecState(arg1);
991         return appendCallSetResult(operation, result);
992     }
993     JITCompiler::Call callOperation(C_JITOperation_EC operation, GPRReg result, JSCell* cell)
994     {
995         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
996         return appendCallSetResult(operation, result);
997     }
998     JITCompiler::Call callOperation(C_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
999     {
1000         m_jit.setupArgumentsWithExecState(arg1, arg2);
1001         return appendCallSetResult(operation, result);
1002     }
1003     JITCompiler::Call callOperation(C_JITOperation_ECZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1004     {
1005         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1006         return appendCallSetResult(operation, result);
1007     }
1008     JITCompiler::Call callOperation(C_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1009     {
1010         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1011         return appendCallSetResult(operation, result);
1012     }
1013     JITCompiler::Call callOperation(C_JITOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
1014     {
1015         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1016         return appendCallSetResult(operation, result);
1017     }
1018     JITCompiler::Call callOperation(C_JITOperation_ESt operation, GPRReg result, Structure* structure)
1019     {
1020         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1021         return appendCallSetResult(operation, result);
1022     }
1023
1024 #if USE(JSVALUE64)
1025     JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table, TrustedImm64 initialValue)
1026     {
1027         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table), initialValue);
1028         return appendCallSetResult(operation, result);
1029     }
1030 #else
1031     JITCompiler::Call callOperation(C_JITOperation_EStJscSymtabJ operation, GPRReg result, Structure* structure, GPRReg scope, SymbolTable* table, TrustedImm32 tag, TrustedImm32 payload)
1032     {
1033         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), scope, TrustedImmPtr(table), payload, tag);
1034         return appendCallSetResult(operation, result);
1035     }
1036 #endif
1037     JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, unsigned knownLength)
1038     {
1039         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength));
1040         return appendCallSetResult(operation, result);
1041     }
1042     JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, unsigned knownLength, unsigned minCapacity)
1043     {
1044         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(knownLength), TrustedImm32(minCapacity));
1045         return appendCallSetResult(operation, result);
1046     }
1047     JITCompiler::Call callOperation(C_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg length)
1048     {
1049         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length);
1050         return appendCallSetResult(operation, result);
1051     }
1052     JITCompiler::Call callOperation(C_JITOperation_EStZZ operation, GPRReg result, Structure* structure, GPRReg length, unsigned minCapacity)
1053     {
1054         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), length, TrustedImm32(minCapacity));
1055         return appendCallSetResult(operation, result);
1056     }
1057     JITCompiler::Call callOperation(C_JITOperation_EJssSt operation, GPRReg result, GPRReg arg1, Structure* structure)
1058     {
1059         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(structure));
1060         return appendCallSetResult(operation, result);
1061     }
1062     JITCompiler::Call callOperation(C_JITOperation_EJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1063     {
1064         m_jit.setupArgumentsWithExecState(arg1, arg2);
1065         return appendCallSetResult(operation, result);
1066     }
1067     JITCompiler::Call callOperation(C_JITOperation_EJssJssJss operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1068     {
1069         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1070         return appendCallSetResult(operation, result);
1071     }
1072
1073     JITCompiler::Call callOperation(S_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1074     {
1075         m_jit.setupArgumentsWithExecState(arg1, arg2);
1076         return appendCallSetResult(operation, result);
1077     }
1078
1079     JITCompiler::Call callOperation(S_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
1080     {
1081         m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
1082         return appendCallSetResult(operation, result);
1083     }
1084
1085     JITCompiler::Call callOperation(C_JITOperation_EGC operation, GPRReg result, JSGlobalObject* globalObject, GPRReg arg2)
1086     {
1087         m_jit.setupArgumentsWithExecState(TrustedImmPtr(globalObject), arg2);
1088         return appendCallSetResult(operation, result);
1089     }
1090
1091     JITCompiler::Call callOperation(Jss_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1092     {
1093         m_jit.setupArgumentsWithExecState(arg1);
1094         return appendCallSetResult(operation, result);
1095     }
1096
1097     JITCompiler::Call callOperation(V_JITOperation_EC operation, GPRReg arg1)
1098     {
1099         m_jit.setupArgumentsWithExecState(arg1);
1100         return appendCall(operation);
1101     }
1102
1103     JITCompiler::Call callOperation(V_JITOperation_EC operation, JSCell* arg1)
1104     {
1105         m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1));
1106         return appendCall(operation);
1107     }
1108
1109     JITCompiler::Call callOperation(V_JITOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
1110     {
1111         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1112         return appendCall(operation);
1113     }
1114     JITCompiler::Call callOperation(V_JITOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
1115     {
1116         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1117         return appendCall(operation);
1118     }
1119
1120     JITCompiler::Call callOperation(V_JITOperation_ECZ operation, GPRReg arg1, int arg2)
1121     {
1122         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1123         return appendCall(operation);
1124     }
1125     JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1126     {
1127         m_jit.setupArgumentsWithExecState(arg1, arg2);
1128         return appendCall(operation);
1129     }
1130     JITCompiler::Call callOperation(V_JITOperation_ECC operation, GPRReg arg1, JSCell* arg2)
1131     {
1132         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1133         return appendCall(operation);
1134     }
1135     JITCompiler::Call callOperation(V_JITOperation_ECC operation, JSCell* arg1, GPRReg arg2)
1136     {
1137         m_jit.setupArgumentsWithExecState(TrustedImmPtr(arg1), arg2);
1138         return appendCall(operation);
1139     }
1140
1141     JITCompiler::Call callOperationWithCallFrameRollbackOnException(V_JITOperation_ECb operation, void* pointer)
1142     {
1143         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1144         return appendCallWithCallFrameRollbackOnException(operation);
1145     }
1146
1147     JITCompiler::Call callOperationWithCallFrameRollbackOnException(Z_JITOperation_E operation, GPRReg result)
1148     {
1149         m_jit.setupArgumentsExecState();
1150         return appendCallWithCallFrameRollbackOnExceptionSetResult(operation, result);
1151     }
1152     JITCompiler::Call callOperation(Z_JITOperation_EC operation, GPRReg result, GPRReg arg1)
1153     {
1154         m_jit.setupArgumentsWithExecState(arg1);
1155         return appendCallSetResult(operation, result);
1156     }
1157
1158     JITCompiler::Call callOperation(V_JITOperation_ECIZC operation, GPRReg regOp1, UniquedStringImpl* identOp2, int32_t op3, GPRReg regOp4)
1159     {
1160         m_jit.setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), TrustedImm32(op3), regOp4);
1161         return appendCall(operation);
1162     }
1163
1164     template<typename FunctionType, typename... Args>
1165     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, Args... args)
1166     {
1167         return callOperation(operation, args...);
1168     }
1169
1170     JITCompiler::Call callOperation(D_JITOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1171     {
1172         m_jit.setupArguments(arg1, arg2);
1173         return appendCallSetResult(operation, result);
1174     }
1175     JITCompiler::Call callOperation(D_JITOperation_D operation, FPRReg result, FPRReg arg1)
1176     {
1177         m_jit.setupArguments(arg1);
1178         return appendCallSetResult(operation, result);
1179     }
1180     JITCompiler::Call callOperation(D_JITOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1181     {
1182         m_jit.setupArguments(arg1, arg2);
1183         return appendCallSetResult(operation, result);
1184     }
1185     JITCompiler::Call callOperation(T_JITOperation_EJss operation, GPRReg result, GPRReg arg1)
1186     {
1187         m_jit.setupArgumentsWithExecState(arg1);
1188         return appendCallSetResult(operation, result);
1189     }
1190     JITCompiler::Call callOperation(C_JITOperation_EJscZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
1191     {
1192         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1193         return appendCallSetResult(operation, result);
1194     }
1195     JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1196     {
1197         m_jit.setupArgumentsWithExecState(arg1);
1198         return appendCallSetResult(operation, result);
1199     }
1200     JITCompiler::Call callOperation(C_JITOperation_EZ operation, GPRReg result, int32_t arg1)
1201     {
1202         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1203         return appendCallSetResult(operation, result);
1204     }
1205
1206     JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1207     {
1208         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1209         return appendCallSetResult(operation, result);
1210     }
1211     
1212     JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, GPRReg arg2)
1213     {
1214         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), arg2);
1215         return appendCallSetResult(operation, result);
1216     }
1217
1218     JITCompiler::Call callOperation(V_JITOperation_EWs operation, WatchpointSet* watchpointSet)
1219     {
1220         m_jit.setupArgumentsWithExecState(TrustedImmPtr(watchpointSet));
1221         return appendCall(operation);
1222     }
1223
1224     JITCompiler::Call callOperation(V_JITOperation_ECRUiUi operation, GPRReg arg1, GPRReg arg2, Imm32 arg3, GPRReg arg4)
1225     {
1226         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3.asTrustedImm32(), arg4);
1227         return appendCall(operation);
1228     }
1229
1230 #if USE(JSVALUE64)
1231     JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg result)
1232     {
1233         m_jit.setupArgumentsExecState();
1234         return appendCallSetResult(operation, result);
1235     }
1236     JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, void* pointer)
1237     {
1238         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1239         return appendCallSetResult(operation, result);
1240     }
1241     JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
1242     {
1243         m_jit.setupArguments(arg1);
1244         JITCompiler::Call call = m_jit.appendCall(operation);
1245         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1246         return call;
1247     }
1248     JITCompiler::Call callOperation(Q_JITOperation_J operation, GPRReg result, GPRReg value)
1249     {
1250         m_jit.setupArguments(value);
1251         return appendCallSetResult(operation, result);
1252     }
1253     JITCompiler::Call callOperation(Q_JITOperation_D operation, GPRReg result, FPRReg value)
1254     {
1255         m_jit.setupArguments(value);
1256         return appendCallSetResult(operation, result);
1257     }
1258     JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg result, UniquedStringImpl* uid)
1259     {
1260         m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
1261         return appendCallSetResult(operation, result);
1262     }
1263     JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg result, GPRReg arg1)
1264     {
1265         m_jit.setupArgumentsWithExecState(arg1);
1266         return appendCallSetResult(operation, result);
1267     }
1268     JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1269     {
1270         m_jit.setupArgumentsWithExecState(arg1, arg2);
1271         return appendCallSetResult(operation, result);
1272     }
1273     JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1274     {
1275         m_jit.setupArgumentsWithExecState(arg1, arg2);
1276         return appendCallSetResult(operation, result);
1277     }
1278     JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg result, void* pointer, size_t size)
1279     {
1280         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1281         return appendCallSetResult(operation, result);
1282     }
1283     JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
1284     {
1285         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1286         return appendCallSetResult(operation, result);
1287     }
1288     JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
1289     {
1290         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1291         return appendCallSetResult(operation, result);
1292     }
1293     JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg result, JSCell* cell)
1294     {
1295         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1296         return appendCallSetResult(operation, result);
1297     }
1298     JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1299     {
1300         m_jit.setupArgumentsWithExecState(arg1, arg2);
1301         return appendCallSetResult(operation, result);
1302     }
1303     JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
1304     {
1305         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
1306         return appendCallSetResult(operation, result);
1307     }
1308     JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg result, StructureStubInfo* stubInfo, GPRReg arg1, UniquedStringImpl* uid)
1309     {
1310         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
1311         return appendCallSetResult(operation, result);
1312     }
1313     JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg result, FPRReg arg1, GPRReg arg2)
1314     {
1315         m_jit.setupArgumentsWithExecState(arg1, arg2);
1316         return appendCallSetResult(operation, result);
1317     }
1318     JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1319     {
1320         m_jit.setupArgumentsWithExecState(arg1, arg2);
1321         return appendCallSetResult(operation, result);
1322     }
1323     JITCompiler::Call callOperation(J_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1324     {
1325         m_jit.setupArgumentsWithExecState(arg1, arg2);
1326         return appendCallSetResult(operation, result);
1327     }
1328     JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1329     {
1330         m_jit.setupArgumentsWithExecState(arg1, arg2);
1331         return appendCallSetResult(operation, result);
1332     }
1333     JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg result, GPRReg arg1)
1334     {
1335         m_jit.setupArgumentsWithExecState(arg1);
1336         return appendCallSetResult(operation, result);
1337     }
1338     JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, GPRReg arg1)
1339     {
1340         m_jit.setupArgumentsWithExecState(arg1);
1341         return appendCallSetResult(operation, result);
1342     }
1343     JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg result, int32_t arg1)
1344     {
1345         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1346         return appendCallSetResult(operation, result);
1347     }
1348     JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
1349     {
1350         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1351         return appendCallSetResult(operation, result);
1352     }
1353     JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1354     {
1355         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1356         return appendCallSetResult(operation, result);
1357     }
1358
1359     JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, GPRReg value, size_t index)
1360     {
1361         m_jit.setupArgumentsWithExecState(value, TrustedImmPtr(index));
1362         return appendCallSetResult(operation, result);
1363     }
1364
1365     JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2)
1366     {
1367         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1368         return appendCallSetResult(operation, result);
1369     }
1370
1371     JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1372     {
1373         m_jit.setupArgumentsWithExecState(arg1);
1374         return appendCallSetResult(operation, result);
1375     }
1376     JITCompiler::Call callOperation(C_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1377     {
1378         m_jit.setupArgumentsWithExecState(arg1, arg2);
1379         return appendCallSetResult(operation, result);
1380     }
1381     JITCompiler::Call callOperation(C_JITOperation_EJJC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1382     {
1383         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1384         return appendCallSetResult(operation, result);
1385     }
1386     JITCompiler::Call callOperation(C_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1387     {
1388         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1389         return appendCallSetResult(operation, result);
1390     }
1391     JITCompiler::Call callOperation(C_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1392     {
1393         m_jit.setupArgumentsWithExecState(arg1, arg2);
1394         return appendCallSetResult(operation, result);
1395     }
1396     JITCompiler::Call callOperation(C_JITOperation_EJZC operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1397     {
1398         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1399         return appendCallSetResult(operation, result);
1400     }
1401     JITCompiler::Call callOperation(S_JITOperation_J operation, GPRReg result, GPRReg arg1)
1402     {
1403         m_jit.setupArguments(arg1);
1404         return appendCallSetResult(operation, result);
1405     }
1406     JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1407     {
1408         m_jit.setupArgumentsWithExecState(arg1);
1409         return appendCallSetResult(operation, result);
1410     }
1411     JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg result, GPRReg arg1)
1412     {
1413         m_jit.setupArgumentsWithExecState(arg1);
1414         return appendCallSetResult(operation, result);
1415     }
1416     JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1417     {
1418         m_jit.setupArgumentsWithExecState(arg1, arg2);
1419         return appendCallSetResult(operation, result);
1420     }
1421
1422     JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1423     {
1424         m_jit.setupArgumentsWithExecState(arg1, arg2);
1425         return appendCallSetResult(operation, result);
1426     }
1427     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1428     {
1429         m_jit.setupArgumentsWithExecState(arg1, arg2);
1430         return appendCallSetResult(operation, result);
1431     }
1432     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
1433     {
1434         m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))));
1435         return appendCallSetResult(operation, result);
1436     }
1437     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
1438     {
1439         m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(imm.m_value))), arg2);
1440         return appendCallSetResult(operation, result);
1441     }
1442     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2)
1443     {
1444         return callOperation(operation, result.payloadGPR(), arg1.payloadGPR(), arg2.payloadGPR());
1445     }
1446     JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1447     {
1448         m_jit.setupArgumentsWithExecState(arg1, arg2);
1449         return appendCallSetResult(operation, result);
1450     }
1451     JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1452     {
1453         m_jit.setupArgumentsWithExecState(arg1, arg2);
1454         return appendCallSetResult(operation, result);
1455     }
1456     JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg result, GPRReg arg1, JSValueRegs arg2)
1457     {
1458         m_jit.setupArgumentsWithExecState(arg1, arg2.gpr());
1459         return appendCallSetResult(operation, result);
1460     }
1461
1462     JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1463     {
1464         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1465         return appendCall(operation);
1466     }
1467     JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1)
1468     {
1469         m_jit.setupArgumentsWithExecState(arg1);
1470         return appendCall(operation);
1471     }
1472     JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
1473     {
1474         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1475         return appendCall(operation);
1476     }
1477     JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1, GPRReg arg2, UniquedStringImpl* uid)
1478     {
1479         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, arg2, TrustedImmPtr(uid));
1480         return appendCall(operation);
1481     }
1482     JITCompiler::Call callOperation(V_JITOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1483     {
1484         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1485         return appendCall(operation);
1486     }
1487     JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1488     {
1489         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1490         return appendCall(operation);
1491     }
1492
1493     JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1494     {
1495         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1496         return appendCall(operation);
1497     }
1498     JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1499     {
1500         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1501         return appendCall(operation);
1502     }
1503
1504     JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1, unsigned arg2, unsigned arg3)
1505     {
1506         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2), TrustedImm32(arg3));
1507         return appendCallSetResult(operation, result);
1508     }
1509     JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2, unsigned arg3, GPRReg arg4)
1510     {
1511         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImm32(arg3), arg4);
1512         return appendCallSetResult(operation, result);
1513     }
1514     JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1, unsigned arg2)
1515     {
1516         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1517         return appendCallSetResult(operation, result);
1518     }
1519     JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2, unsigned arg3, GPRReg arg4, unsigned arg5)
1520     {
1521         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
1522         return appendCall(operation);
1523     }
1524     JITCompiler::Call callOperation(V_JITOperation_ECJZC operation, GPRReg regOp1, GPRReg regOp2, int32_t op3, GPRReg regOp4)
1525     {
1526         m_jit.setupArgumentsWithExecState(regOp1, regOp2, TrustedImm32(op3), regOp4);
1527         return appendCall(operation);
1528     }
1529     JITCompiler::Call callOperation(V_JITOperation_ECIZJJ operation, GPRReg regOp1, UniquedStringImpl* identOp2, int32_t op3, GPRReg regOp4, GPRReg regOp5)
1530     {
1531         m_jit.setupArgumentsWithExecState(regOp1, TrustedImmPtr(identOp2), TrustedImm32(op3), regOp4, regOp5);
1532         return appendCall(operation);
1533     }
1534 #else // USE(JSVALUE32_64)
1535
1536 // 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]).
1537 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1538 #if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
1539 #define EABI_32BIT_DUMMY_ARG      TrustedImm32(0),
1540 #else
1541 #define EABI_32BIT_DUMMY_ARG
1542 #endif
1543
1544 // JSVALUE32_64 is a 64-bit integer that cannot be put half in an argument register and half on stack when using SH4 architecture.
1545 // To avoid this, let's occupy the 4th argument register (r7) with a dummy argument when necessary. This must only be done when there
1546 // is no other 32-bit value argument behind this 64-bit JSValue.
1547 #if CPU(SH4)
1548 #define SH4_32BIT_DUMMY_ARG      TrustedImm32(0),
1549 #else
1550 #define SH4_32BIT_DUMMY_ARG
1551 #endif
1552
1553     JITCompiler::Call callOperation(Z_JITOperation_D operation, GPRReg result, FPRReg arg1)
1554     {
1555         prepareForExternalCall();
1556         m_jit.setupArguments(arg1);
1557         JITCompiler::Call call = m_jit.appendCall(operation);
1558         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1559         return call;
1560     }
1561     JITCompiler::Call callOperation(J_JITOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
1562     {
1563         m_jit.setupArgumentsExecState();
1564         return appendCallSetResult(operation, resultPayload, resultTag);
1565     }
1566     JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
1567     {
1568         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1569         return appendCallSetResult(operation, resultPayload, resultTag);
1570     }
1571     JITCompiler::Call callOperation(J_JITOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
1572     {
1573         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1574         return appendCallSetResult(operation, resultPayload, resultTag);
1575     }
1576     JITCompiler::Call callOperation(J_JITOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1577     {
1578         m_jit.setupArgumentsWithExecState(arg1);
1579         return appendCallSetResult(operation, resultPayload, resultTag);
1580     }
1581     JITCompiler::Call callOperation(J_JITOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, UniquedStringImpl* uid)
1582     {
1583         m_jit.setupArgumentsWithExecState(TrustedImmPtr(uid));
1584         return appendCallSetResult(operation, resultPayload, resultTag);
1585     }
1586     JITCompiler::Call callOperation(J_JITOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1587     {
1588         m_jit.setupArgumentsWithExecState(arg1);
1589         return appendCallSetResult(operation, resultPayload, resultTag);
1590     }
1591     JITCompiler::Call callOperation(J_JITOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1592     {
1593         m_jit.setupArgumentsWithExecState(arg1, arg2);
1594         return appendCallSetResult(operation, resultPayload, resultTag);
1595     }
1596     JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultPayload, GPRReg resultTag, GPRReg arg1)
1597     {
1598         m_jit.setupArgumentsWithExecState(arg1);
1599         return appendCallSetResult(operation, resultPayload, resultTag);
1600     }
1601     JITCompiler::Call callOperation(J_JITOperation_EJC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1602     {
1603         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1604         return appendCallSetResult(operation, resultPayload, resultTag);
1605     }
1606     JITCompiler::Call callOperation(J_JITOperation_EJssZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1607     {
1608         m_jit.setupArgumentsWithExecState(arg1, arg2);
1609         return appendCallSetResult(operation, resultPayload, resultTag);
1610     }
1611     JITCompiler::Call callOperation(J_JITOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
1612     {
1613         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1614         return appendCallSetResult(operation, resultPayload, resultTag);
1615     }
1616     JITCompiler::Call callOperation(J_JITOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
1617     {
1618         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1619         return appendCallSetResult(operation, resultPayload, resultTag);
1620     }
1621     JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
1622     {
1623         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
1624         return appendCallSetResult(operation, resultPayload, resultTag);
1625     }
1626     JITCompiler::Call callOperation(J_JITOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1627     {
1628         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1629         return appendCallSetResult(operation, resultPayload, resultTag);
1630     }
1631
1632     JITCompiler::Call callOperation(J_JITOperation_EC operation, GPRReg resultTag, GPRReg resultPayload, JSCell* cell)
1633     {
1634         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1635         return appendCallSetResult(operation, resultPayload, resultTag);
1636     }
1637     JITCompiler::Call callOperation(J_JITOperation_ECZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1638     {
1639         m_jit.setupArgumentsWithExecState(arg1, arg2);
1640         return appendCallSetResult(operation, resultPayload, resultTag);
1641     }
1642     JITCompiler::Call callOperation(J_JITOperation_EJscC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, JSCell* cell)
1643     {
1644         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1645         return appendCallSetResult(operation, resultPayload, resultTag);
1646     }
1647     JITCompiler::Call callOperation(J_JITOperation_EJscCJ operation, GPRReg result, GPRReg arg1, JSCell* cell, GPRReg arg2Tag, GPRReg arg2Payload)
1648     {
1649         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell), EABI_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1650         return appendCallSetResult(operation, result);
1651     }
1652     JITCompiler::Call callOperation(J_JITOperation_ESsiCI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1, const UniquedStringImpl* uid)
1653     {
1654         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1, TrustedImmPtr(uid));
1655         return appendCallSetResult(operation, resultPayload, resultTag);
1656     }
1657     JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
1658     {
1659         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, TrustedImmPtr(uid));
1660         return appendCallSetResult(operation, resultPayload, resultTag);
1661     }
1662     JITCompiler::Call callOperation(J_JITOperation_ESsiJI operation, GPRReg resultTag, GPRReg resultPayload, StructureStubInfo* stubInfo, int32_t arg1Tag, GPRReg arg1Payload, UniquedStringImpl* uid)
1663     {
1664         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(uid));
1665         return appendCallSetResult(operation, resultPayload, resultTag);
1666     }
1667     JITCompiler::Call callOperation(J_JITOperation_EDA operation, GPRReg resultTag, GPRReg resultPayload, FPRReg arg1, GPRReg arg2)
1668     {
1669         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1, arg2);
1670         return appendCallSetResult(operation, resultPayload, resultTag);
1671     }
1672     JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1673     {
1674         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1675         return appendCallSetResult(operation, resultPayload, resultTag);
1676     }
1677     JITCompiler::Call callOperation(J_JITOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, TrustedImm32 arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1678     {
1679         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1680         return appendCallSetResult(operation, resultPayload, resultTag);
1681     }
1682     JITCompiler::Call callOperation(J_JITOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
1683     {
1684         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1685         return appendCallSetResult(operation, resultPayload, resultTag);
1686     }
1687     JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1688     {
1689         m_jit.setupArgumentsWithExecState(arg1);
1690         return appendCallSetResult(operation, resultPayload, resultTag);
1691     }
1692     JITCompiler::Call callOperation(J_JITOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
1693     {
1694         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1695         return appendCallSetResult(operation, resultPayload, resultTag);
1696     }
1697     JITCompiler::Call callOperation(J_JITOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1698     {
1699         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1700         return appendCallSetResult(operation, resultPayload, resultTag);
1701     }
1702     JITCompiler::Call callOperation(J_JITOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
1703     {
1704         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1705         return appendCallSetResult(operation, resultPayload, resultTag);
1706     }
1707
1708     JITCompiler::Call callOperation(P_JITOperation_EJS operation, GPRReg result, JSValueRegs value, size_t index)
1709     {
1710         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG value.payloadGPR(), value.tagGPR(), TrustedImmPtr(index));
1711         return appendCallSetResult(operation, result);
1712     }
1713
1714     JITCompiler::Call callOperation(P_JITOperation_EStJ operation, GPRReg result, Structure* structure, GPRReg arg2Tag, GPRReg arg2Payload)
1715     {
1716         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2Payload, arg2Tag);
1717         return appendCallSetResult(operation, result);
1718     }
1719
1720     JITCompiler::Call callOperation(C_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1721     {
1722         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1723         return appendCallSetResult(operation, result);
1724     }
1725
1726     JITCompiler::Call callOperation(C_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1727     {
1728         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1729         return appendCallSetResult(operation, result);
1730     }
1731
1732     JITCompiler::Call callOperation(C_JITOperation_EJJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1733     {
1734         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1735         return appendCallSetResult(operation, result);
1736     }
1737
1738     JITCompiler::Call callOperation(S_JITOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1739     {
1740         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1741         return appendCallSetResult(operation, result);
1742     }
1743
1744     JITCompiler::Call callOperation(S_JITOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1745     {
1746         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1747         return appendCallSetResult(operation, result);
1748     }
1749     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1750     {
1751         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1752         return appendCallSetResult(operation, resultPayload, resultTag);
1753     }
1754     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
1755     {
1756         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, SH4_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag));
1757         return appendCallSetResult(operation, resultPayload, resultTag);
1758     }
1759     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
1760     {
1761         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), SH4_32BIT_DUMMY_ARG arg2Payload, arg2Tag);
1762         return appendCallSetResult(operation, resultPayload, resultTag);
1763     }
1764     JITCompiler::Call callOperation(J_JITOperation_EJJ operation, JSValueRegs result, JSValueRegs arg1, JSValueRegs arg2)
1765     {
1766         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1.tagGPR(), arg1.payloadGPR(), arg2.tagGPR(), arg2.payloadGPR());
1767     }
1768
1769     JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
1770     {
1771         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
1772         return appendCallSetResult(operation, resultPayload, resultTag);
1773     }
1774     JITCompiler::Call callOperation(J_JITOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Payload)
1775     {
1776         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, MacroAssembler::TrustedImm32(JSValue::CellTag));
1777         return appendCallSetResult(operation, resultPayload, resultTag);
1778     }
1779     JITCompiler::Call callOperation(J_JITOperation_ECJ operation, JSValueRegs result, GPRReg arg1, JSValueRegs arg2)
1780     {
1781         m_jit.setupArgumentsWithExecState(arg1, arg2.payloadGPR(), arg2.tagGPR());
1782         return appendCallSetResult(operation, result.payloadGPR(), result.tagGPR());
1783     }
1784     JITCompiler::Call callOperation(J_JITOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1785     {
1786         m_jit.setupArgumentsWithExecState(arg1, arg2);
1787         return appendCallSetResult(operation, resultPayload, resultTag);
1788     }
1789
1790     JITCompiler::Call callOperation(V_JITOperation_EOZD operation, GPRReg arg1, GPRReg arg2, FPRReg arg3)
1791     {
1792         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3);
1793         return appendCall(operation);
1794     }
1795
1796     JITCompiler::Call callOperation(V_JITOperation_EJ operation, GPRReg arg1Tag, GPRReg arg1Payload)
1797     {
1798         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1799         return appendCall(operation);
1800     }
1801
1802     JITCompiler::Call callOperation(V_JITOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
1803     {
1804         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
1805         return appendCall(operation);
1806     }
1807     JITCompiler::Call callOperation(V_JITOperation_ESsiJJI operation, StructureStubInfo* stubInfo, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Payload, UniquedStringImpl* uid)
1808     {
1809         m_jit.setupArgumentsWithExecState(TrustedImmPtr(stubInfo), arg1Payload, arg1Tag, arg2Payload, TrustedImm32(JSValue::CellTag), TrustedImmPtr(uid));
1810         return appendCall(operation);
1811     }
1812     JITCompiler::Call callOperation(V_JITOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1813     {
1814         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1815         return appendCall(operation);
1816     }
1817
1818     JITCompiler::Call callOperation(V_JITOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1819     {
1820         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1821         return appendCall(operation);
1822     }
1823
1824     JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1825     {
1826         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1827         return appendCall(operation);
1828     }
1829     JITCompiler::Call callOperation(V_JITOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, TrustedImm32 arg3Tag, GPRReg arg3Payload)
1830     {
1831         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG SH4_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1832         return appendCall(operation);
1833     }
1834
1835     JITCompiler::Call callOperation(Z_JITOperation_EJZZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2, unsigned arg3)
1836     {
1837         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG  arg1Payload, arg1Tag, TrustedImm32(arg2), TrustedImm32(arg3));
1838         return appendCallSetResult(operation, result);
1839     }
1840     JITCompiler::Call callOperation(F_JITOperation_EFJZZ operation, GPRReg result, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4)
1841     {
1842         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
1843         return appendCallSetResult(operation, result);
1844     }
1845     JITCompiler::Call callOperation(Z_JITOperation_EJZ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, unsigned arg2)
1846     {
1847         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImm32(arg2));
1848         return appendCallSetResult(operation, result);
1849     }
1850     JITCompiler::Call callOperation(V_JITOperation_EZJZZZ operation, unsigned arg1, GPRReg arg2Tag, GPRReg arg2Payload, unsigned arg3, GPRReg arg4, unsigned arg5)
1851     {
1852         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2Payload, arg2Tag, TrustedImm32(arg3), arg4, TrustedImm32(arg5));
1853         return appendCall(operation);
1854     }
1855     JITCompiler::Call callOperation(V_JITOperation_ECJZC operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, int32_t arg3, GPRReg arg4)
1856     {
1857         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, TrustedImm32(arg3), arg4);
1858         return appendCall(operation);
1859     }
1860     JITCompiler::Call callOperation(V_JITOperation_ECIZCC operation, GPRReg arg1, UniquedStringImpl* identOp2, int32_t op3, GPRReg arg4, GPRReg arg5)
1861     {
1862         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identOp2), TrustedImm32(op3), arg4, arg5);
1863         return appendCall(operation);
1864     }
1865 #undef EABI_32BIT_DUMMY_ARG
1866 #undef SH4_32BIT_DUMMY_ARG
1867     
1868     template<typename FunctionType>
1869     JITCompiler::Call callOperation(
1870         FunctionType operation, JSValueRegs result)
1871     {
1872         return callOperation(operation, result.tagGPR(), result.payloadGPR());
1873     }
1874     template<typename FunctionType, typename ArgumentType1>
1875     JITCompiler::Call callOperation(
1876         FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
1877     {
1878         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
1879     }
1880     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1881     JITCompiler::Call callOperation(
1882         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1883     {
1884         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1885     }
1886     template<
1887         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1888         typename ArgumentType3>
1889     JITCompiler::Call callOperation(
1890         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1891         ArgumentType3 arg3)
1892     {
1893         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1894     }
1895     template<
1896         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1897         typename ArgumentType3, typename ArgumentType4>
1898     JITCompiler::Call callOperation(
1899         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1900         ArgumentType3 arg3, ArgumentType4 arg4)
1901     {
1902         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1903     }
1904     template<
1905         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1906         typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1907     JITCompiler::Call callOperation(
1908         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1909         ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1910     {
1911         return callOperation(
1912             operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1913     }
1914 #endif // USE(JSVALUE32_64)
1915     
1916 #if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS) && !CPU(SH4)
1917     void prepareForExternalCall()
1918     {
1919         // We're about to call out to a "native" helper function. The helper
1920         // function is expected to set topCallFrame itself with the ExecState
1921         // that is passed to it.
1922         //
1923         // We explicitly trash topCallFrame here so that we'll know if some of
1924         // the helper functions are not setting topCallFrame when they should
1925         // be doing so. Note: the previous value in topcallFrame was not valid
1926         // anyway since it was not being updated by JIT'ed code by design.
1927
1928         for (unsigned i = 0; i < sizeof(void*) / 4; i++)
1929             m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.vm()->topCallFrame) + i * 4);
1930     }
1931 #else
1932     void prepareForExternalCall() { }
1933 #endif
1934
1935     // These methods add call instructions, optionally setting results, and optionally rolling back the call frame on an exception.
1936     JITCompiler::Call appendCall(const FunctionPtr& function)
1937     {
1938         prepareForExternalCall();
1939         m_jit.emitStoreCodeOrigin(m_currentNode->origin.semantic);
1940         return m_jit.appendCall(function);
1941     }
1942     JITCompiler::Call appendCallWithCallFrameRollbackOnException(const FunctionPtr& function)
1943     {
1944         JITCompiler::Call call = appendCall(function);
1945         m_jit.exceptionCheckWithCallFrameRollback();
1946         return call;
1947     }
1948     JITCompiler::Call appendCallWithCallFrameRollbackOnExceptionSetResult(const FunctionPtr& function, GPRReg result)
1949     {
1950         JITCompiler::Call call = appendCallWithCallFrameRollbackOnException(function);
1951         if ((result != InvalidGPRReg) && (result != GPRInfo::returnValueGPR))
1952             m_jit.move(GPRInfo::returnValueGPR, result);
1953         return call;
1954     }
1955     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1956     {
1957         JITCompiler::Call call = appendCall(function);
1958         if (result != InvalidGPRReg)
1959             m_jit.move(GPRInfo::returnValueGPR, result);
1960         return call;
1961     }
1962     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
1963     {
1964         JITCompiler::Call call = appendCall(function);
1965         m_jit.setupResults(result1, result2);
1966         return call;
1967     }
1968 #if CPU(X86)
1969     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1970     {
1971         JITCompiler::Call call = appendCall(function);
1972         if (result != InvalidFPRReg) {
1973             m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1974             m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1975         }
1976         return call;
1977     }
1978 #elif CPU(ARM) && !CPU(ARM_HARDFP)
1979     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1980     {
1981         JITCompiler::Call call = appendCall(function);
1982         if (result != InvalidFPRReg)
1983             m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1984         return call;
1985     }
1986 #else // CPU(X86_64) || (CPU(ARM) && CPU(ARM_HARDFP)) || CPU(ARM64) || CPU(MIPS) || CPU(SH4)
1987     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1988     {
1989         JITCompiler::Call call = appendCall(function);
1990         if (result != InvalidFPRReg)
1991             m_jit.moveDouble(FPRInfo::returnValueFPR, result);
1992         return call;
1993     }
1994 #endif
1995     
1996     void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BasicBlock* destination)
1997     {
1998         return addBranch(m_jit.branchDouble(cond, left, right), destination);
1999     }
2000     
2001     void branchDoubleNonZero(FPRReg value, FPRReg scratch, BasicBlock* destination)
2002     {
2003         return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
2004     }
2005     
2006     template<typename T, typename U>
2007     void branch32(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2008     {
2009         return addBranch(m_jit.branch32(cond, left, right), destination);
2010     }
2011     
2012     template<typename T, typename U>
2013     void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2014     {
2015         return addBranch(m_jit.branchTest32(cond, value, mask), destination);
2016     }
2017     
2018     template<typename T>
2019     void branchTest32(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
2020     {
2021         return addBranch(m_jit.branchTest32(cond, value), destination);
2022     }
2023     
2024 #if USE(JSVALUE64)
2025     template<typename T, typename U>
2026     void branch64(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2027     {
2028         return addBranch(m_jit.branch64(cond, left, right), destination);
2029     }
2030 #endif
2031     
2032     template<typename T, typename U>
2033     void branch8(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2034     {
2035         return addBranch(m_jit.branch8(cond, left, right), destination);
2036     }
2037     
2038     template<typename T, typename U>
2039     void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BasicBlock* destination)
2040     {
2041         return addBranch(m_jit.branchPtr(cond, left, right), destination);
2042     }
2043     
2044     template<typename T, typename U>
2045     void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2046     {
2047         return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
2048     }
2049     
2050     template<typename T>
2051     void branchTestPtr(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
2052     {
2053         return addBranch(m_jit.branchTestPtr(cond, value), destination);
2054     }
2055     
2056     template<typename T, typename U>
2057     void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BasicBlock* destination)
2058     {
2059         return addBranch(m_jit.branchTest8(cond, value, mask), destination);
2060     }
2061     
2062     template<typename T>
2063     void branchTest8(JITCompiler::ResultCondition cond, T value, BasicBlock* destination)
2064     {
2065         return addBranch(m_jit.branchTest8(cond, value), destination);
2066     }
2067     
2068     enum FallThroughMode {
2069         AtFallThroughPoint,
2070         ForceJump
2071     };
2072     void jump(BasicBlock* destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
2073     {
2074         if (destination == nextBlock()
2075             && fallThroughMode == AtFallThroughPoint)
2076             return;
2077         addBranch(m_jit.jump(), destination);
2078     }
2079     
2080     void addBranch(const MacroAssembler::Jump& jump, BasicBlock* destination)
2081     {
2082         m_branches.append(BranchRecord(jump, destination));
2083     }
2084     void addBranch(const MacroAssembler::JumpList& jump, BasicBlock* destination);
2085
2086     void linkBranches();
2087
2088     void dump(const char* label = 0);
2089
2090     bool betterUseStrictInt52(Node* node)
2091     {
2092         return !generationInfo(node).isInt52();
2093     }
2094     bool betterUseStrictInt52(Edge edge)
2095     {
2096         return betterUseStrictInt52(edge.node());
2097     }
2098     
2099     bool compare(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_JITOperation_EJJ);
2100     bool compilePeepHoleBranch(Node*, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_JITOperation_EJJ);
2101     void compilePeepHoleInt32Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2102     void compilePeepHoleInt52Branch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2103     void compilePeepHoleBooleanBranch(Node*, Node* branchNode, JITCompiler::RelationalCondition);
2104     void compilePeepHoleDoubleBranch(Node*, Node* branchNode, JITCompiler::DoubleCondition);
2105     void compilePeepHoleObjectEquality(Node*, Node* branchNode);
2106     void compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode);
2107     void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode);
2108     void compileObjectEquality(Node*);
2109     void compileObjectStrictEquality(Edge objectChild, Edge otherChild);
2110     void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
2111     void compileObjectOrOtherLogicalNot(Edge value);
2112     void compileLogicalNot(Node*);
2113     void compileStringEquality(
2114         Node*, GPRReg leftGPR, GPRReg rightGPR, GPRReg lengthGPR,
2115         GPRReg leftTempGPR, GPRReg rightTempGPR, GPRReg leftTemp2GPR,
2116         GPRReg rightTemp2GPR, JITCompiler::JumpList fastTrue,
2117         JITCompiler::JumpList fastSlow);
2118     void compileStringEquality(Node*);
2119     void compileStringIdentEquality(Node*);
2120     void compileStringToUntypedEquality(Node*, Edge stringEdge, Edge untypedEdge);
2121     void compileStringIdentToNotStringVarEquality(Node*, Edge stringEdge, Edge notStringVarEdge);
2122     void compileStringZeroLength(Node*);
2123     void compileMiscStrictEq(Node*);
2124
2125     template<typename Functor>
2126     void extractStringImplFromBinarySymbols(Edge leftSymbolEdge, Edge rightSymbolEdge, const Functor&);
2127     void compileSymbolEquality(Node*);
2128     void compilePeepHoleSymbolEquality(Node*, Node* branchNode);
2129
2130     void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
2131     void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
2132     void emitBranch(Node*);
2133     
2134     struct StringSwitchCase {
2135         StringSwitchCase() { }
2136         
2137         StringSwitchCase(StringImpl* string, BasicBlock* target)
2138             : string(string)
2139             , target(target)
2140         {
2141         }
2142         
2143         bool operator<(const StringSwitchCase& other) const
2144         {
2145             return stringLessThan(*string, *other.string);
2146         }
2147         
2148         StringImpl* string;
2149         BasicBlock* target;
2150     };
2151     
2152     void emitSwitchIntJump(SwitchData*, GPRReg value, GPRReg scratch);
2153     void emitSwitchImm(Node*, SwitchData*);
2154     void emitSwitchCharStringJump(SwitchData*, GPRReg value, GPRReg scratch);
2155     void emitSwitchChar(Node*, SwitchData*);
2156     void emitBinarySwitchStringRecurse(
2157         SwitchData*, const Vector<StringSwitchCase>&, unsigned numChecked,
2158         unsigned begin, unsigned end, GPRReg buffer, GPRReg length, GPRReg temp,
2159         unsigned alreadyCheckedLength, bool checkedExactLength);
2160     void emitSwitchStringOnString(SwitchData*, GPRReg string);
2161     void emitSwitchString(Node*, SwitchData*);
2162     void emitSwitch(Node*);
2163     
2164     void compileToStringOrCallStringConstructorOnCell(Node*);
2165     void compileNewStringObject(Node*);
2166     
2167     void compileNewTypedArray(Node*);
2168     
2169     void compileInt32Compare(Node*, MacroAssembler::RelationalCondition);
2170     void compileInt52Compare(Node*, MacroAssembler::RelationalCondition);
2171     void compileBooleanCompare(Node*, MacroAssembler::RelationalCondition);
2172     void compileDoubleCompare(Node*, MacroAssembler::DoubleCondition);
2173     
2174     bool compileStrictEq(Node*);
2175     
2176     void compileAllocatePropertyStorage(Node*);
2177     void compileReallocatePropertyStorage(Node*);
2178     void compileGetButterfly(Node*);
2179     
2180 #if USE(JSVALUE32_64)
2181     template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
2182     void compileContiguousPutByVal(Node*, BaseOperandType&, PropertyOperandType&, ValueOperandType&, GPRReg valuePayloadReg, TagType valueTag);
2183 #endif
2184     void compileDoublePutByVal(Node*, SpeculateCellOperand& base, SpeculateStrictInt32Operand& property);
2185     bool putByValWillNeedExtraRegister(ArrayMode arrayMode)
2186     {
2187         return arrayMode.mayStoreToHole();
2188     }
2189     GPRReg temporaryRegisterForPutByVal(GPRTemporary&, ArrayMode);
2190     GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node* node)
2191     {
2192         return temporaryRegisterForPutByVal(temporary, node->arrayMode());
2193     }
2194     
2195     void compileGetCharCodeAt(Node*);
2196     void compileGetByValOnString(Node*);
2197     void compileFromCharCode(Node*); 
2198
2199     void compileGetByValOnDirectArguments(Node*);
2200     void compileGetByValOnScopedArguments(Node*);
2201     
2202     void compileGetScope(Node*);
2203     void compileSkipScope(Node*);
2204
2205     void compileGetArrayLength(Node*);
2206
2207     void compileCheckIdent(Node*);
2208     
2209     void compileValueRep(Node*);
2210     void compileDoubleRep(Node*);
2211     
2212     void compileValueToInt32(Node*);
2213     void compileUInt32ToNumber(Node*);
2214     void compileDoubleAsInt32(Node*);
2215     void compileValueAdd(Node*);
2216     void compileArithAdd(Node*);
2217     void compileMakeRope(Node*);
2218     void compileArithClz32(Node*);
2219     void compileArithSub(Node*);
2220     void compileArithNegate(Node*);
2221     void compileArithMul(Node*);
2222     void compileArithDiv(Node*);
2223     void compileArithMod(Node*);
2224     void compileArithPow(Node*);
2225     void compileArithRound(Node*);
2226     void compileArithSqrt(Node*);
2227     void compileArithLog(Node*);
2228     void compileConstantStoragePointer(Node*);
2229     void compileGetIndexedPropertyStorage(Node*);
2230     JITCompiler::Jump jumpForTypedArrayOutOfBounds(Node*, GPRReg baseGPR, GPRReg indexGPR);
2231     void emitTypedArrayBoundsCheck(Node*, GPRReg baseGPR, GPRReg indexGPR);
2232     void compileGetTypedArrayByteOffset(Node*);
2233     void compileGetByValOnIntTypedArray(Node*, TypedArrayType);
2234     void compilePutByValForIntTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
2235     void compileGetByValOnFloatTypedArray(Node*, TypedArrayType);
2236     void compilePutByValForFloatTypedArray(GPRReg base, GPRReg property, Node*, TypedArrayType);
2237     template <typename ClassType> void compileNewFunctionCommon(GPRReg, Structure*, GPRReg, GPRReg, GPRReg, MacroAssembler::JumpList&, size_t, FunctionExecutable*, ptrdiff_t, ptrdiff_t, ptrdiff_t);
2238     void compileNewFunction(Node*);
2239     void compileForwardVarargs(Node*);
2240     void compileCreateActivation(Node*);
2241     void compileCreateDirectArguments(Node*);
2242     void compileGetFromArguments(Node*);
2243     void compilePutToArguments(Node*);
2244     void compileCreateScopedArguments(Node*);
2245     void compileCreateClonedArguments(Node*);
2246     void compileCopyRest(Node*);
2247     void compileGetRestLength(Node*);
2248     void compileNotifyWrite(Node*);
2249     bool compileRegExpExec(Node*);
2250     void compileIsObjectOrNull(Node*);
2251     void compileIsFunction(Node*);
2252     void compileTypeOf(Node*);
2253     void compileCheckStructure(Node*, GPRReg cellGPR, GPRReg tempGPR);
2254     void compileCheckStructure(Node*);
2255     void compilePutAccessorById(Node*);
2256     void compilePutGetterSetterById(Node*);
2257     void compilePutAccessorByVal(Node*);
2258     
2259     void moveTrueTo(GPRReg);
2260     void moveFalseTo(GPRReg);
2261     void blessBoolean(GPRReg);
2262     
2263     // size can be an immediate or a register, and must be in bytes. If size is a register,
2264     // it must be a different register than resultGPR. Emits code that place a pointer to
2265     // the end of the allocation. The returned jump is the jump to the slow path.
2266     template<typename SizeType>
2267     MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
2268     {
2269         CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
2270
2271         // It's invalid to allocate zero bytes in CopiedSpace. 
2272 #ifndef NDEBUG
2273         m_jit.move(size, resultGPR);
2274         MacroAssembler::Jump nonZeroSize = m_jit.branchTest32(MacroAssembler::NonZero, resultGPR);
2275         m_jit.abortWithReason(DFGBasicStorageAllocatorZeroSize);
2276         nonZeroSize.link(&m_jit);
2277 #endif
2278
2279         m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
2280         MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
2281         m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
2282         m_jit.negPtr(resultGPR);
2283         m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
2284         
2285         return slowPath;
2286     }
2287
2288     // Allocator for a cell of a specific size.
2289     template <typename StructureType> // StructureType can be GPR or ImmPtr.
2290     void emitAllocateJSCell(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2291         GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2292     {
2293         if (Options::forceGCSlowPaths())
2294             slowPath.append(m_jit.jump());
2295         else {
2296             m_jit.loadPtr(MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()), resultGPR);
2297             slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2298         }
2299         
2300         // The object is half-allocated: we have what we know is a fresh object, but
2301         // it's still on the GC's free list.
2302         m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
2303         m_jit.storePtr(scratchGPR, MacroAssembler::Address(allocatorGPR, MarkedAllocator::offsetOfFreeListHead()));
2304
2305         // Initialize the object's Structure.
2306         m_jit.emitStoreStructureWithTypeInfo(structure, resultGPR, scratchGPR);
2307     }
2308
2309     // Allocator for an object of a specific size.
2310     template <typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2311     void emitAllocateJSObject(GPRReg resultGPR, GPRReg allocatorGPR, StructureType structure,
2312         StorageType storage, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2313     {
2314         emitAllocateJSCell(resultGPR, allocatorGPR, structure, scratchGPR, slowPath);
2315         
2316         // Initialize the object's property storage pointer.
2317         m_jit.storePtr(storage, MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
2318     }
2319
2320     template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2321     void emitAllocateJSObjectWithKnownSize(
2322         GPRReg resultGPR, StructureType structure, StorageType storage, GPRReg scratchGPR1,
2323         GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath, size_t size)
2324     {
2325         MarkedAllocator* allocator = &m_jit.vm()->heap.allocatorForObjectOfType<ClassType>(size);
2326         m_jit.move(TrustedImmPtr(allocator), scratchGPR1);
2327         emitAllocateJSObject(resultGPR, scratchGPR1, structure, storage, scratchGPR2, slowPath);
2328     }
2329
2330     // Convenience allocator for a built-in object.
2331     template <typename ClassType, typename StructureType, typename StorageType> // StructureType and StorageType can be GPR or ImmPtr.
2332     void emitAllocateJSObject(GPRReg resultGPR, StructureType structure, StorageType storage,
2333         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2334     {
2335         emitAllocateJSObjectWithKnownSize<ClassType>(
2336             resultGPR, structure, storage, scratchGPR1, scratchGPR2, slowPath,
2337             ClassType::allocationSize(0));
2338     }
2339
2340     template <typename ClassType, typename StructureType> // StructureType and StorageType can be GPR or ImmPtr.
2341     void emitAllocateVariableSizedJSObject(GPRReg resultGPR, StructureType structure, GPRReg allocationSize, GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2342     {
2343         static_assert(!(MarkedSpace::preciseStep & (MarkedSpace::preciseStep - 1)), "MarkedSpace::preciseStep must be a power of two.");
2344         static_assert(!(MarkedSpace::impreciseStep & (MarkedSpace::impreciseStep - 1)), "MarkedSpace::impreciseStep must be a power of two.");
2345
2346         MarkedSpace::Subspace& subspace = m_jit.vm()->heap.subspaceForObjectOfType<ClassType>();
2347         m_jit.add32(TrustedImm32(MarkedSpace::preciseStep - 1), allocationSize);
2348         MacroAssembler::Jump notSmall = m_jit.branch32(MacroAssembler::AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::preciseCutoff));
2349         m_jit.rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::preciseStep)), scratchGPR1);
2350         m_jit.mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1);
2351         m_jit.addPtr(MacroAssembler::TrustedImmPtr(&subspace.preciseAllocators[0]), scratchGPR1);
2352
2353         MacroAssembler::Jump selectedSmallSpace = m_jit.jump();
2354         notSmall.link(&m_jit);
2355         slowPath.append(m_jit.branch32(MacroAssembler::AboveOrEqual, allocationSize, TrustedImm32(MarkedSpace::impreciseCutoff)));
2356         m_jit.rshift32(allocationSize, TrustedImm32(getLSBSet(MarkedSpace::impreciseStep)), scratchGPR1);
2357         m_jit.mul32(TrustedImm32(sizeof(MarkedAllocator)), scratchGPR1, scratchGPR1);
2358         m_jit.addPtr(MacroAssembler::TrustedImmPtr(&subspace.impreciseAllocators[0]), scratchGPR1);
2359
2360         selectedSmallSpace.link(&m_jit);
2361
2362         emitAllocateJSObject(resultGPR, scratchGPR1, structure, TrustedImmPtr(0), scratchGPR2, slowPath);
2363     }
2364
2365     template <typename T>
2366     void emitAllocateDestructibleObject(GPRReg resultGPR, Structure* structure, 
2367         GPRReg scratchGPR1, GPRReg scratchGPR2, MacroAssembler::JumpList& slowPath)
2368     {
2369         emitAllocateJSObject<T>(resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR1, scratchGPR2, slowPath);
2370         m_jit.storePtr(TrustedImmPtr(structure->classInfo()), MacroAssembler::Address(resultGPR, JSDestructibleObject::classInfoOffset()));
2371     }
2372
2373     void emitAllocateJSArray(GPRReg resultGPR, Structure*, GPRReg storageGPR, unsigned numElements);
2374     
2375     void emitGetLength(InlineCallFrame*, GPRReg lengthGPR, bool includeThis = false);
2376     void emitGetLength(CodeOrigin, GPRReg lengthGPR, bool includeThis = false);
2377     void emitGetCallee(CodeOrigin, GPRReg calleeGPR);
2378     void emitGetArgumentStart(CodeOrigin, GPRReg startGPR);
2379     
2380     // Generate an OSR exit fuzz check. Returns Jump() if OSR exit fuzz is not enabled, or if
2381     // it's in training mode.
2382     MacroAssembler::Jump emitOSRExitFuzzCheck();
2383     
2384     // Add a speculation check.
2385     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail);
2386     void speculationCheck(ExitKind, JSValueSource, Node*, const MacroAssembler::JumpList& jumpsToFail);
2387
2388     // Add a speculation check without additional recovery, and with a promise to supply a jump later.
2389     OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Node*);
2390     OSRExitJumpPlaceholder speculationCheck(ExitKind, JSValueSource, Edge);
2391     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
2392     void speculationCheck(ExitKind, JSValueSource, Edge, const MacroAssembler::JumpList& jumpsToFail);
2393     // Add a speculation check with additional recovery.
2394     void speculationCheck(ExitKind, JSValueSource, Node*, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2395     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2396     
2397     void emitInvalidationPoint(Node*);
2398     
2399     // Called when we statically determine that a speculation will fail.
2400     void terminateSpeculativeExecution(ExitKind, JSValueRegs, Node*);
2401     void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2402     
2403     // Helpers for performing type checks on an edge stored in the given registers.
2404     bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
2405     void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
2406     
2407     void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType);
2408     void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType);
2409     
2410     void speculateInt32(Edge);
2411 #if USE(JSVALUE64)
2412     void convertMachineInt(Edge, GPRReg resultGPR);
2413     void speculateMachineInt(Edge);
2414     void speculateDoubleRepMachineInt(Edge);
2415 #endif // USE(JSVALUE64)
2416     void speculateNumber(Edge);
2417     void speculateRealNumber(Edge);
2418     void speculateDoubleRepReal(Edge);
2419     void speculateBoolean(Edge);
2420     void speculateCell(Edge);
2421     void speculateCellOrOther(Edge);
2422     void speculateObject(Edge);
2423     void speculateFunction(Edge);
2424     void speculateFinalObject(Edge);
2425     void speculateObjectOrOther(Edge);
2426     void speculateString(Edge edge, GPRReg cell);
2427     void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage);
2428     void speculateStringIdent(Edge edge, GPRReg string);
2429     void speculateStringIdent(Edge);
2430     void speculateString(Edge);
2431     void speculateNotStringVar(Edge);
2432     template<typename StructureLocationType>
2433     void speculateStringObjectForStructure(Edge, StructureLocationType);
2434     void speculateStringObject(Edge, GPRReg);
2435     void speculateStringObject(Edge);
2436     void speculateStringOrStringObject(Edge);
2437     void speculateSymbol(Edge, GPRReg cell);
2438     void speculateSymbol(Edge);
2439     void speculateNotCell(Edge);
2440     void speculateOther(Edge);
2441     void speculateMisc(Edge, JSValueRegs);
2442     void speculateMisc(Edge);
2443     void speculate(Node*, Edge);
2444     
2445     JITCompiler::Jump jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode, IndexingType);
2446     JITCompiler::JumpList jumpSlowForUnwantedArrayMode(GPRReg tempWithIndexingTypeReg, ArrayMode);
2447     void checkArray(Node*);
2448     void arrayify(Node*, GPRReg baseReg, GPRReg propertyReg);
2449     void arrayify(Node*);
2450     
2451     template<bool strict>
2452     GPRReg fillSpeculateInt32Internal(Edge, DataFormat& returnFormat);
2453     
2454     // It is possible, during speculative generation, to reach a situation in which we
2455     // can statically determine a speculation will fail (for example, when two nodes
2456     // will make conflicting speculations about the same operand). In such cases this
2457     // flag is cleared, indicating no further code generation should take place.
2458     bool m_compileOkay;
2459     
2460     void recordSetLocal(
2461         VirtualRegister bytecodeReg, VirtualRegister machineReg, DataFormat format)
2462     {
2463         m_stream->appendAndLog(VariableEvent::setLocal(bytecodeReg, machineReg, format));
2464     }
2465     
2466     void recordSetLocal(DataFormat format)
2467     {
2468         VariableAccessData* variable = m_currentNode->variableAccessData();
2469         recordSetLocal(variable->local(), variable->machineLocal(), format);
2470     }
2471
2472     GenerationInfo& generationInfoFromVirtualRegister(VirtualRegister virtualRegister)
2473     {
2474         return m_generationInfo[virtualRegister.toLocal()];
2475     }
2476     
2477     GenerationInfo& generationInfo(Node* node)
2478     {
2479         return generationInfoFromVirtualRegister(node->virtualRegister());
2480     }
2481     
2482     GenerationInfo& generationInfo(Edge edge)
2483     {
2484         return generationInfo(edge.node());
2485     }
2486
2487     // The JIT, while also provides MacroAssembler functionality.
2488     JITCompiler& m_jit;
2489
2490     // The current node being generated.
2491     BasicBlock* m_block;
2492     Node* m_currentNode;
2493     NodeType m_lastGeneratedNode;
2494     unsigned m_indexInBlock;
2495     // Virtual and physical register maps.
2496     Vector<GenerationInfo, 32> m_generationInfo;
2497     RegisterBank<GPRInfo> m_gprs;
2498     RegisterBank<FPRInfo> m_fprs;
2499
2500     Vector<MacroAssembler::Label> m_osrEntryHeads;
2501     
2502     struct BranchRecord {
2503         BranchRecord(MacroAssembler::Jump jump, BasicBlock* destination)
2504             : jump(jump)
2505             , destination(destination)
2506         {
2507         }
2508
2509         MacroAssembler::Jump jump;
2510         BasicBlock* destination;
2511     };
2512     Vector<BranchRecord, 8> m_branches;
2513
2514     NodeOrigin m_origin;
2515     
2516     InPlaceAbstractState m_state;
2517     AbstractInterpreter<InPlaceAbstractState> m_interpreter;
2518     
2519     VariableEventStream* m_stream;
2520     MinifiedGraph* m_minifiedGraph;
2521     
2522     Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators;
2523     Vector<SilentRegisterSavePlan> m_plans;
2524     unsigned m_outOfLineStreamIndex { UINT_MAX };
2525 };
2526
2527
2528 // === Operand types ===
2529 //
2530 // These classes are used to lock the operands to a node into machine
2531 // registers. These classes implement of pattern of locking a value
2532 // into register at the point of construction only if it is already in
2533 // registers, and otherwise loading it lazily at the point it is first
2534 // used. We do so in order to attempt to avoid spilling one operand
2535 // in order to make space available for another.
2536
2537 class JSValueOperand {
2538 public:
2539     explicit JSValueOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2540         : m_jit(jit)
2541         , m_edge(edge)
2542 #if USE(JSVALUE64)
2543         , m_gprOrInvalid(InvalidGPRReg)
2544 #elif USE(JSVALUE32_64)
2545         , m_isDouble(false)
2546 #endif
2547     {
2548         ASSERT(m_jit);
2549         if (!edge)
2550             return;
2551         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == UntypedUse);
2552 #if USE(JSVALUE64)
2553         if (jit->isFilled(node()))
2554             gpr();
2555 #elif USE(JSVALUE32_64)
2556         m_register.pair.tagGPR = InvalidGPRReg;
2557         m_register.pair.payloadGPR = InvalidGPRReg;
2558         if (jit->isFilled(node()))
2559             fill();
2560 #endif
2561     }
2562
2563     explicit JSValueOperand(JSValueOperand&& other)
2564         : m_jit(other.m_jit)
2565         , m_edge(other.m_edge)
2566     {
2567 #if USE(JSVALUE64)
2568         m_gprOrInvalid = other.m_gprOrInvalid;
2569 #elif USE(JSVALUE32_64)
2570         m_register.pair.tagGPR = InvalidGPRReg;
2571         m_register.pair.payloadGPR = InvalidGPRReg;
2572         m_isDouble = other.m_isDouble;
2573
2574         if (m_edge) {
2575             if (m_isDouble)
2576                 m_register.fpr = other.m_register.fpr;
2577             else
2578                 m_register.pair = other.m_register.pair;
2579         }
2580 #endif
2581         other.m_edge = Edge();
2582 #if USE(JSVALUE64)
2583         other.m_gprOrInvalid = InvalidGPRReg;
2584 #elif USE(JSVALUE32_64)
2585         other.m_isDouble = false;
2586 #endif
2587     }
2588
2589     ~JSValueOperand()
2590     {
2591         if (!m_edge)
2592             return;
2593 #if USE(JSVALUE64)
2594         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2595         m_jit->unlock(m_gprOrInvalid);
2596 #elif USE(JSVALUE32_64)
2597         if (m_isDouble) {
2598             ASSERT(m_register.fpr != InvalidFPRReg);
2599             m_jit->unlock(m_register.fpr);
2600         } else {
2601             ASSERT(m_register.pair.tagGPR != InvalidGPRReg && m_register.pair.payloadGPR != InvalidGPRReg);
2602             m_jit->unlock(m_register.pair.tagGPR);
2603             m_jit->unlock(m_register.pair.payloadGPR);
2604         }
2605 #endif
2606     }
2607     
2608     Edge edge() const
2609     {
2610         return m_edge;
2611     }
2612
2613     Node* node() const
2614     {
2615         return edge().node();
2616     }
2617
2618 #if USE(JSVALUE64)
2619     GPRReg gpr()
2620     {
2621         if (m_gprOrInvalid == InvalidGPRReg)
2622             m_gprOrInvalid = m_jit->fillJSValue(m_edge);
2623         return m_gprOrInvalid;
2624     }
2625     JSValueRegs jsValueRegs()
2626     {
2627         return JSValueRegs(gpr());
2628     }
2629 #elif USE(JSVALUE32_64)
2630     bool isDouble() { return m_isDouble; }
2631
2632     void fill()
2633     {
2634         if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
2635             m_isDouble = !m_jit->fillJSValue(m_edge, m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
2636     }
2637
2638     GPRReg tagGPR()
2639     {
2640         fill();
2641         ASSERT(!m_isDouble);
2642         return m_register.pair.tagGPR;
2643     } 
2644
2645     GPRReg payloadGPR()
2646     {
2647         fill();
2648         ASSERT(!m_isDouble);
2649         return m_register.pair.payloadGPR;
2650     }
2651     
2652     JSValueRegs jsValueRegs()
2653     {
2654         return JSValueRegs(tagGPR(), payloadGPR());
2655     }
2656
2657     GPRReg gpr(WhichValueWord which)
2658     {
2659         return jsValueRegs().gpr(which);
2660     }
2661
2662     FPRReg fpr()
2663     {
2664         fill();
2665         ASSERT(m_isDouble);
2666         return m_register.fpr;
2667     }
2668 #endif
2669
2670     void use()
2671     {
2672         m_jit->use(node());
2673     }
2674
2675 private:
2676     SpeculativeJIT* m_jit;
2677     Edge m_edge;
2678 #if USE(JSVALUE64)
2679     GPRReg m_gprOrInvalid;
2680 #elif USE(JSVALUE32_64)
2681     union {
2682         struct {
2683             GPRReg tagGPR;
2684             GPRReg payloadGPR;
2685         } pair;
2686         FPRReg fpr;
2687     } m_register;
2688     bool m_isDouble;
2689 #endif
2690 };
2691
2692 class StorageOperand {
2693 public:
2694     explicit StorageOperand(SpeculativeJIT* jit, Edge edge)
2695         : m_jit(jit)
2696         , m_edge(edge)
2697         , m_gprOrInvalid(InvalidGPRReg)
2698     {
2699         ASSERT(m_jit);
2700         ASSERT(edge.useKind() == UntypedUse || edge.useKind() == KnownCellUse);
2701         if (jit->isFilled(node()))
2702             gpr();
2703     }
2704     
2705     ~StorageOperand()
2706     {
2707         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2708         m_jit->unlock(m_gprOrInvalid);
2709     }
2710     
2711     Edge edge() const
2712     {
2713         return m_edge;
2714     }
2715     
2716     Node* node() const
2717     {
2718         return edge().node();
2719     }
2720     
2721     GPRReg gpr()
2722     {
2723         if (m_gprOrInvalid == InvalidGPRReg)
2724             m_gprOrInvalid = m_jit->fillStorage(edge());
2725         return m_gprOrInvalid;
2726     }
2727     
2728     void use()
2729     {
2730         m_jit->use(node());
2731     }
2732     
2733 private:
2734     SpeculativeJIT* m_jit;
2735     Edge m_edge;
2736     GPRReg m_gprOrInvalid;
2737 };
2738
2739
2740 // === Temporaries ===
2741 //
2742 // These classes are used to allocate temporary registers.
2743 // A mechanism is provided to attempt to reuse the registers
2744 // currently allocated to child nodes whose value is consumed
2745 // by, and not live after, this operation.
2746
2747 enum ReuseTag { Reuse };
2748
2749 class GPRTemporary {
2750 public:
2751     GPRTemporary();
2752     GPRTemporary(SpeculativeJIT*);
2753     GPRTemporary(SpeculativeJIT*, GPRReg specific);
2754     template<typename T>
2755     GPRTemporary(SpeculativeJIT* jit, ReuseTag, T& operand)
2756         : m_jit(jit)
2757         , m_gpr(InvalidGPRReg)
2758     {
2759         if (m_jit->canReuse(operand.node()))
2760             m_gpr = m_jit->reuse(operand.gpr());
2761         else
2762             m_gpr = m_jit->allocate();
2763     }
2764     template<typename T1, typename T2>
2765     GPRTemporary(SpeculativeJIT* jit, ReuseTag, T1& op1, T2& op2)
2766         : m_jit(jit)
2767         , m_gpr(InvalidGPRReg)
2768     {
2769         if (m_jit->canReuse(op1.node()))
2770             m_gpr = m_jit->reuse(op1.gpr());
2771         else if (m_jit->canReuse(op2.node()))
2772             m_gpr = m_jit->reuse(op2.gpr());
2773         else if (m_jit->canReuse(op1.node(), op2.node()) && op1.gpr() == op2.gpr())
2774             m_gpr = m_jit->reuse(op1.gpr());
2775         else
2776             m_gpr = m_jit->allocate();
2777     }
2778 #if USE(JSVALUE32_64)
2779     GPRTemporary(SpeculativeJIT*, ReuseTag, JSValueOperand&, WhichValueWord);
2780 #endif
2781
2782     void adopt(GPRTemporary&);
2783
2784     ~GPRTemporary()
2785     {
2786         if (m_jit && m_gpr != InvalidGPRReg)
2787             m_jit->unlock(gpr());
2788     }
2789
2790     GPRReg gpr()
2791     {
2792         return m_gpr;
2793     }
2794
2795 private:
2796     SpeculativeJIT* m_jit;
2797     GPRReg m_gpr;
2798 };
2799
2800 class JSValueRegsTemporary {
2801 public:
2802     JSValueRegsTemporary();
2803     JSValueRegsTemporary(SpeculativeJIT*);
2804     ~JSValueRegsTemporary();
2805     
2806     JSValueRegs regs();
2807
2808 private:
2809 #if USE(JSVALUE64)
2810     GPRTemporary m_gpr;
2811 #else
2812     GPRTemporary m_payloadGPR;
2813     GPRTemporary m_tagGPR;
2814 #endif
2815 };
2816
2817 class FPRTemporary {
2818 public:
2819     FPRTemporary(SpeculativeJIT*);
2820     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2821     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2822 #if USE(JSVALUE32_64)
2823     FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2824 #endif
2825
2826     ~FPRTemporary()
2827     {
2828         m_jit->unlock(fpr());
2829     }
2830
2831     FPRReg fpr() const
2832     {
2833         ASSERT(m_fpr != InvalidFPRReg);
2834         return m_fpr;
2835     }
2836
2837 protected:
2838     FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2839         : m_jit(jit)
2840         , m_fpr(lockedFPR)
2841     {
2842     }
2843
2844 private:
2845     SpeculativeJIT* m_jit;
2846     FPRReg m_fpr;
2847 };
2848
2849
2850 // === Results ===
2851 //
2852 // These classes lock the result of a call to a C++ helper function.
2853
2854 class GPRFlushedCallResult : public GPRTemporary {
2855 public:
2856     GPRFlushedCallResult(SpeculativeJIT* jit)
2857         : GPRTemporary(jit, GPRInfo::returnValueGPR)
2858     {
2859     }
2860 };
2861
2862 #if USE(JSVALUE32_64)
2863 class GPRFlushedCallResult2 : public GPRTemporary {
2864 public:
2865     GPRFlushedCallResult2(SpeculativeJIT* jit)
2866         : GPRTemporary(jit, GPRInfo::returnValueGPR2)
2867     {
2868     }
2869 };
2870 #endif
2871
2872 class FPRResult : public FPRTemporary {
2873 public:
2874     FPRResult(SpeculativeJIT* jit)
2875         : FPRTemporary(jit, lockedResult(jit))
2876     {
2877     }
2878
2879 private:
2880     static FPRReg lockedResult(SpeculativeJIT* jit)
2881     {
2882         jit->lock(FPRInfo::returnValueFPR);
2883         return FPRInfo::returnValueFPR;
2884     }
2885 };
2886
2887
2888 // === Speculative Operand types ===
2889 //
2890 // SpeculateInt32Operand, SpeculateStrictInt32Operand and SpeculateCellOperand.
2891 //
2892 // These are used to lock the operands to a node into machine registers within the
2893 // SpeculativeJIT. The classes operate like those above, however these will
2894 // perform a speculative check for a more restrictive type than we can statically
2895 // determine the operand to have. If the operand does not have the requested type,
2896 // a bail-out to the non-speculative path will be taken.
2897
2898 class SpeculateInt32Operand {
2899 public:
2900     explicit SpeculateInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2901         : m_jit(jit)
2902         , m_edge(edge)
2903         , m_gprOrInvalid(InvalidGPRReg)
2904 #ifndef NDEBUG
2905         , m_format(DataFormatNone)
2906 #endif
2907     {
2908         ASSERT(m_jit);
2909         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2910         if (jit->isFilled(node()))
2911             gpr();
2912     }
2913
2914     ~SpeculateInt32Operand()
2915     {
2916         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2917         m_jit->unlock(m_gprOrInvalid);
2918     }
2919     
2920     Edge edge() const
2921     {
2922         return m_edge;
2923     }
2924
2925     Node* node() const
2926     {
2927         return edge().node();
2928     }
2929
2930     DataFormat format()
2931     {
2932         gpr(); // m_format is set when m_gpr is locked.
2933         ASSERT(m_format == DataFormatInt32 || m_format == DataFormatJSInt32);
2934         return m_format;
2935     }
2936
2937     GPRReg gpr()
2938     {
2939         if (m_gprOrInvalid == InvalidGPRReg)
2940             m_gprOrInvalid = m_jit->fillSpeculateInt32(edge(), m_format);
2941         return m_gprOrInvalid;
2942     }
2943     
2944     void use()
2945     {
2946         m_jit->use(node());
2947     }
2948
2949 private:
2950     SpeculativeJIT* m_jit;
2951     Edge m_edge;
2952     GPRReg m_gprOrInvalid;
2953     DataFormat m_format;
2954 };
2955
2956 class SpeculateStrictInt32Operand {
2957 public:
2958     explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
2959         : m_jit(jit)
2960         , m_edge(edge)
2961         , m_gprOrInvalid(InvalidGPRReg)
2962     {
2963         ASSERT(m_jit);
2964         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || (edge.useKind() == Int32Use || edge.useKind() == KnownInt32Use));
2965         if (jit->isFilled(node()))
2966             gpr();
2967     }
2968
2969     ~SpeculateStrictInt32Operand()
2970     {
2971         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2972         m_jit->unlock(m_gprOrInvalid);
2973     }
2974     
2975     Edge edge() const
2976     {
2977         return m_edge;
2978     }
2979
2980     Node* node() const
2981     {
2982         return edge().node();
2983     }
2984
2985     GPRReg gpr()
2986     {
2987         if (m_gprOrInvalid == InvalidGPRReg)
2988             m_gprOrInvalid = m_jit->fillSpeculateInt32Strict(edge());
2989         return m_gprOrInvalid;
2990     }
2991     
2992     void use()
2993     {
2994         m_jit->use(node());
2995     }
2996
2997 private:
2998     SpeculativeJIT* m_jit;
2999     Edge m_edge;
3000     GPRReg m_gprOrInvalid;
3001 };
3002
3003 // Gives you a canonical Int52 (i.e. it's left-shifted by 16, low bits zero).
3004 class SpeculateInt52Operand {
3005 public:
3006     explicit SpeculateInt52Operand(SpeculativeJIT* jit, Edge edge)
3007         : m_jit(jit)
3008         , m_edge(edge)
3009         , m_gprOrInvalid(InvalidGPRReg)
3010     {
3011         RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3012         if (jit->isFilled(node()))
3013             gpr();
3014     }
3015     
3016     ~SpeculateInt52Operand()
3017     {
3018         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3019         m_jit->unlock(m_gprOrInvalid);
3020     }
3021     
3022     Edge edge() const
3023     {
3024         return m_edge;
3025     }
3026     
3027     Node* node() const
3028     {
3029         return edge().node();
3030     }
3031     
3032     GPRReg gpr()
3033     {
3034         if (m_gprOrInvalid == InvalidGPRReg)
3035             m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatInt52);
3036         return m_gprOrInvalid;
3037     }
3038     
3039     void use()
3040     {
3041         m_jit->use(node());
3042     }
3043     
3044 private:
3045     SpeculativeJIT* m_jit;
3046     Edge m_edge;
3047     GPRReg m_gprOrInvalid;
3048 };
3049
3050 // Gives you a strict Int52 (i.e. the payload is in the low 48 bits, high 16 bits are sign-extended).
3051 class SpeculateStrictInt52Operand {
3052 public:
3053     explicit SpeculateStrictInt52Operand(SpeculativeJIT* jit, Edge edge)
3054         : m_jit(jit)
3055         , m_edge(edge)
3056         , m_gprOrInvalid(InvalidGPRReg)
3057     {
3058         RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3059         if (jit->isFilled(node()))
3060             gpr();
3061     }
3062     
3063     ~SpeculateStrictInt52Operand()
3064     {
3065         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3066         m_jit->unlock(m_gprOrInvalid);
3067     }
3068     
3069     Edge edge() const
3070     {
3071         return m_edge;
3072     }
3073     
3074     Node* node() const
3075     {
3076         return edge().node();
3077     }
3078     
3079     GPRReg gpr()
3080     {
3081         if (m_gprOrInvalid == InvalidGPRReg)
3082             m_gprOrInvalid = m_jit->fillSpeculateInt52(edge(), DataFormatStrictInt52);
3083         return m_gprOrInvalid;
3084     }
3085     
3086     void use()
3087     {
3088         m_jit->use(node());
3089     }
3090     
3091 private:
3092     SpeculativeJIT* m_jit;
3093     Edge m_edge;
3094     GPRReg m_gprOrInvalid;
3095 };
3096
3097 enum OppositeShiftTag { OppositeShift };
3098
3099 class SpeculateWhicheverInt52Operand {
3100 public:
3101     explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge)
3102         : m_jit(jit)
3103         , m_edge(edge)
3104         , m_gprOrInvalid(InvalidGPRReg)
3105         , m_strict(jit->betterUseStrictInt52(edge))
3106     {
3107         RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3108         if (jit->isFilled(node()))
3109             gpr();
3110     }
3111     
3112     explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, const SpeculateWhicheverInt52Operand& other)
3113         : m_jit(jit)
3114         , m_edge(edge)
3115         , m_gprOrInvalid(InvalidGPRReg)
3116         , m_strict(other.m_strict)
3117     {
3118         RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3119         if (jit->isFilled(node()))
3120             gpr();
3121     }
3122     
3123     explicit SpeculateWhicheverInt52Operand(SpeculativeJIT* jit, Edge edge, OppositeShiftTag, const SpeculateWhicheverInt52Operand& other)
3124         : m_jit(jit)
3125         , m_edge(edge)
3126         , m_gprOrInvalid(InvalidGPRReg)
3127         , m_strict(!other.m_strict)
3128     {
3129         RELEASE_ASSERT(edge.useKind() == Int52RepUse);
3130         if (jit->isFilled(node()))
3131             gpr();
3132     }
3133     
3134     ~SpeculateWhicheverInt52Operand()
3135     {
3136         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3137         m_jit->unlock(m_gprOrInvalid);
3138     }
3139     
3140     Edge edge() const
3141     {
3142         return m_edge;
3143     }
3144     
3145     Node* node() const
3146     {
3147         return edge().node();
3148     }
3149     
3150     GPRReg gpr()
3151     {
3152         if (m_gprOrInvalid == InvalidGPRReg) {
3153             m_gprOrInvalid = m_jit->fillSpeculateInt52(
3154                 edge(), m_strict ? DataFormatStrictInt52 : DataFormatInt52);
3155         }
3156         return m_gprOrInvalid;
3157     }
3158     
3159     void use()
3160     {
3161         m_jit->use(node());
3162     }
3163     
3164     DataFormat format() const
3165     {
3166         return m_strict ? DataFormatStrictInt52 : DataFormatInt52;
3167     }
3168
3169 private:
3170     SpeculativeJIT* m_jit;
3171     Edge m_edge;
3172     GPRReg m_gprOrInvalid;
3173     bool m_strict;
3174 };
3175
3176 class SpeculateDoubleOperand {
3177 public:
3178     explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge edge)
3179         : m_jit(jit)
3180         , m_edge(edge)
3181         , m_fprOrInvalid(InvalidFPRReg)
3182     {
3183         ASSERT(m_jit);
3184         RELEASE_ASSERT(isDouble(edge.useKind()));
3185         if (jit->isFilled(node()))
3186             fpr();
3187     }
3188
3189     ~SpeculateDoubleOperand()
3190     {
3191         ASSERT(m_fprOrInvalid != InvalidFPRReg);
3192         m_jit->unlock(m_fprOrInvalid);
3193     }
3194     
3195     Edge edge() const
3196     {
3197         return m_edge;
3198     }
3199
3200     Node* node() const
3201     {
3202         return edge().node();
3203     }
3204
3205     FPRReg fpr()
3206     {
3207         if (m_fprOrInvalid == InvalidFPRReg)
3208             m_fprOrInvalid = m_jit->fillSpeculateDouble(edge());
3209         return m_fprOrInvalid;
3210     }
3211     
3212     void use()
3213     {
3214         m_jit->use(node());
3215     }
3216
3217 private:
3218     SpeculativeJIT* m_jit;
3219     Edge m_edge;
3220     FPRReg m_fprOrInvalid;
3221 };
3222
3223 class SpeculateCellOperand {
3224 public:
3225     explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
3226         : m_jit(jit)
3227         , m_edge(edge)
3228         , m_gprOrInvalid(InvalidGPRReg)
3229     {
3230         ASSERT(m_jit);
3231         if (!edge)
3232             return;
3233         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || isCell(edge.useKind()));
3234         if (jit->isFilled(node()))
3235             gpr();
3236     }
3237
3238     ~SpeculateCellOperand()
3239     {
3240         if (!m_edge)
3241             return;
3242         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3243         m_jit->unlock(m_gprOrInvalid);
3244     }
3245     
3246     Edge edge() const
3247     {
3248         return m_edge;
3249     }
3250
3251     Node* node() const
3252     {
3253         return edge().node();
3254     }
3255
3256     GPRReg gpr()
3257     {
3258         ASSERT(m_edge);
3259         if (m_gprOrInvalid == InvalidGPRReg)
3260             m_gprOrInvalid = m_jit->fillSpeculateCell(edge());
3261         return m_gprOrInvalid;
3262     }
3263     
3264     void use()
3265     {
3266         ASSERT(m_edge);
3267         m_jit->use(node());
3268     }
3269
3270 private:
3271     SpeculativeJIT* m_jit;
3272     Edge m_edge;
3273     GPRReg m_gprOrInvalid;
3274 };
3275
3276 class SpeculateBooleanOperand {
3277 public:
3278     explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)
3279         : m_jit(jit)
3280         , m_edge(edge)
3281         , m_gprOrInvalid(InvalidGPRReg)
3282     {
3283         ASSERT(m_jit);
3284         ASSERT_UNUSED(mode, mode == ManualOperandSpeculation || edge.useKind() == BooleanUse || edge.useKind() == KnownBooleanUse);
3285         if (jit->isFilled(node()))
3286             gpr();
3287     }
3288     
3289     ~SpeculateBooleanOperand()
3290     {
3291         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3292         m_jit->unlock(m_gprOrInvalid);
3293     }
3294     
3295     Edge edge() const
3296     {
3297         return m_edge;
3298     }
3299     
3300     Node* node() const
3301     {
3302         return edge().node();
3303     }
3304     
3305     GPRReg gpr()
3306     {
3307         if (m_gprOrInvalid == InvalidGPRReg)
3308             m_gprOrInvalid = m_jit->fillSpeculateBoolean(edge());
3309         return m_gprOrInvalid;
3310     }
3311     
3312     void use()
3313     {
3314         m_jit->use(node());
3315     }
3316
3317 private:
3318     SpeculativeJIT* m_jit;
3319     Edge m_edge;
3320     GPRReg m_gprOrInvalid;
3321 };
3322
3323 template<typename StructureLocationType>
3324 void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
3325 {
3326     Structure* stringObjectStructure =
3327         m_jit.globalObjectFor(m_currentNode->origin.semantic)->stringObjectStructure();
3328     
3329     if (!m_state.forNode(edge).m_structure.isSubsetOf(StructureSet(stringObjectStructure))) {
3330         speculationCheck(
3331             NotStringObject, JSValueRegs(), 0,
3332             m_jit.branchStructure(
3333                 JITCompiler::NotEqual, structureLocation, stringObjectStructure));
3334     }
3335 }
3336
3337 #define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
3338         JSValueSource _dtc_source = (source);                           \
3339         Edge _dtc_edge = (edge);                                        \
3340         SpeculatedType _dtc_typesPassedThrough = typesPassedThrough;    \
3341         if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough))        \
3342             break;                                                      \
3343         typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \
3344     } while (0)
3345