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