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