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