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