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