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