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