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