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