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