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