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