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