JSC should infer when indexed storage is contiguous, and optimize for it
[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     // Spill all VirtualRegisters back to the JSStack.
834     void flushRegisters()
835     {
836         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
837             if (iter.name() != InvalidVirtualRegister) {
838                 spill(iter.name());
839                 iter.release();
840             }
841         }
842         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
843             if (iter.name() != InvalidVirtualRegister) {
844                 spill(iter.name());
845                 iter.release();
846             }
847         }
848     }
849
850 #ifndef NDEBUG
851     // Used to ASSERT flushRegisters() has been called prior to
852     // calling out from JIT code to a C helper function.
853     bool isFlushed()
854     {
855         for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
856             if (iter.name() != InvalidVirtualRegister)
857                 return false;
858         }
859         for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
860             if (iter.name() != InvalidVirtualRegister)
861                 return false;
862         }
863         return true;
864     }
865 #endif
866
867 #if USE(JSVALUE64)
868     MacroAssembler::ImmPtr valueOfJSConstantAsImmPtr(NodeIndex nodeIndex)
869     {
870         return MacroAssembler::ImmPtr(JSValue::encode(valueOfJSConstant(nodeIndex)));
871     }
872 #endif
873
874     // Helper functions to enable code sharing in implementations of bit/shift ops.
875     void bitOp(NodeType op, int32_t imm, GPRReg op1, GPRReg result)
876     {
877         switch (op) {
878         case BitAnd:
879             m_jit.and32(Imm32(imm), op1, result);
880             break;
881         case BitOr:
882             m_jit.or32(Imm32(imm), op1, result);
883             break;
884         case BitXor:
885             m_jit.xor32(Imm32(imm), op1, result);
886             break;
887         default:
888             ASSERT_NOT_REACHED();
889         }
890     }
891     void bitOp(NodeType op, GPRReg op1, GPRReg op2, GPRReg result)
892     {
893         switch (op) {
894         case BitAnd:
895             m_jit.and32(op1, op2, result);
896             break;
897         case BitOr:
898             m_jit.or32(op1, op2, result);
899             break;
900         case BitXor:
901             m_jit.xor32(op1, op2, result);
902             break;
903         default:
904             ASSERT_NOT_REACHED();
905         }
906     }
907     void shiftOp(NodeType op, GPRReg op1, int32_t shiftAmount, GPRReg result)
908     {
909         switch (op) {
910         case BitRShift:
911             m_jit.rshift32(op1, Imm32(shiftAmount), result);
912             break;
913         case BitLShift:
914             m_jit.lshift32(op1, Imm32(shiftAmount), result);
915             break;
916         case BitURShift:
917             m_jit.urshift32(op1, Imm32(shiftAmount), result);
918             break;
919         default:
920             ASSERT_NOT_REACHED();
921         }
922     }
923     void shiftOp(NodeType op, GPRReg op1, GPRReg shiftAmount, GPRReg result)
924     {
925         switch (op) {
926         case BitRShift:
927             m_jit.rshift32(op1, shiftAmount, result);
928             break;
929         case BitLShift:
930             m_jit.lshift32(op1, shiftAmount, result);
931             break;
932         case BitURShift:
933             m_jit.urshift32(op1, shiftAmount, result);
934             break;
935         default:
936             ASSERT_NOT_REACHED();
937         }
938     }
939     
940     // Returns the index of the branch node if peephole is okay, UINT_MAX otherwise.
941     unsigned detectPeepHoleBranch()
942     {
943         BasicBlock* block = m_jit.graph().m_blocks[m_block].get();
944
945         // Check that no intervening nodes will be generated.
946         for (unsigned index = m_indexInBlock + 1; index < block->size() - 1; ++index) {
947             NodeIndex nodeIndex = block->at(index);
948             if (at(nodeIndex).shouldGenerate())
949                 return UINT_MAX;
950         }
951
952         // Check if the lastNode is a branch on this node.
953         Node& lastNode = at(block->last());
954         return lastNode.op() == Branch && lastNode.child1().index() == m_compileIndex ? block->size() - 1 : UINT_MAX;
955     }
956     
957     void nonSpeculativeValueToNumber(Node&);
958     void nonSpeculativeValueToInt32(Node&);
959     void nonSpeculativeUInt32ToNumber(Node&);
960
961 #if USE(JSVALUE64)
962     void cachedGetById(CodeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
963     void cachedPutById(CodeOrigin, GPRReg base, GPRReg value, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
964 #elif USE(JSVALUE32_64)
965     void cachedGetById(CodeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget = JITCompiler::Jump(), SpillRegistersMode = NeedToSpill);
966     void cachedPutById(CodeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, Edge valueUse, GPRReg scratchGPR, unsigned identifierNumber, PutKind, JITCompiler::Jump slowPathTarget = JITCompiler::Jump());
967 #endif
968
969     void nonSpeculativeNonPeepholeCompareNull(Edge operand, bool invert = false);
970     void nonSpeculativePeepholeBranchNull(Edge operand, NodeIndex branchNodeIndex, bool invert = false);
971     bool nonSpeculativeCompareNull(Node&, Edge operand, bool invert = false);
972     
973     void nonSpeculativePeepholeBranch(Node&, NodeIndex branchNodeIndex, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
974     void nonSpeculativeNonPeepholeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
975     bool nonSpeculativeCompare(Node&, MacroAssembler::RelationalCondition, S_DFGOperation_EJJ helperFunction);
976     
977     void nonSpeculativePeepholeStrictEq(Node&, NodeIndex branchNodeIndex, bool invert = false);
978     void nonSpeculativeNonPeepholeStrictEq(Node&, bool invert = false);
979     bool nonSpeculativeStrictEq(Node&, bool invert = false);
980     
981     void compileInstanceOfForObject(Node&, GPRReg valueReg, GPRReg prototypeReg, GPRReg scratchAndResultReg);
982     void compileInstanceOf(Node&);
983     
984     // Access to our fixed callee CallFrame.
985     MacroAssembler::Address callFrameSlot(int slot)
986     {
987         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + slot) * static_cast<int>(sizeof(Register)));
988     }
989
990     // Access to our fixed callee CallFrame.
991     MacroAssembler::Address argumentSlot(int argument)
992     {
993         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)));
994     }
995
996     MacroAssembler::Address callFrameTagSlot(int slot)
997     {
998         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + slot) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
999     }
1000
1001     MacroAssembler::Address callFramePayloadSlot(int slot)
1002     {
1003         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + slot) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
1004     }
1005
1006     MacroAssembler::Address argumentTagSlot(int argument)
1007     {
1008         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag));
1009     }
1010
1011     MacroAssembler::Address argumentPayloadSlot(int argument)
1012     {
1013         return MacroAssembler::Address(GPRInfo::callFrameRegister, (m_jit.codeBlock()->m_numCalleeRegisters + argumentToOperand(argument)) * static_cast<int>(sizeof(Register)) + OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload));
1014     }
1015
1016     void emitCall(Node&);
1017     
1018     // Called once a node has completed code generation but prior to setting
1019     // its result, to free up its children. (This must happen prior to setting
1020     // the nodes result, since the node may have the same VirtualRegister as
1021     // a child, and as such will use the same GeneratioInfo).
1022     void useChildren(Node&);
1023
1024     // These method called to initialize the the GenerationInfo
1025     // to describe the result of an operation.
1026     void integerResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatInteger, UseChildrenMode mode = CallUseChildren)
1027     {
1028         Node& node = at(nodeIndex);
1029         if (mode == CallUseChildren)
1030             useChildren(node);
1031
1032         VirtualRegister virtualRegister = node.virtualRegister();
1033         GenerationInfo& info = m_generationInfo[virtualRegister];
1034
1035         if (format == DataFormatInteger) {
1036             m_jit.jitAssertIsInt32(reg);
1037             m_gprs.retain(reg, virtualRegister, SpillOrderInteger);
1038             info.initInteger(nodeIndex, node.refCount(), reg);
1039         } else {
1040 #if USE(JSVALUE64)
1041             ASSERT(format == DataFormatJSInteger);
1042             m_jit.jitAssertIsJSInt32(reg);
1043             m_gprs.retain(reg, virtualRegister, SpillOrderJS);
1044             info.initJSValue(nodeIndex, node.refCount(), reg, format);
1045 #elif USE(JSVALUE32_64)
1046             ASSERT_NOT_REACHED();
1047 #endif
1048         }
1049     }
1050     void integerResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
1051     {
1052         integerResult(reg, nodeIndex, DataFormatInteger, mode);
1053     }
1054     void noResult(NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1055     {
1056         if (mode == UseChildrenCalledExplicitly)
1057             return;
1058         Node& node = at(nodeIndex);
1059         useChildren(node);
1060     }
1061     void cellResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1062     {
1063         Node& node = at(nodeIndex);
1064         if (mode == CallUseChildren)
1065             useChildren(node);
1066
1067         VirtualRegister virtualRegister = node.virtualRegister();
1068         m_gprs.retain(reg, virtualRegister, SpillOrderCell);
1069         GenerationInfo& info = m_generationInfo[virtualRegister];
1070         info.initCell(nodeIndex, node.refCount(), reg);
1071     }
1072     void booleanResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1073     {
1074         Node& node = at(nodeIndex);
1075         if (mode == CallUseChildren)
1076             useChildren(node);
1077
1078         VirtualRegister virtualRegister = node.virtualRegister();
1079         m_gprs.retain(reg, virtualRegister, SpillOrderBoolean);
1080         GenerationInfo& info = m_generationInfo[virtualRegister];
1081         info.initBoolean(nodeIndex, node.refCount(), reg);
1082     }
1083 #if USE(JSVALUE64)
1084     void jsValueResult(GPRReg reg, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
1085     {
1086         if (format == DataFormatJSInteger)
1087             m_jit.jitAssertIsJSInt32(reg);
1088         
1089         Node& node = at(nodeIndex);
1090         if (mode == CallUseChildren)
1091             useChildren(node);
1092
1093         VirtualRegister virtualRegister = node.virtualRegister();
1094         m_gprs.retain(reg, virtualRegister, SpillOrderJS);
1095         GenerationInfo& info = m_generationInfo[virtualRegister];
1096         info.initJSValue(nodeIndex, node.refCount(), reg, format);
1097     }
1098     void jsValueResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode)
1099     {
1100         jsValueResult(reg, nodeIndex, DataFormatJS, mode);
1101     }
1102 #elif USE(JSVALUE32_64)
1103     void jsValueResult(GPRReg tag, GPRReg payload, NodeIndex nodeIndex, DataFormat format = DataFormatJS, UseChildrenMode mode = CallUseChildren)
1104     {
1105         Node& node = at(nodeIndex);
1106         if (mode == CallUseChildren)
1107             useChildren(node);
1108
1109         VirtualRegister virtualRegister = node.virtualRegister();
1110         m_gprs.retain(tag, virtualRegister, SpillOrderJS);
1111         m_gprs.retain(payload, virtualRegister, SpillOrderJS);
1112         GenerationInfo& info = m_generationInfo[virtualRegister];
1113         info.initJSValue(nodeIndex, node.refCount(), tag, payload, format);
1114     }
1115     void jsValueResult(GPRReg tag, GPRReg payload, NodeIndex nodeIndex, UseChildrenMode mode)
1116     {
1117         jsValueResult(tag, payload, nodeIndex, DataFormatJS, mode);
1118     }
1119 #endif
1120     void storageResult(GPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1121     {
1122         Node& node = at(nodeIndex);
1123         if (mode == CallUseChildren)
1124             useChildren(node);
1125         
1126         VirtualRegister virtualRegister = node.virtualRegister();
1127         m_gprs.retain(reg, virtualRegister, SpillOrderStorage);
1128         GenerationInfo& info = m_generationInfo[virtualRegister];
1129         info.initStorage(nodeIndex, node.refCount(), reg);
1130     }
1131     void doubleResult(FPRReg reg, NodeIndex nodeIndex, UseChildrenMode mode = CallUseChildren)
1132     {
1133         Node& node = at(nodeIndex);
1134         if (mode == CallUseChildren)
1135             useChildren(node);
1136
1137         VirtualRegister virtualRegister = node.virtualRegister();
1138         m_fprs.retain(reg, virtualRegister, SpillOrderDouble);
1139         GenerationInfo& info = m_generationInfo[virtualRegister];
1140         info.initDouble(nodeIndex, node.refCount(), reg);
1141     }
1142     void initConstantInfo(NodeIndex nodeIndex)
1143     {
1144         ASSERT(isInt32Constant(nodeIndex) || isNumberConstant(nodeIndex) || isJSConstant(nodeIndex));
1145         Node& node = at(nodeIndex);
1146         m_generationInfo[node.virtualRegister()].initConstant(nodeIndex, node.refCount());
1147     }
1148     
1149     // These methods add calls to C++ helper functions.
1150     // These methods are broadly value representation specific (i.e.
1151     // deal with the fact that a JSValue may be passed in one or two
1152     // machine registers, and delegate the calling convention specific
1153     // decision as to how to fill the regsiters to setupArguments* methods.
1154 #if USE(JSVALUE64)
1155     JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
1156     {
1157         m_jit.setupArgumentsExecState();
1158         return appendCallWithExceptionCheckSetResult(operation, result);
1159     }
1160     JITCompiler::Call callOperation(P_DFGOperation_EO operation, GPRReg result, GPRReg object)
1161     {
1162         m_jit.setupArgumentsWithExecState(object);
1163         return appendCallWithExceptionCheckSetResult(operation, result);
1164     }
1165     JITCompiler::Call callOperation(P_DFGOperation_EOS operation, GPRReg result, GPRReg object, size_t size)
1166     {
1167         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
1168         return appendCallWithExceptionCheckSetResult(operation, result);
1169     }
1170     JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg object, int32_t size)
1171     {
1172         m_jit.setupArgumentsWithExecState(object, TrustedImmPtr(size));
1173         return appendCallWithExceptionCheckSetResult(operation, result);
1174     }
1175     JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
1176     {
1177         m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
1178         return appendCallWithExceptionCheckSetResult(operation, result);
1179     }
1180     JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
1181     {
1182         m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
1183         return appendCallWithExceptionCheckSetResult(operation, result);
1184     }
1185     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg result)
1186     {
1187         m_jit.setupArgumentsExecState();
1188         return appendCallWithExceptionCheckSetResult(operation, result);
1189     }
1190     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, void* pointer)
1191     {
1192         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1193         return appendCallWithExceptionCheckSetResult(operation, result);
1194     }
1195     JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
1196     {
1197         m_jit.setupArguments(arg1);
1198         JITCompiler::Call call = m_jit.appendCall(operation);
1199         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1200         return call;
1201     }
1202     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg result, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1203     {
1204         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1205         return appendCallWithExceptionCheckSetResult(operation, result);
1206     }
1207     JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg result, Identifier* identifier)
1208     {
1209         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
1210         return appendCallWithExceptionCheckSetResult(operation, result);
1211     }
1212     JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg result, GPRReg arg1)
1213     {
1214         m_jit.setupArgumentsWithExecState(arg1);
1215         return appendCallWithExceptionCheckSetResult(operation, result);
1216     }
1217     JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1218     {
1219         m_jit.setupArgumentsWithExecState(arg1, arg2);
1220         return appendCallWithExceptionCheckSetResult(operation, result);
1221     }
1222     JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg result, Structure* structure)
1223     {
1224         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1225         return appendCallWithExceptionCheckSetResult(operation, result);
1226     }
1227     JITCompiler::Call callOperation(J_DFGOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
1228     {
1229         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1230         return appendCallWithExceptionCheckSetResult(operation, result);
1231     }
1232     JITCompiler::Call callOperation(J_DFGOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1233     {
1234         m_jit.setupArgumentsWithExecState(arg1, arg2);
1235         return appendCallWithExceptionCheckSetResult(operation, result);
1236     }
1237     JITCompiler::Call callOperation(J_DFGOperation_EStPS operation, GPRReg result, Structure* structure, void* pointer, size_t size)
1238     {
1239         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
1240         return appendCallWithExceptionCheckSetResult(operation, result);
1241     }
1242     JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg result, void* pointer, size_t size)
1243     {
1244         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1245         return appendCallWithExceptionCheckSetResult(operation, result);
1246     }
1247     JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg result, int startConstant, int numConstants)
1248     {
1249         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1250         return appendCallWithExceptionCheckSetResult(operation, result);
1251     }
1252     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, void* pointer)
1253     {
1254         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1255         return appendCallWithExceptionCheckSetResult(operation, result);
1256     }
1257     JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
1258     {
1259         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1260         return appendCallWithExceptionCheckSetResult(operation, result);
1261     }
1262     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg result, GPRReg arg1, Identifier* identifier)
1263     {
1264         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1265         return appendCallWithExceptionCheckSetResult(operation, result);
1266     }
1267     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1268     {
1269         m_jit.setupArgumentsWithExecState(arg1, arg2);
1270         return appendCallWithExceptionCheckSetResult(operation, result);
1271     }
1272     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg result, GPRReg arg1)
1273     {
1274         m_jit.setupArgumentsWithExecState(arg1);
1275         return appendCallWithExceptionCheckSetResult(operation, result);
1276     }
1277     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, GPRReg arg1)
1278     {
1279         m_jit.setupArgumentsWithExecState(arg1);
1280         return appendCallWithExceptionCheckSetResult(operation, result);
1281     }
1282     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg result, int32_t arg1)
1283     {
1284         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1285         return appendCallWithExceptionCheckSetResult(operation, result);
1286     }
1287     JITCompiler::Call callOperation(J_DFGOperation_EZZ operation, GPRReg result, int32_t arg1, GPRReg arg2)
1288     {
1289         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1290         return appendCallWithExceptionCheckSetResult(operation, result);
1291     }
1292     JITCompiler::Call callOperation(J_DFGOperation_EZIcfZ operation, GPRReg result, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1293     {
1294         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1295         return appendCallWithExceptionCheckSetResult(operation, result);
1296     }
1297     JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
1298     {
1299         m_jit.setupArgumentsExecState();
1300         return appendCallWithExceptionCheckSetResult(operation, result);
1301     }
1302     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
1303     {
1304         m_jit.setupArgumentsWithExecState(arg1);
1305         return appendCallWithExceptionCheckSetResult(operation, result);
1306     }
1307     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
1308     {
1309         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1310         return appendCallWithExceptionCheckSetResult(operation, result);
1311     }
1312     JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1313     {
1314         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1315         return appendCallWithExceptionCheckSetResult(operation, result);
1316     }
1317     JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
1318     {
1319         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1320         return appendCallWithExceptionCheckSetResult(operation, result);
1321     }
1322     JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1)
1323     {
1324         m_jit.setupArguments(arg1);
1325         return appendCallSetResult(operation, result);
1326     }
1327     JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1)
1328     {
1329         m_jit.setupArgumentsWithExecState(arg1);
1330         return appendCallWithExceptionCheckSetResult(operation, result);
1331     }
1332     JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1333     {
1334         m_jit.setupArgumentsWithExecState(arg1, arg2);
1335         return appendCallWithExceptionCheckSetResult(operation, result);
1336     }
1337     JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1338     {
1339         m_jit.setupArgumentsWithExecState(arg1, arg2);
1340         return appendCallWithExceptionCheckSetResult(operation, result);
1341     }
1342     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1343     {
1344         m_jit.setupArgumentsWithExecState(arg1, arg2);
1345         return appendCallWithExceptionCheckSetResult(operation, result);
1346     }
1347     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1, MacroAssembler::TrustedImm32 imm)
1348     {
1349         m_jit.setupArgumentsWithExecState(arg1, MacroAssembler::TrustedImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm.m_value)))));
1350         return appendCallWithExceptionCheckSetResult(operation, result);
1351     }
1352     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg result, MacroAssembler::TrustedImm32 imm, GPRReg arg2)
1353     {
1354         m_jit.setupArgumentsWithExecState(MacroAssembler::TrustedImmPtr(static_cast<const void*>(JSValue::encode(jsNumber(imm.m_value)))), arg2);
1355         return appendCallWithExceptionCheckSetResult(operation, result);
1356     }
1357     JITCompiler::Call callOperation(J_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1358     {
1359         m_jit.setupArgumentsWithExecState(arg1, arg2);
1360         return appendCallWithExceptionCheckSetResult(operation, result);
1361     }
1362     JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1363     {
1364         m_jit.setupArgumentsWithExecState(arg1, arg2);
1365         return appendCallWithExceptionCheckSetResult(operation, result);
1366     }
1367     JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
1368     {
1369         m_jit.setupArgumentsWithExecState(arg1);
1370         return appendCallWithExceptionCheck(operation);
1371     }
1372     JITCompiler::Call callOperation(V_DFGOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* arg2)
1373     {
1374         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1375         return appendCallWithExceptionCheck(operation);
1376     }
1377     JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* arg3)
1378     {
1379         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(arg3));
1380         return appendCallWithExceptionCheck(operation);
1381     }
1382     JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1, GPRReg arg2, void* pointer)
1383     {
1384         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(pointer));
1385         return appendCallWithExceptionCheck(operation);
1386     }
1387     JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1388     {
1389         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1390         return appendCallWithExceptionCheck(operation);
1391     }
1392     JITCompiler::Call callOperation(V_DFGOperation_EJJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1393     {
1394         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1395         return appendCallWithExceptionCheck(operation);
1396     }
1397     JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1398     {
1399         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1400         return appendCallWithExceptionCheck(operation);
1401     }
1402     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1403     {
1404         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1405         return appendCallWithExceptionCheck(operation);
1406     }
1407     JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3)
1408     {
1409         m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
1410         return appendCallWithExceptionCheck(operation);
1411     }
1412     JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
1413     {
1414         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1415         return appendCallWithExceptionCheck(operation);
1416     }
1417     JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1418     {
1419         m_jit.setupArgumentsWithExecState(arg1, arg2);
1420         return appendCallWithExceptionCheck(operation);
1421     }
1422     JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
1423     {
1424         m_jit.setupArguments(TrustedImmPtr(watchpointSet));
1425         return appendCall(operation);
1426     }
1427     template<typename FunctionType, typename ArgumentType1>
1428     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1429     {
1430         return callOperation(operation, arg1);
1431     }
1432     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1433     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1434     {
1435         return callOperation(operation, arg1, arg2);
1436     }
1437     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1438     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1439     {
1440         return callOperation(operation, arg1, arg2, arg3);
1441     }
1442     JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1)
1443     {
1444         m_jit.setupArgumentsWithExecState(arg1);
1445         return appendCallWithExceptionCheckSetResult(operation, result);
1446     }
1447     JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1448     {
1449         m_jit.setupArguments(arg1, arg2);
1450         return appendCallSetResult(operation, result);
1451     }
1452     JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1453     {
1454         m_jit.setupArguments(arg1, arg2);
1455         return appendCallSetResult(operation, result);
1456     }
1457 #else
1458
1459 // 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]).
1460 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1461 #if COMPILER_SUPPORTS(EABI) && CPU(ARM)
1462 #define EABI_32BIT_DUMMY_ARG      TrustedImm32(0),
1463 #else
1464 #define EABI_32BIT_DUMMY_ARG
1465 #endif
1466
1467     JITCompiler::Call callOperation(P_DFGOperation_E operation, GPRReg result)
1468     {
1469         m_jit.setupArgumentsExecState();
1470         return appendCallWithExceptionCheckSetResult(operation, result);
1471     }
1472     JITCompiler::Call callOperation(P_DFGOperation_EO operation, GPRReg result, GPRReg arg1)
1473     {
1474         m_jit.setupArgumentsWithExecState(arg1);
1475         return appendCallWithExceptionCheckSetResult(operation, result);
1476     }
1477     JITCompiler::Call callOperation(P_DFGOperation_EOS operation, GPRReg result, GPRReg arg1, size_t arg2)
1478     {
1479         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1480         return appendCallWithExceptionCheckSetResult(operation, result);
1481     }
1482     JITCompiler::Call callOperation(P_DFGOperation_EOZ operation, GPRReg result, GPRReg arg1, int32_t arg2)
1483     {
1484         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(arg2));
1485         return appendCallWithExceptionCheckSetResult(operation, result);
1486     }
1487     JITCompiler::Call callOperation(P_DFGOperation_EPS operation, GPRReg result, GPRReg old, size_t size)
1488     {
1489         m_jit.setupArgumentsWithExecState(old, TrustedImmPtr(size));
1490         return appendCallWithExceptionCheckSetResult(operation, result);
1491     }
1492     JITCompiler::Call callOperation(P_DFGOperation_ES operation, GPRReg result, size_t size)
1493     {
1494         m_jit.setupArgumentsWithExecState(TrustedImmPtr(size));
1495         return appendCallWithExceptionCheckSetResult(operation, result);
1496     }
1497     JITCompiler::Call callOperation(Z_DFGOperation_D operation, GPRReg result, FPRReg arg1)
1498     {
1499         prepareForExternalCall();
1500         m_jit.setupArguments(arg1);
1501         JITCompiler::Call call = m_jit.appendCall(operation);
1502         m_jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, result);
1503         return call;
1504     }
1505     JITCompiler::Call callOperation(J_DFGOperation_E operation, GPRReg resultTag, GPRReg resultPayload)
1506     {
1507         m_jit.setupArgumentsExecState();
1508         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1509     }
1510     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, void* pointer)
1511     {
1512         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer));
1513         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1514     }
1515     JITCompiler::Call callOperation(J_DFGOperation_EPP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, void* pointer)
1516     {
1517         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(pointer));
1518         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1519     }
1520     JITCompiler::Call callOperation(J_DFGOperation_EGriJsgI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2, Identifier* identifier)
1521     {
1522         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(identifier));
1523         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1524     }
1525     JITCompiler::Call callOperation(J_DFGOperation_EP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1526     {
1527         m_jit.setupArgumentsWithExecState(arg1);
1528         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1529     }
1530     JITCompiler::Call callOperation(J_DFGOperation_EI operation, GPRReg resultTag, GPRReg resultPayload, Identifier* identifier)
1531     {
1532         m_jit.setupArgumentsWithExecState(TrustedImmPtr(identifier));
1533         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1534     }
1535     JITCompiler::Call callOperation(J_DFGOperation_EA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1536     {
1537         m_jit.setupArgumentsWithExecState(arg1);
1538         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1539     }
1540     JITCompiler::Call callOperation(J_DFGOperation_EAZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1541     {
1542         m_jit.setupArgumentsWithExecState(arg1, arg2);
1543         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1544     }
1545     JITCompiler::Call callOperation(J_DFGOperation_ESt operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure)
1546     {
1547         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
1548         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1549     }
1550     JITCompiler::Call callOperation(J_DFGOperation_EStZ operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure, GPRReg arg2)
1551     {
1552         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
1553         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1554     }
1555     JITCompiler::Call callOperation(J_DFGOperation_EStZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1556     {
1557         m_jit.setupArgumentsWithExecState(arg1, arg2);
1558         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1559     }
1560     JITCompiler::Call callOperation(J_DFGOperation_EStPS operation, GPRReg resultTag, GPRReg resultPayload, Structure* structure, void* pointer, size_t size)
1561     {
1562         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImmPtr(pointer), TrustedImmPtr(size));
1563         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1564     }
1565     JITCompiler::Call callOperation(J_DFGOperation_EPS operation, GPRReg resultTag, GPRReg resultPayload, void* pointer, size_t size)
1566     {
1567         m_jit.setupArgumentsWithExecState(TrustedImmPtr(pointer), TrustedImmPtr(size));
1568         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1569     }
1570     JITCompiler::Call callOperation(J_DFGOperation_ESS operation, GPRReg resultTag, GPRReg resultPayload, int startConstant, int numConstants)
1571     {
1572         m_jit.setupArgumentsWithExecState(TrustedImm32(startConstant), TrustedImm32(numConstants));
1573         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1574     }
1575     JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, void* pointer)
1576     {
1577         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(pointer));
1578         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1579     }
1580     JITCompiler::Call callOperation(J_DFGOperation_EJP operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1581     {
1582         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1583         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1584     }
1585     JITCompiler::Call callOperation(J_DFGOperation_ECI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, Identifier* identifier)
1586     {
1587         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(identifier));
1588         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1589     }
1590     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, Identifier* identifier)
1591     {
1592         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, TrustedImmPtr(identifier));
1593         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1594     }
1595     JITCompiler::Call callOperation(J_DFGOperation_EJI operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1Tag, GPRReg arg1Payload, Identifier* identifier)
1596     {
1597         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, TrustedImm32(arg1Tag), TrustedImmPtr(identifier));
1598         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1599     }
1600     JITCompiler::Call callOperation(J_DFGOperation_EJA operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2)
1601     {
1602         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2);
1603         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1604     }
1605     JITCompiler::Call callOperation(J_DFGOperation_EJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload)
1606     {
1607         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1608         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1609     }
1610     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1)
1611     {
1612         m_jit.setupArgumentsWithExecState(arg1);
1613         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1614     }
1615     JITCompiler::Call callOperation(J_DFGOperation_EZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1)
1616     {
1617         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1));
1618         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1619     }
1620     JITCompiler::Call callOperation(J_DFGOperation_EZIcfZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, InlineCallFrame* inlineCallFrame, GPRReg arg2)
1621     {
1622         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), TrustedImmPtr(inlineCallFrame), arg2);
1623         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1624     }
1625     JITCompiler::Call callOperation(J_DFGOperation_EZZ operation, GPRReg resultTag, GPRReg resultPayload, int32_t arg1, GPRReg arg2)
1626     {
1627         m_jit.setupArgumentsWithExecState(TrustedImm32(arg1), arg2);
1628         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1629     }
1630     JITCompiler::Call callOperation(C_DFGOperation_E operation, GPRReg result)
1631     {
1632         m_jit.setupArgumentsExecState();
1633         return appendCallWithExceptionCheckSetResult(operation, result);
1634     }
1635     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, GPRReg arg1)
1636     {
1637         m_jit.setupArgumentsWithExecState(arg1);
1638         return appendCallWithExceptionCheckSetResult(operation, result);
1639     }
1640     JITCompiler::Call callOperation(C_DFGOperation_EC operation, GPRReg result, JSCell* cell)
1641     {
1642         m_jit.setupArgumentsWithExecState(TrustedImmPtr(cell));
1643         return appendCallWithExceptionCheckSetResult(operation, result);
1644     }
1645     JITCompiler::Call callOperation(C_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, JSCell* cell)
1646     {
1647         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(cell));
1648         return appendCallWithExceptionCheckSetResult(operation, result);
1649     }
1650     JITCompiler::Call callOperation(C_DFGOperation_EIcf operation, GPRReg result, InlineCallFrame* inlineCallFrame)
1651     {
1652         m_jit.setupArgumentsWithExecState(TrustedImmPtr(inlineCallFrame));
1653         return appendCallWithExceptionCheckSetResult(operation, result);
1654     }
1655     JITCompiler::Call callOperation(S_DFGOperation_J operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1656     {
1657         m_jit.setupArguments(arg1Payload, arg1Tag);
1658         return appendCallSetResult(operation, result);
1659     }
1660     JITCompiler::Call callOperation(S_DFGOperation_EJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1661     {
1662         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1663         return appendCallWithExceptionCheckSetResult(operation, result);
1664     }
1665     JITCompiler::Call callOperation(S_DFGOperation_ECC operation, GPRReg result, GPRReg arg1, GPRReg arg2)
1666     {
1667         m_jit.setupArgumentsWithExecState(arg1, arg2);
1668         return appendCallWithExceptionCheckSetResult(operation, result);
1669     }
1670     JITCompiler::Call callOperation(S_DFGOperation_EJJ operation, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1671     {
1672         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1673         return appendCallWithExceptionCheckSetResult(operation, result);
1674     }
1675     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2Tag, GPRReg arg2Payload)
1676     {
1677         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2Payload, arg2Tag);
1678         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1679     }
1680     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1Tag, GPRReg arg1Payload, MacroAssembler::TrustedImm32 imm)
1681     {
1682         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, imm, TrustedImm32(JSValue::Int32Tag));
1683         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1684     }
1685     JITCompiler::Call callOperation(J_DFGOperation_EJJ operation, GPRReg resultTag, GPRReg resultPayload, MacroAssembler::TrustedImm32 imm, GPRReg arg2Tag, GPRReg arg2Payload)
1686     {
1687         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG imm, TrustedImm32(JSValue::Int32Tag), arg2Payload, arg2Tag);
1688         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1689     }
1690     JITCompiler::Call callOperation(J_DFGOperation_ECJ operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload)
1691     {
1692         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag);
1693         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1694     }
1695     JITCompiler::Call callOperation(J_DFGOperation_ECC operation, GPRReg resultTag, GPRReg resultPayload, GPRReg arg1, GPRReg arg2)
1696     {
1697         m_jit.setupArgumentsWithExecState(arg1, arg2);
1698         return appendCallWithExceptionCheckSetResult(operation, resultPayload, resultTag);
1699     }
1700     JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
1701     {
1702         m_jit.setupArgumentsWithExecState(arg1);
1703         return appendCallWithExceptionCheck(operation);
1704     }
1705     JITCompiler::Call callOperation(V_DFGOperation_ECIcf operation, GPRReg arg1, InlineCallFrame* inlineCallFrame)
1706     {
1707         m_jit.setupArgumentsWithExecState(arg1, TrustedImmPtr(inlineCallFrame));
1708         return appendCallWithExceptionCheck(operation);
1709     }
1710     JITCompiler::Call callOperation(V_DFGOperation_ECCIcf operation, GPRReg arg1, GPRReg arg2, InlineCallFrame* inlineCallFrame)
1711     {
1712         m_jit.setupArgumentsWithExecState(arg1, arg2, TrustedImmPtr(inlineCallFrame));
1713         return appendCallWithExceptionCheck(operation);
1714     }
1715     JITCompiler::Call callOperation(V_DFGOperation_EJPP operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, void* pointer)
1716     {
1717         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(pointer));
1718         return appendCallWithExceptionCheck(operation);
1719     }
1720     JITCompiler::Call callOperation(V_DFGOperation_EJCI operation, GPRReg arg1Tag, GPRReg arg1Payload, GPRReg arg2, Identifier* identifier)
1721     {
1722         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag, arg2, TrustedImmPtr(identifier));
1723         return appendCallWithExceptionCheck(operation);
1724     }
1725     JITCompiler::Call callOperation(V_DFGOperation_ECJJ operation, GPRReg arg1, GPRReg arg2Tag, GPRReg arg2Payload, GPRReg arg3Tag, GPRReg arg3Payload)
1726     {
1727         m_jit.setupArgumentsWithExecState(arg1, arg2Payload, arg2Tag, arg3Payload, arg3Tag);
1728         return appendCallWithExceptionCheck(operation);
1729     }
1730     JITCompiler::Call callOperation(V_DFGOperation_ECZ operation, GPRReg arg1, int arg2)
1731     {
1732         m_jit.setupArgumentsWithExecState(arg1, TrustedImm32(arg2));
1733         return appendCallWithExceptionCheck(operation);
1734     }
1735     JITCompiler::Call callOperation(V_DFGOperation_ECC operation, GPRReg arg1, GPRReg arg2)
1736     {
1737         m_jit.setupArgumentsWithExecState(arg1, arg2);
1738         return appendCallWithExceptionCheck(operation);
1739     }
1740     JITCompiler::Call callOperation(V_DFGOperation_EPZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1741     {
1742         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1743         return appendCallWithExceptionCheck(operation);
1744     }
1745     JITCompiler::Call callOperation(V_DFGOperation_EOZJ operation, GPRReg arg1, GPRReg arg2, GPRReg arg3Tag, GPRReg arg3Payload)
1746     {
1747         m_jit.setupArgumentsWithExecState(arg1, arg2, EABI_32BIT_DUMMY_ARG arg3Payload, arg3Tag);
1748         return appendCallWithExceptionCheck(operation);
1749     }
1750     JITCompiler::Call callOperation(V_DFGOperation_W operation, WatchpointSet* watchpointSet)
1751     {
1752         m_jit.setupArguments(TrustedImmPtr(watchpointSet));
1753         return appendCall(operation);
1754     }
1755     template<typename FunctionType, typename ArgumentType1>
1756     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1)
1757     {
1758         return callOperation(operation, arg1);
1759     }
1760     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1761     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2)
1762     {
1763         return callOperation(operation, arg1, arg2);
1764     }
1765     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3>
1766     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3)
1767     {
1768         return callOperation(operation, arg1, arg2, arg3);
1769     }
1770     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4>
1771     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4)
1772     {
1773         return callOperation(operation, arg1, arg2, arg3, arg4);
1774     }
1775     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2, typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1776     JITCompiler::Call callOperation(FunctionType operation, NoResultTag, ArgumentType1 arg1, ArgumentType2 arg2, ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1777     {
1778         return callOperation(operation, arg1, arg2, arg3, arg4, arg5);
1779     }
1780
1781     JITCompiler::Call callOperation(D_DFGOperation_EJ operation, FPRReg result, GPRReg arg1Tag, GPRReg arg1Payload)
1782     {
1783         m_jit.setupArgumentsWithExecState(EABI_32BIT_DUMMY_ARG arg1Payload, arg1Tag);
1784         return appendCallWithExceptionCheckSetResult(operation, result);
1785     }
1786
1787     JITCompiler::Call callOperation(D_DFGOperation_ZZ operation, FPRReg result, GPRReg arg1, GPRReg arg2)
1788     {
1789         m_jit.setupArguments(arg1, arg2);
1790         return appendCallSetResult(operation, result);
1791     }
1792     JITCompiler::Call callOperation(D_DFGOperation_DD operation, FPRReg result, FPRReg arg1, FPRReg arg2)
1793     {
1794         m_jit.setupArguments(arg1, arg2);
1795         return appendCallSetResult(operation, result);
1796     }
1797
1798 #undef EABI_32BIT_DUMMY_ARG
1799     
1800     template<typename FunctionType>
1801     JITCompiler::Call callOperation(
1802         FunctionType operation, JSValueRegs result)
1803     {
1804         return callOperation(operation, result.tagGPR(), result.payloadGPR());
1805     }
1806     template<typename FunctionType, typename ArgumentType1>
1807     JITCompiler::Call callOperation(
1808         FunctionType operation, JSValueRegs result, ArgumentType1 arg1)
1809     {
1810         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1);
1811     }
1812     template<typename FunctionType, typename ArgumentType1, typename ArgumentType2>
1813     JITCompiler::Call callOperation(
1814         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2)
1815     {
1816         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2);
1817     }
1818     template<
1819         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1820         typename ArgumentType3>
1821     JITCompiler::Call callOperation(
1822         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1823         ArgumentType3 arg3)
1824     {
1825         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3);
1826     }
1827     template<
1828         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1829         typename ArgumentType3, typename ArgumentType4>
1830     JITCompiler::Call callOperation(
1831         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1832         ArgumentType3 arg3, ArgumentType4 arg4)
1833     {
1834         return callOperation(operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4);
1835     }
1836     template<
1837         typename FunctionType, typename ArgumentType1, typename ArgumentType2,
1838         typename ArgumentType3, typename ArgumentType4, typename ArgumentType5>
1839     JITCompiler::Call callOperation(
1840         FunctionType operation, JSValueRegs result, ArgumentType1 arg1, ArgumentType2 arg2,
1841         ArgumentType3 arg3, ArgumentType4 arg4, ArgumentType5 arg5)
1842     {
1843         return callOperation(
1844             operation, result.tagGPR(), result.payloadGPR(), arg1, arg2, arg3, arg4, arg5);
1845     }
1846 #endif
1847     
1848 #if !defined(NDEBUG) && !CPU(ARM)
1849     void prepareForExternalCall()
1850     {
1851         for (unsigned i = 0; i < sizeof(void*) / 4; i++)
1852             m_jit.store32(TrustedImm32(0xbadbeef), reinterpret_cast<char*>(&m_jit.globalData()->topCallFrame) + i * 4);
1853     }
1854 #else
1855     void prepareForExternalCall() { }
1856 #endif
1857
1858     // These methods add call instructions, with optional exception checks & setting results.
1859     JITCompiler::Call appendCallWithExceptionCheck(const FunctionPtr& function)
1860     {
1861         prepareForExternalCall();
1862         CodeOrigin codeOrigin = at(m_compileIndex).codeOrigin;
1863         CallBeginToken token;
1864         m_jit.beginCall(codeOrigin, token);
1865         JITCompiler::Call call = m_jit.appendCall(function);
1866         m_jit.addExceptionCheck(call, codeOrigin, token);
1867         return call;
1868     }
1869     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result)
1870     {
1871         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1872         m_jit.move(GPRInfo::returnValueGPR, result);
1873         return call;
1874     }
1875     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, GPRReg result)
1876     {
1877         prepareForExternalCall();
1878         JITCompiler::Call call = m_jit.appendCall(function);
1879         m_jit.move(GPRInfo::returnValueGPR, result);
1880         return call;
1881     }
1882     JITCompiler::Call appendCall(const FunctionPtr& function)
1883     {
1884         prepareForExternalCall();
1885         return m_jit.appendCall(function);
1886     }
1887     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, GPRReg result1, GPRReg result2)
1888     {
1889         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1890         m_jit.setupResults(result1, result2);
1891         return call;
1892     }
1893 #if CPU(X86)
1894     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1895     {
1896         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1897         m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1898         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1899         return call;
1900     }
1901     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1902     {
1903         JITCompiler::Call call = m_jit.appendCall(function);
1904         m_jit.assembler().fstpl(0, JITCompiler::stackPointerRegister);
1905         m_jit.loadDouble(JITCompiler::stackPointerRegister, result);
1906         return call;
1907     }
1908 #elif CPU(ARM)
1909 #if CPU(ARM_HARDFP)
1910     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1911     {
1912         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1913         m_jit.moveDouble(result, FPRInfo::argumentFPR0);
1914         return call;
1915     }
1916     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1917     {
1918         JITCompiler::Call call = m_jit.appendCall(function);
1919         m_jit.moveDouble(result, FPRInfo::argumentFPR0);
1920         return call;
1921     }
1922 #else
1923         JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1924     {
1925         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1926         m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1927         return call;
1928     }
1929     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1930     {
1931         JITCompiler::Call call = m_jit.appendCall(function);
1932         m_jit.assembler().vmov(result, GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
1933         return call;
1934     }
1935 #endif // CPU(ARM_HARDFP)
1936 #else
1937     JITCompiler::Call appendCallWithExceptionCheckSetResult(const FunctionPtr& function, FPRReg result)
1938     {
1939         JITCompiler::Call call = appendCallWithExceptionCheck(function);
1940         m_jit.moveDouble(FPRInfo::returnValueFPR, result);
1941         return call;
1942     }
1943     JITCompiler::Call appendCallSetResult(const FunctionPtr& function, FPRReg result)
1944     {
1945         JITCompiler::Call call = m_jit.appendCall(function);
1946         m_jit.moveDouble(FPRInfo::returnValueFPR, result);
1947         return call;
1948     }
1949 #endif
1950     
1951     void branchDouble(JITCompiler::DoubleCondition cond, FPRReg left, FPRReg right, BlockIndex destination)
1952     {
1953         if (!haveEdgeCodeToEmit(destination))
1954             return addBranch(m_jit.branchDouble(cond, left, right), destination);
1955         
1956         JITCompiler::Jump notTaken = m_jit.branchDouble(JITCompiler::invert(cond), left, right);
1957         emitEdgeCode(destination);
1958         addBranch(m_jit.jump(), destination);
1959         notTaken.link(&m_jit);
1960     }
1961     
1962     void branchDoubleNonZero(FPRReg value, FPRReg scratch, BlockIndex destination)
1963     {
1964         if (!haveEdgeCodeToEmit(destination))
1965             return addBranch(m_jit.branchDoubleNonZero(value, scratch), destination);
1966         
1967         JITCompiler::Jump notTaken = m_jit.branchDoubleZeroOrNaN(value, scratch);
1968         emitEdgeCode(destination);
1969         addBranch(m_jit.jump(), destination);
1970         notTaken.link(&m_jit);
1971     }
1972     
1973     template<typename T, typename U>
1974     void branch32(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
1975     {
1976         if (!haveEdgeCodeToEmit(destination))
1977             return addBranch(m_jit.branch32(cond, left, right), destination);
1978         
1979         JITCompiler::Jump notTaken = m_jit.branch32(JITCompiler::invert(cond), left, right);
1980         emitEdgeCode(destination);
1981         addBranch(m_jit.jump(), destination);
1982         notTaken.link(&m_jit);
1983     }
1984     
1985     template<typename T, typename U>
1986     void branchTest32(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
1987     {
1988         ASSERT(JITCompiler::isInvertible(cond));
1989         
1990         if (!haveEdgeCodeToEmit(destination))
1991             return addBranch(m_jit.branchTest32(cond, value, mask), destination);
1992         
1993         JITCompiler::Jump notTaken = m_jit.branchTest32(JITCompiler::invert(cond), value, mask);
1994         emitEdgeCode(destination);
1995         addBranch(m_jit.jump(), destination);
1996         notTaken.link(&m_jit);
1997     }
1998     
1999     template<typename T>
2000     void branchTest32(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
2001     {
2002         ASSERT(JITCompiler::isInvertible(cond));
2003         
2004         if (!haveEdgeCodeToEmit(destination))
2005             return addBranch(m_jit.branchTest32(cond, value), destination);
2006         
2007         JITCompiler::Jump notTaken = m_jit.branchTest32(JITCompiler::invert(cond), value);
2008         emitEdgeCode(destination);
2009         addBranch(m_jit.jump(), destination);
2010         notTaken.link(&m_jit);
2011     }
2012     
2013     template<typename T, typename U>
2014     void branchPtr(JITCompiler::RelationalCondition cond, T left, U right, BlockIndex destination)
2015     {
2016         if (!haveEdgeCodeToEmit(destination))
2017             return addBranch(m_jit.branchPtr(cond, left, right), destination);
2018         
2019         JITCompiler::Jump notTaken = m_jit.branchPtr(JITCompiler::invert(cond), left, right);
2020         emitEdgeCode(destination);
2021         addBranch(m_jit.jump(), destination);
2022         notTaken.link(&m_jit);
2023     }
2024     
2025     template<typename T, typename U>
2026     void branchTestPtr(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
2027     {
2028         ASSERT(JITCompiler::isInvertible(cond));
2029         
2030         if (!haveEdgeCodeToEmit(destination))
2031             return addBranch(m_jit.branchTestPtr(cond, value, mask), destination);
2032         
2033         JITCompiler::Jump notTaken = m_jit.branchTestPtr(JITCompiler::invert(cond), value, mask);
2034         emitEdgeCode(destination);
2035         addBranch(m_jit.jump(), destination);
2036         notTaken.link(&m_jit);
2037     }
2038     
2039     template<typename T>
2040     void branchTestPtr(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
2041     {
2042         ASSERT(JITCompiler::isInvertible(cond));
2043         
2044         if (!haveEdgeCodeToEmit(destination))
2045             return addBranch(m_jit.branchTestPtr(cond, value), destination);
2046         
2047         JITCompiler::Jump notTaken = m_jit.branchTestPtr(JITCompiler::invert(cond), value);
2048         emitEdgeCode(destination);
2049         addBranch(m_jit.jump(), destination);
2050         notTaken.link(&m_jit);
2051     }
2052     
2053     template<typename T, typename U>
2054     void branchTest8(JITCompiler::ResultCondition cond, T value, U mask, BlockIndex destination)
2055     {
2056         ASSERT(JITCompiler::isInvertible(cond));
2057         
2058         if (!haveEdgeCodeToEmit(destination))
2059             return addBranch(m_jit.branchTest8(cond, value, mask), destination);
2060         
2061         JITCompiler::Jump notTaken = m_jit.branchTest8(JITCompiler::invert(cond), value, mask);
2062         emitEdgeCode(destination);
2063         addBranch(m_jit.jump(), destination);
2064         notTaken.link(&m_jit);
2065     }
2066     
2067     template<typename T>
2068     void branchTest8(JITCompiler::ResultCondition cond, T value, BlockIndex destination)
2069     {
2070         ASSERT(JITCompiler::isInvertible(cond));
2071         
2072         if (!haveEdgeCodeToEmit(destination))
2073             return addBranch(m_jit.branchTest8(cond, value), destination);
2074         
2075         JITCompiler::Jump notTaken = m_jit.branchTest8(JITCompiler::invert(cond), value);
2076         emitEdgeCode(destination);
2077         addBranch(m_jit.jump(), destination);
2078         notTaken.link(&m_jit);
2079     }
2080     
2081     enum FallThroughMode {
2082         AtFallThroughPoint,
2083         ForceJump
2084     };
2085     void jump(BlockIndex destination, FallThroughMode fallThroughMode = AtFallThroughPoint)
2086     {
2087         if (haveEdgeCodeToEmit(destination))
2088             emitEdgeCode(destination);
2089         if (destination == nextBlock()
2090             && fallThroughMode == AtFallThroughPoint)
2091             return;
2092         addBranch(m_jit.jump(), destination);
2093     }
2094     
2095     inline bool haveEdgeCodeToEmit(BlockIndex)
2096     {
2097         return DFG_ENABLE_EDGE_CODE_VERIFICATION;
2098     }
2099     void emitEdgeCode(BlockIndex destination)
2100     {
2101         if (!DFG_ENABLE_EDGE_CODE_VERIFICATION)
2102             return;
2103         m_jit.move(TrustedImm32(destination), GPRInfo::regT0);
2104     }
2105
2106     void addBranch(const MacroAssembler::Jump& jump, BlockIndex destination)
2107     {
2108         m_branches.append(BranchRecord(jump, destination));
2109     }
2110
2111     void linkBranches()
2112     {
2113         for (size_t i = 0; i < m_branches.size(); ++i) {
2114             BranchRecord& branch = m_branches[i];
2115             branch.jump.linkTo(m_blockHeads[branch.destination], &m_jit);
2116         }
2117     }
2118
2119     BasicBlock* block()
2120     {
2121         return m_jit.graph().m_blocks[m_block].get();
2122     }
2123
2124 #ifndef NDEBUG
2125     void dump(const char* label = 0);
2126 #endif
2127
2128 #if DFG_ENABLE(CONSISTENCY_CHECK)
2129     void checkConsistency();
2130 #else
2131     void checkConsistency() { }
2132 #endif
2133
2134     bool isInteger(NodeIndex nodeIndex)
2135     {
2136         Node& node = at(nodeIndex);
2137         if (node.hasInt32Result())
2138             return true;
2139
2140         if (isInt32Constant(nodeIndex))
2141             return true;
2142
2143         VirtualRegister virtualRegister = node.virtualRegister();
2144         GenerationInfo& info = m_generationInfo[virtualRegister];
2145         
2146         return info.isJSInteger();
2147     }
2148     
2149     bool compare(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
2150     bool compilePeepHoleBranch(Node&, MacroAssembler::RelationalCondition, MacroAssembler::DoubleCondition, S_DFGOperation_EJJ);
2151     void compilePeepHoleIntegerBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::RelationalCondition);
2152     void compilePeepHoleDoubleBranch(Node&, NodeIndex branchNodeIndex, JITCompiler::DoubleCondition);
2153     void compilePeepHoleObjectEquality(Node&, NodeIndex branchNodeIndex);
2154     void compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, NodeIndex branchNodeIndex);
2155     void compileObjectEquality(Node&);
2156     void compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild);
2157     void compileValueAdd(Node&);
2158     void compileNonStringCellOrOtherLogicalNot(Edge value, bool needSpeculationCheck);
2159     void compileLogicalNot(Node&);
2160     void emitNonStringCellOrOtherBranch(Edge value, BlockIndex taken, BlockIndex notTaken, bool needSpeculationCheck);
2161     void emitBranch(Node&);
2162     
2163     void compileIntegerCompare(Node&, MacroAssembler::RelationalCondition);
2164     void compileDoubleCompare(Node&, MacroAssembler::DoubleCondition);
2165     
2166     bool compileStrictEqForConstant(Node&, Edge value, JSValue constant);
2167     
2168     bool compileStrictEq(Node&);
2169     
2170     void compileAllocatePropertyStorage(Node&);
2171     void compileReallocatePropertyStorage(Node&);
2172     
2173 #if USE(JSVALUE64)
2174     MacroAssembler::JumpList compileContiguousGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg);
2175     MacroAssembler::JumpList compileArrayStorageGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultReg);
2176 #else
2177     MacroAssembler::JumpList compileContiguousGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg);
2178     MacroAssembler::JumpList compileArrayStorageGetByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg resultTagReg, GPRReg resultPayloadReg);
2179 #endif
2180     
2181     bool putByValWillNeedExtraRegister(Array::Mode arrayMode)
2182     {
2183         switch (arrayMode) {
2184         // For ArrayStorage, we need an extra reg for stores to holes except if
2185         // we're in SlowPut mode.
2186         case ARRAY_STORAGE_TO_HOLE_MODES:
2187         case OUT_OF_BOUNDS_ARRAY_STORAGE_MODES:
2188         case ALL_EFFECTFUL_ARRAY_STORAGE_MODES:
2189             return true;
2190             
2191         // For Contiguous, we need an extra reg for any access that may store
2192         // to the tail.
2193         case CONTIGUOUS_TO_TAIL_MODES:
2194         case OUT_OF_BOUNDS_CONTIGUOUS_MODES:
2195         case ALL_EFFECTFUL_CONTIGUOUS_MODES:
2196             return true;
2197             
2198         // All polymorphic modes need an extra reg.
2199         case ALL_POLYMORPHIC_MODES:
2200             return true;
2201             
2202         default:
2203             return false;
2204         }
2205     }
2206     GPRReg temporaryRegisterForPutByVal(GPRTemporary&, Array::Mode);
2207     GPRReg temporaryRegisterForPutByVal(GPRTemporary& temporary, Node& node)
2208     {
2209         return temporaryRegisterForPutByVal(temporary, node.arrayMode());
2210     }
2211 #if USE(JSVALUE64)
2212     MacroAssembler::JumpList compileContiguousPutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg);
2213     MacroAssembler::JumpList compileArrayStoragePutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueReg, GPRReg tempReg);
2214 #else
2215     MacroAssembler::JumpList compileContiguousPutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg);
2216     MacroAssembler::JumpList compileArrayStoragePutByVal(Node&, GPRReg baseReg, GPRReg propertyReg, GPRReg storageReg, GPRReg valueTagReg, GPRReg valuePayloadReg);
2217 #endif
2218     
2219     void compileGetCharCodeAt(Node&);
2220     void compileGetByValOnString(Node&);
2221
2222     void compileGetByValOnArguments(Node&);
2223     void compileGetArgumentsLength(Node&);
2224     
2225     void compileGetArrayLength(Node&);
2226     
2227     void compileValueToInt32(Node&);
2228     void compileUInt32ToNumber(Node&);
2229     void compileDoubleAsInt32(Node&);
2230     void compileInt32ToDouble(Node&);
2231     void compileAdd(Node&);
2232     void compileArithSub(Node&);
2233     void compileArithNegate(Node&);
2234     void compileArithMul(Node&);
2235 #if CPU(X86) || CPU(X86_64)
2236     void compileIntegerArithDivForX86(Node&);
2237 #endif
2238     void compileArithMod(Node&);
2239     void compileSoftModulo(Node&);
2240     enum TypedArraySignedness {
2241         SignedTypedArray,
2242         UnsignedTypedArray
2243     };
2244     enum TypedArrayRounding {
2245         TruncateRounding,
2246         ClampRounding
2247     };
2248     void compileGetIndexedPropertyStorage(Node&);
2249     void compileGetByValOnIntTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize, TypedArraySignedness);
2250     void compilePutByValForIntTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize, TypedArraySignedness, TypedArrayRounding = TruncateRounding);
2251     void compileGetByValOnFloatTypedArray(const TypedArrayDescriptor&, Node&, size_t elementSize);
2252     void compilePutByValForFloatTypedArray(const TypedArrayDescriptor&, GPRReg base, GPRReg property, Node&, size_t elementSize);
2253     void compileNewFunctionNoCheck(Node&);
2254     void compileNewFunctionExpression(Node&);
2255     bool compileRegExpExec(Node&);
2256    
2257     // It is NOT okay for the structure and the scratch register to be the same thing because if they are then the Structure will 
2258     // get clobbered. 
2259     template <typename ClassType, MarkedBlock::DestructorType destructorType, typename StructureType> 
2260     void emitAllocateBasicJSObject(StructureType structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2261     {
2262         MarkedAllocator* allocator = 0;
2263         if (destructorType == MarkedBlock::Normal)
2264             allocator = &m_jit.globalData()->heap.allocatorForObjectWithNormalDestructor(sizeof(ClassType));
2265         else if (destructorType == MarkedBlock::ImmortalStructure)
2266             allocator = &m_jit.globalData()->heap.allocatorForObjectWithImmortalStructureDestructor(sizeof(ClassType));
2267         else
2268             allocator = &m_jit.globalData()->heap.allocatorForObjectWithoutDestructor(sizeof(ClassType));
2269
2270         m_jit.loadPtr(&allocator->m_freeList.head, resultGPR);
2271         slowPath.append(m_jit.branchTestPtr(MacroAssembler::Zero, resultGPR));
2272         
2273         // The object is half-allocated: we have what we know is a fresh object, but
2274         // it's still on the GC's free list.
2275         m_jit.loadPtr(MacroAssembler::Address(resultGPR), scratchGPR);
2276         m_jit.storePtr(scratchGPR, &allocator->m_freeList.head);
2277
2278         // Initialize the object's Structure.
2279         m_jit.storePtr(structure, MacroAssembler::Address(resultGPR, JSCell::structureOffset()));
2280         
2281         // Initialize the object's property storage pointer.
2282         m_jit.storePtr(MacroAssembler::TrustedImmPtr(0), MacroAssembler::Address(resultGPR, JSObject::butterflyOffset()));
2283     }
2284
2285     template<typename T>
2286     void emitAllocateJSFinalObject(T structure, GPRReg resultGPR, GPRReg scratchGPR, MacroAssembler::JumpList& slowPath)
2287     {
2288         return emitAllocateBasicJSObject<JSFinalObject, MarkedBlock::None>(structure, resultGPR, scratchGPR, slowPath);
2289     }
2290
2291 #if USE(JSVALUE64) 
2292     JITCompiler::Jump convertToDouble(GPRReg value, FPRReg result, GPRReg tmp);
2293 #elif USE(JSVALUE32_64)
2294     JITCompiler::Jump convertToDouble(JSValueOperand&, FPRReg result);
2295 #endif
2296
2297     // Add a speculation check without additional recovery.
2298     void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail);
2299     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail);
2300     // Add a set of speculation checks without additional recovery.
2301     void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::JumpList& jumpsToFail);
2302     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::JumpList& jumpsToFail);
2303     // Add a speculation check with additional recovery.
2304     void speculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2305     void speculationCheck(ExitKind, JSValueSource, Edge, MacroAssembler::Jump jumpToFail, const SpeculationRecovery&);
2306     // Use this like you would use speculationCheck(), except that you don't pass it a jump
2307     // (because you don't have to execute a branch; that's kind of the whole point), and you
2308     // must register the returned Watchpoint with something relevant. In general, this should
2309     // be used with extreme care. Use speculationCheck() unless you've got an amazing reason
2310     // not to.
2311     JumpReplacementWatchpoint* speculationWatchpoint(ExitKind, JSValueSource, NodeIndex);
2312     // The default for speculation watchpoints is that they're uncounted, because the
2313     // act of firing a watchpoint invalidates it. So, future recompilations will not
2314     // attempt to set this watchpoint again.
2315     JumpReplacementWatchpoint* speculationWatchpoint(ExitKind = UncountableWatchpoint);
2316     
2317     // It is generally a good idea to not use this directly.
2318     void convertLastOSRExitToForward(const ValueRecovery& = ValueRecovery());
2319     
2320     // Note: not specifying the valueRecovery argument (leaving it as ValueRecovery()) implies
2321     // that you've ensured that there exists a MovHint prior to your use of forwardSpeculationCheck().
2322     void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, const ValueRecovery& = ValueRecovery());
2323     void forwardSpeculationCheck(ExitKind, JSValueSource, NodeIndex, MacroAssembler::JumpList& jumpsToFail, const ValueRecovery& = ValueRecovery());
2324     void speculationCheckWithConditionalDirection(ExitKind, JSValueSource, NodeIndex, MacroAssembler::Jump jumpToFail, bool isForward);
2325     // Called when we statically determine that a speculation will fail.
2326     void terminateSpeculativeExecution(ExitKind, JSValueRegs, NodeIndex);
2327     void terminateSpeculativeExecution(ExitKind, JSValueRegs, Edge);
2328     void terminateSpeculativeExecutionWithConditionalDirection(ExitKind, JSValueRegs, NodeIndex, bool isForward);
2329     // Issue a forward speculation watchpoint, which will exit to the next instruction rather
2330     // than the current one.
2331     JumpReplacementWatchpoint* forwardSpeculationWatchpoint(ExitKind = UncountableWatchpoint);
2332     JumpReplacementWatchpoint* speculationWatchpointWithConditionalDirection(ExitKind, bool isForward);
2333     
2334     const TypedArrayDescriptor* typedArrayDescriptor(Array::Mode);
2335     
2336     void checkArray(Node&);
2337     void arrayify(Node&);
2338     
2339     template<bool strict>
2340     GPRReg fillSpeculateIntInternal(NodeIndex, DataFormat& returnFormat);
2341     
2342     // It is possible, during speculative generation, to reach a situation in which we
2343     // can statically determine a speculation will fail (for example, when two nodes
2344     // will make conflicting speculations about the same operand). In such cases this
2345     // flag is cleared, indicating no further code generation should take place.
2346     bool m_compileOkay;
2347     
2348     // Tracking for which nodes are currently holding the values of arguments and bytecode
2349     // operand-indexed variables.
2350     
2351     ValueSource valueSourceForOperand(int operand)
2352     {
2353         return valueSourceReferenceForOperand(operand);
2354     }
2355     
2356     void setNodeIndexForOperand(NodeIndex nodeIndex, int operand)
2357     {
2358         valueSourceReferenceForOperand(operand) = ValueSource(nodeIndex);
2359     }
2360     
2361     // Call this with care, since it both returns a reference into an array
2362     // and potentially resizes the array. So it would not be right to call this
2363     // twice and then perform operands on both references, since the one from
2364     // the first call may no longer be valid.
2365     ValueSource& valueSourceReferenceForOperand(int operand)
2366     {
2367         if (operandIsArgument(operand)) {
2368             int argument = operandToArgument(operand);
2369             return m_arguments[argument];
2370         }
2371         
2372         if ((unsigned)operand >= m_variables.size())
2373             m_variables.resize(operand + 1);
2374         
2375         return m_variables[operand];
2376     }
2377     
2378     void recordSetLocal(int operand, ValueSource valueSource)
2379     {
2380         valueSourceReferenceForOperand(operand) = valueSource;
2381         m_stream->appendAndLog(VariableEvent::setLocal(operand, valueSource.dataFormat()));
2382     }
2383     
2384     // The JIT, while also provides MacroAssembler functionality.
2385     JITCompiler& m_jit;
2386
2387     // The current node being generated.
2388     BlockIndex m_block;
2389     NodeIndex m_compileIndex;
2390     unsigned m_indexInBlock;
2391     // Virtual and physical register maps.
2392     Vector<GenerationInfo, 32> m_generationInfo;
2393     RegisterBank<GPRInfo> m_gprs;
2394     RegisterBank<FPRInfo> m_fprs;
2395
2396     Vector<MacroAssembler::Label> m_blockHeads;
2397     Vector<MacroAssembler::Label> m_osrEntryHeads;
2398     
2399     struct BranchRecord {
2400         BranchRecord(MacroAssembler::Jump jump, BlockIndex destination)
2401             : jump(jump)
2402             , destination(destination)
2403         {
2404         }
2405
2406         MacroAssembler::Jump jump;
2407         BlockIndex destination;
2408     };
2409     Vector<BranchRecord, 8> m_branches;
2410
2411     Vector<ValueSource, 0> m_arguments;
2412     Vector<ValueSource, 0> m_variables;
2413     int m_lastSetOperand;
2414     CodeOrigin m_codeOriginForOSR;
2415     
2416     AbstractState m_state;
2417     
2418     VariableEventStream* m_stream;
2419     MinifiedGraph* m_minifiedGraph;
2420     
2421     bool m_isCheckingArgumentTypes;
2422     
2423     Vector<SlowPathGenerator*, 8> m_slowPathGenerators; // doesn't use OwnPtr<> because I don't want to include DFGSlowPathGenerator.h
2424     Vector<SilentRegisterSavePlan> m_plans;
2425     
2426     ValueRecovery computeValueRecoveryFor(const ValueSource&);
2427
2428     ValueRecovery computeValueRecoveryFor(int operand)
2429     {
2430         return computeValueRecoveryFor(valueSourceForOperand(operand));
2431     }
2432 };
2433
2434
2435 // === Operand types ===
2436 //
2437 // IntegerOperand, DoubleOperand and JSValueOperand.
2438 //
2439 // These classes are used to lock the operands to a node into machine
2440 // registers. These classes implement of pattern of locking a value
2441 // into register at the point of construction only if it is already in
2442 // registers, and otherwise loading it lazily at the point it is first
2443 // used. We do so in order to attempt to avoid spilling one operand
2444 // in order to make space available for another.
2445
2446 class IntegerOperand {
2447 public:
2448     explicit IntegerOperand(SpeculativeJIT* jit, Edge use)
2449         : m_jit(jit)
2450         , m_index(use.index())
2451         , m_gprOrInvalid(InvalidGPRReg)
2452 #ifndef NDEBUG
2453         , m_format(DataFormatNone)
2454 #endif
2455     {
2456         ASSERT(m_jit);
2457         ASSERT(use.useKind() != DoubleUse);
2458         if (jit->isFilled(m_index))
2459             gpr();
2460     }
2461
2462     ~IntegerOperand()
2463     {
2464         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2465         m_jit->unlock(m_gprOrInvalid);
2466     }
2467
2468     NodeIndex index() const
2469     {
2470         return m_index;
2471     }
2472
2473     DataFormat format()
2474     {
2475         gpr(); // m_format is set when m_gpr is locked.
2476         ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
2477         return m_format;
2478     }
2479
2480     GPRReg gpr()
2481     {
2482         if (m_gprOrInvalid == InvalidGPRReg)
2483             m_gprOrInvalid = m_jit->fillInteger(index(), m_format);
2484         return m_gprOrInvalid;
2485     }
2486     
2487     void use()
2488     {
2489         m_jit->use(m_index);
2490     }
2491
2492 private:
2493     SpeculativeJIT* m_jit;
2494     NodeIndex m_index;
2495     GPRReg m_gprOrInvalid;
2496     DataFormat m_format;
2497 };
2498
2499 class DoubleOperand {
2500 public:
2501     explicit DoubleOperand(SpeculativeJIT* jit, Edge use)
2502         : m_jit(jit)
2503         , m_index(use.index())
2504         , m_fprOrInvalid(InvalidFPRReg)
2505     {
2506         ASSERT(m_jit);
2507         
2508         // This is counter-intuitive but correct. DoubleOperand is intended to
2509         // be used only when you're a node that is happy to accept an untyped
2510         // value, but will special-case for doubles (using DoubleOperand) if the
2511         // value happened to already be represented as a double. The implication
2512         // is that you will not try to force the value to become a double if it
2513         // is not one already.
2514         ASSERT(use.useKind() != DoubleUse);
2515         
2516         if (jit->isFilledDouble(m_index))
2517             fpr();
2518     }
2519
2520     ~DoubleOperand()
2521     {
2522         ASSERT(m_fprOrInvalid != InvalidFPRReg);
2523         m_jit->unlock(m_fprOrInvalid);
2524     }
2525
2526     NodeIndex index() const
2527     {
2528         return m_index;
2529     }
2530
2531     FPRReg fpr()
2532     {
2533         if (m_fprOrInvalid == InvalidFPRReg)
2534             m_fprOrInvalid = m_jit->fillDouble(index());
2535         return m_fprOrInvalid;
2536     }
2537     
2538     void use()
2539     {
2540         m_jit->use(m_index);
2541     }
2542
2543 private:
2544     SpeculativeJIT* m_jit;
2545     NodeIndex m_index;
2546     FPRReg m_fprOrInvalid;
2547 };
2548
2549 class JSValueOperand {
2550 public:
2551     explicit JSValueOperand(SpeculativeJIT* jit, Edge use)
2552         : m_jit(jit)
2553         , m_index(use.index())
2554 #if USE(JSVALUE64)
2555         , m_gprOrInvalid(InvalidGPRReg)
2556 #elif USE(JSVALUE32_64)
2557         , m_isDouble(false)
2558 #endif
2559     {
2560         ASSERT(m_jit);
2561         ASSERT(use.useKind() != DoubleUse);
2562 #if USE(JSVALUE64)
2563         if (jit->isFilled(m_index))
2564             gpr();
2565 #elif USE(JSVALUE32_64)
2566         m_register.pair.tagGPR = InvalidGPRReg;
2567         m_register.pair.payloadGPR = InvalidGPRReg;
2568         if (jit->isFilled(m_index))
2569             fill();
2570 #endif
2571     }
2572
2573     ~JSValueOperand()
2574     {
2575 #if USE(JSVALUE64)
2576         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2577         m_jit->unlock(m_gprOrInvalid);
2578 #elif USE(JSVALUE32_64)
2579         if (m_isDouble) {
2580             ASSERT(m_register.fpr != InvalidFPRReg);
2581             m_jit->unlock(m_register.fpr);
2582         } else {
2583             ASSERT(m_register.pair.tagGPR != InvalidGPRReg && m_register.pair.payloadGPR != InvalidGPRReg);
2584             m_jit->unlock(m_register.pair.tagGPR);
2585             m_jit->unlock(m_register.pair.payloadGPR);
2586         }
2587 #endif
2588     }
2589
2590     NodeIndex index() const
2591     {
2592         return m_index;
2593     }
2594
2595 #if USE(JSVALUE64)
2596     GPRReg gpr()
2597     {
2598         if (m_gprOrInvalid == InvalidGPRReg)
2599             m_gprOrInvalid = m_jit->fillJSValue(index());
2600         return m_gprOrInvalid;
2601     }
2602     JSValueRegs jsValueRegs()
2603     {
2604         return JSValueRegs(gpr());
2605     }
2606 #elif USE(JSVALUE32_64)
2607     bool isDouble() { return m_isDouble; }
2608
2609     void fill()
2610     {
2611         if (m_register.pair.tagGPR == InvalidGPRReg && m_register.pair.payloadGPR == InvalidGPRReg)
2612             m_isDouble = !m_jit->fillJSValue(index(), m_register.pair.tagGPR, m_register.pair.payloadGPR, m_register.fpr);
2613     }
2614
2615     GPRReg tagGPR()
2616     {
2617         fill();
2618         ASSERT(!m_isDouble);
2619         return m_register.pair.tagGPR;
2620     }
2621
2622     GPRReg payloadGPR()
2623     {
2624         fill();
2625         ASSERT(!m_isDouble);
2626         return m_register.pair.payloadGPR;
2627     }
2628
2629     JSValueRegs jsValueRegs()
2630     {
2631         return JSValueRegs(tagGPR(), payloadGPR());
2632     }
2633
2634     FPRReg fpr()
2635     {
2636         fill();
2637         ASSERT(m_isDouble);
2638         return m_register.fpr;
2639     }
2640 #endif
2641
2642     void use()
2643     {
2644         m_jit->use(m_index);
2645     }
2646
2647 private:
2648     SpeculativeJIT* m_jit;
2649     NodeIndex m_index;
2650 #if USE(JSVALUE64)
2651     GPRReg m_gprOrInvalid;
2652 #elif USE(JSVALUE32_64)
2653     union {
2654         struct {
2655             GPRReg tagGPR;
2656             GPRReg payloadGPR;
2657         } pair;
2658         FPRReg fpr;
2659     } m_register;
2660     bool m_isDouble;
2661 #endif
2662 };
2663
2664 class StorageOperand {
2665 public:
2666     explicit StorageOperand(SpeculativeJIT* jit, Edge use)
2667         : m_jit(jit)
2668         , m_index(use.index())
2669         , m_gprOrInvalid(InvalidGPRReg)
2670     {
2671         ASSERT(m_jit);
2672         ASSERT(use.useKind() != DoubleUse);
2673         if (jit->isFilled(m_index))
2674             gpr();
2675     }
2676     
2677     ~StorageOperand()
2678     {
2679         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2680         m_jit->unlock(m_gprOrInvalid);
2681     }
2682     
2683     NodeIndex index() const
2684     {
2685         return m_index;
2686     }
2687     
2688     GPRReg gpr()
2689     {
2690         if (m_gprOrInvalid == InvalidGPRReg)
2691             m_gprOrInvalid = m_jit->fillStorage(index());
2692         return m_gprOrInvalid;
2693     }
2694     
2695     void use()
2696     {
2697         m_jit->use(m_index);
2698     }
2699     
2700 private:
2701     SpeculativeJIT* m_jit;
2702     NodeIndex m_index;
2703     GPRReg m_gprOrInvalid;
2704 };
2705
2706
2707 // === Temporaries ===
2708 //
2709 // These classes are used to allocate temporary registers.
2710 // A mechanism is provided to attempt to reuse the registers
2711 // currently allocated to child nodes whose value is consumed
2712 // by, and not live after, this operation.
2713
2714 class GPRTemporary {
2715 public:
2716     GPRTemporary();
2717     GPRTemporary(SpeculativeJIT*);
2718     GPRTemporary(SpeculativeJIT*, GPRReg specific);
2719     GPRTemporary(SpeculativeJIT*, SpeculateIntegerOperand&);
2720     GPRTemporary(SpeculativeJIT*, SpeculateIntegerOperand&, SpeculateIntegerOperand&);
2721     GPRTemporary(SpeculativeJIT*, SpeculateStrictInt32Operand&);
2722     GPRTemporary(SpeculativeJIT*, IntegerOperand&);
2723     GPRTemporary(SpeculativeJIT*, IntegerOperand&, IntegerOperand&);
2724     GPRTemporary(SpeculativeJIT*, SpeculateCellOperand&);
2725     GPRTemporary(SpeculativeJIT*, SpeculateBooleanOperand&);
2726 #if USE(JSVALUE64)
2727     GPRTemporary(SpeculativeJIT*, JSValueOperand&);
2728 #elif USE(JSVALUE32_64)
2729     GPRTemporary(SpeculativeJIT*, JSValueOperand&, bool tag = true);
2730 #endif
2731     GPRTemporary(SpeculativeJIT*, StorageOperand&);
2732
2733     void adopt(GPRTemporary&);
2734
2735     ~GPRTemporary()
2736     {
2737         if (m_jit && m_gpr != InvalidGPRReg)
2738             m_jit->unlock(gpr());
2739     }
2740
2741     GPRReg gpr()
2742     {
2743         return m_gpr;
2744     }
2745
2746 private:
2747     SpeculativeJIT* m_jit;
2748     GPRReg m_gpr;
2749 };
2750
2751 class FPRTemporary {
2752 public:
2753     FPRTemporary(SpeculativeJIT*);
2754     FPRTemporary(SpeculativeJIT*, DoubleOperand&);
2755     FPRTemporary(SpeculativeJIT*, DoubleOperand&, DoubleOperand&);
2756     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&);
2757     FPRTemporary(SpeculativeJIT*, SpeculateDoubleOperand&, SpeculateDoubleOperand&);
2758 #if USE(JSVALUE32_64)
2759     FPRTemporary(SpeculativeJIT*, JSValueOperand&);
2760 #endif
2761
2762     ~FPRTemporary()
2763     {
2764         m_jit->unlock(fpr());
2765     }
2766
2767     FPRReg fpr() const
2768     {
2769         ASSERT(m_fpr != InvalidFPRReg);
2770         return m_fpr;
2771     }
2772
2773 protected:
2774     FPRTemporary(SpeculativeJIT* jit, FPRReg lockedFPR)
2775         : m_jit(jit)
2776         , m_fpr(lockedFPR)
2777     {
2778     }
2779
2780 private:
2781     SpeculativeJIT* m_jit;
2782     FPRReg m_fpr;
2783 };
2784
2785
2786 // === Results ===
2787 //
2788 // These classes lock the result of a call to a C++ helper function.
2789
2790 class GPRResult : public GPRTemporary {
2791 public:
2792     GPRResult(SpeculativeJIT* jit)
2793         : GPRTemporary(jit, GPRInfo::returnValueGPR)
2794     {
2795     }
2796 };
2797
2798 #if USE(JSVALUE32_64)
2799 class GPRResult2 : public GPRTemporary {
2800 public:
2801     GPRResult2(SpeculativeJIT* jit)
2802         : GPRTemporary(jit, GPRInfo::returnValueGPR2)
2803     {
2804     }
2805 };
2806 #endif
2807
2808 class FPRResult : public FPRTemporary {
2809 public:
2810     FPRResult(SpeculativeJIT* jit)
2811         : FPRTemporary(jit, lockedResult(jit))
2812     {
2813     }
2814
2815 private:
2816     static FPRReg lockedResult(SpeculativeJIT* jit)
2817     {
2818         jit->lock(FPRInfo::returnValueFPR);
2819         return FPRInfo::returnValueFPR;
2820     }
2821 };
2822
2823
2824 // === Speculative Operand types ===
2825 //
2826 // SpeculateIntegerOperand, SpeculateStrictInt32Operand and SpeculateCellOperand.
2827 //
2828 // These are used to lock the operands to a node into machine registers within the
2829 // SpeculativeJIT. The classes operate like those above, however these will
2830 // perform a speculative check for a more restrictive type than we can statically
2831 // determine the operand to have. If the operand does not have the requested type,
2832 // a bail-out to the non-speculative path will be taken.
2833
2834 class SpeculateIntegerOperand {
2835 public:
2836     explicit SpeculateIntegerOperand(SpeculativeJIT* jit, Edge use)
2837         : m_jit(jit)
2838         , m_index(use.index())
2839         , m_gprOrInvalid(InvalidGPRReg)
2840 #ifndef NDEBUG
2841         , m_format(DataFormatNone)
2842 #endif
2843     {
2844         ASSERT(m_jit);
2845         ASSERT(use.useKind() != DoubleUse);
2846         if (jit->isFilled(m_index))
2847             gpr();
2848     }
2849
2850     ~SpeculateIntegerOperand()
2851     {
2852         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2853         m_jit->unlock(m_gprOrInvalid);
2854     }
2855
2856     NodeIndex index() const
2857     {
2858         return m_index;
2859     }
2860
2861     DataFormat format()
2862     {
2863         gpr(); // m_format is set when m_gpr is locked.
2864         ASSERT(m_format == DataFormatInteger || m_format == DataFormatJSInteger);
2865         return m_format;
2866     }
2867
2868     GPRReg gpr()
2869     {
2870         if (m_gprOrInvalid == InvalidGPRReg)
2871             m_gprOrInvalid = m_jit->fillSpeculateInt(index(), m_format);
2872         return m_gprOrInvalid;
2873     }
2874
2875 private:
2876     SpeculativeJIT* m_jit;
2877     NodeIndex m_index;
2878     GPRReg m_gprOrInvalid;
2879     DataFormat m_format;
2880 };
2881
2882 class SpeculateStrictInt32Operand {
2883 public:
2884     explicit SpeculateStrictInt32Operand(SpeculativeJIT* jit, Edge use)
2885         : m_jit(jit)
2886         , m_index(use.index())
2887         , m_gprOrInvalid(InvalidGPRReg)
2888     {
2889         ASSERT(m_jit);
2890         ASSERT(use.useKind() != DoubleUse);
2891         if (jit->isFilled(m_index))
2892             gpr();
2893     }
2894
2895     ~SpeculateStrictInt32Operand()
2896     {
2897         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2898         m_jit->unlock(m_gprOrInvalid);
2899     }
2900
2901     NodeIndex index() const
2902     {
2903         return m_index;
2904     }
2905
2906     GPRReg gpr()
2907     {
2908         if (m_gprOrInvalid == InvalidGPRReg)
2909             m_gprOrInvalid = m_jit->fillSpeculateIntStrict(index());
2910         return m_gprOrInvalid;
2911     }
2912     
2913     void use()
2914     {
2915         m_jit->use(m_index);
2916     }
2917
2918 private:
2919     SpeculativeJIT* m_jit;
2920     NodeIndex m_index;
2921     GPRReg m_gprOrInvalid;
2922 };
2923
2924 class SpeculateDoubleOperand {
2925 public:
2926     explicit SpeculateDoubleOperand(SpeculativeJIT* jit, Edge use)
2927         : m_jit(jit)
2928         , m_index(use.index())
2929         , m_fprOrInvalid(InvalidFPRReg)
2930     {
2931         ASSERT(m_jit);
2932         ASSERT(use.useKind() == DoubleUse);
2933         if (jit->isFilled(m_index))
2934             fpr();
2935     }
2936
2937     ~SpeculateDoubleOperand()
2938     {
2939         ASSERT(m_fprOrInvalid != InvalidFPRReg);
2940         m_jit->unlock(m_fprOrInvalid);
2941     }
2942
2943     NodeIndex index() const
2944     {
2945         return m_index;
2946     }
2947
2948     FPRReg fpr()
2949     {
2950         if (m_fprOrInvalid == InvalidFPRReg)
2951             m_fprOrInvalid = m_jit->fillSpeculateDouble(index());
2952         return m_fprOrInvalid;
2953     }
2954
2955 private:
2956     SpeculativeJIT* m_jit;
2957     NodeIndex m_index;
2958     FPRReg m_fprOrInvalid;
2959 };
2960
2961 class SpeculateCellOperand {
2962 public:
2963     explicit SpeculateCellOperand(SpeculativeJIT* jit, Edge use, bool isForwardSpeculation = false)
2964         : m_jit(jit)
2965         , m_index(use.index())
2966         , m_gprOrInvalid(InvalidGPRReg)
2967         , m_isForwardSpeculation(isForwardSpeculation)
2968     {
2969         ASSERT(m_jit);
2970         ASSERT(use.useKind() != DoubleUse);
2971         if (jit->isFilled(m_index))
2972             gpr();
2973     }
2974
2975     ~SpeculateCellOperand()
2976     {
2977         ASSERT(m_gprOrInvalid != InvalidGPRReg);
2978         m_jit->unlock(m_gprOrInvalid);
2979     }
2980
2981     NodeIndex index() const
2982     {
2983         return m_index;
2984     }
2985
2986     GPRReg gpr()
2987     {
2988         if (m_gprOrInvalid == InvalidGPRReg)
2989             m_gprOrInvalid = m_jit->fillSpeculateCell(index(), m_isForwardSpeculation);
2990         return m_gprOrInvalid;
2991     }
2992     
2993     void use()
2994     {
2995         m_jit->use(m_index);
2996     }
2997
2998 private:
2999     SpeculativeJIT* m_jit;
3000     NodeIndex m_index;
3001     GPRReg m_gprOrInvalid;
3002     bool m_isForwardSpeculation;
3003 };
3004
3005 class SpeculateBooleanOperand {
3006 public:
3007     explicit SpeculateBooleanOperand(SpeculativeJIT* jit, Edge use)
3008         : m_jit(jit)
3009         , m_index(use.index())
3010         , m_gprOrInvalid(InvalidGPRReg)
3011     {
3012         ASSERT(m_jit);
3013         ASSERT(use.useKind() != DoubleUse);
3014         if (jit->isFilled(m_index))
3015             gpr();
3016     }
3017     
3018     ~SpeculateBooleanOperand()
3019     {
3020         ASSERT(m_gprOrInvalid != InvalidGPRReg);
3021         m_jit->unlock(m_gprOrInvalid);
3022     }
3023     
3024     NodeIndex index() const
3025     {
3026         return m_index;
3027     }
3028     
3029     GPRReg gpr()
3030     {
3031         if (m_gprOrInvalid == InvalidGPRReg)
3032             m_gprOrInvalid = m_jit->fillSpeculateBoolean(index());
3033         return m_gprOrInvalid;
3034     }
3035     
3036     void use()
3037     {
3038         m_jit->use(m_index);
3039     }
3040
3041 private:
3042     SpeculativeJIT* m_jit;
3043     NodeIndex m_index;
3044     GPRReg m_gprOrInvalid;
3045 };
3046
3047 } } // namespace JSC::DFG
3048
3049 #endif
3050 #endif
3051