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