db59f637ea86bf6ea6a567367be91d5b6741a556
[WebKit.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT32_64.cpp
1 /*
2  * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
3  * Copyright (C) 2011 Intel Corporation. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #include "config.h"
28 #include "DFGSpeculativeJIT.h"
29
30 #if ENABLE(DFG_JIT)
31
32 #include "ArrayPrototype.h"
33 #include "CallFrameShuffler.h"
34 #include "DFGAbstractInterpreterInlines.h"
35 #include "DFGCallArrayAllocatorSlowPathGenerator.h"
36 #include "DFGOperations.h"
37 #include "DFGSlowPathGenerator.h"
38 #include "DirectArguments.h"
39 #include "GetterSetter.h"
40 #include "HasOwnPropertyCache.h"
41 #include "HashMapImpl.h"
42 #include "JSEnvironmentRecord.h"
43 #include "JSPropertyNameEnumerator.h"
44 #include "ObjectPrototype.h"
45 #include "JSCInlines.h"
46 #include "SetupVarargsFrame.h"
47 #include "TypeProfilerLog.h"
48 #include "Watchdog.h"
49
50 namespace JSC { namespace DFG {
51
52 #if USE(JSVALUE32_64)
53
54 static_assert(SpecCellCheck == SpecCell, "This is strongly assumed in the 32-bit DFG backend.");
55
56 bool SpeculativeJIT::fillJSValue(Edge edge, GPRReg& tagGPR, GPRReg& payloadGPR, FPRReg& fpr)
57 {
58     // FIXME: For double we could fill with a FPR.
59     UNUSED_PARAM(fpr);
60
61     VirtualRegister virtualRegister = edge->virtualRegister();
62     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
63
64     switch (info.registerFormat()) {
65     case DataFormatNone: {
66
67         if (edge->hasConstant()) {
68             tagGPR = allocate();
69             payloadGPR = allocate();
70             JSValue value = edge->asJSValue();
71             m_jit.move(Imm32(value.tag()), tagGPR);
72             m_jit.move(Imm32(value.payload()), payloadGPR);
73             m_gprs.retain(tagGPR, virtualRegister, SpillOrderConstant);
74             m_gprs.retain(payloadGPR, virtualRegister, SpillOrderConstant);
75             info.fillJSValue(*m_stream, tagGPR, payloadGPR, DataFormatJS);
76         } else {
77             DataFormat spillFormat = info.spillFormat();
78             ASSERT(spillFormat != DataFormatNone && spillFormat != DataFormatStorage);
79             tagGPR = allocate();
80             payloadGPR = allocate();
81             switch (spillFormat) {
82             case DataFormatInt32:
83                 m_jit.move(TrustedImm32(JSValue::Int32Tag), tagGPR);
84                 spillFormat = DataFormatJSInt32; // This will be used as the new register format.
85                 break;
86             case DataFormatCell:
87                 m_jit.move(TrustedImm32(JSValue::CellTag), tagGPR);
88                 spillFormat = DataFormatJSCell; // This will be used as the new register format.
89                 break;
90             case DataFormatBoolean:
91                 m_jit.move(TrustedImm32(JSValue::BooleanTag), tagGPR);
92                 spillFormat = DataFormatJSBoolean; // This will be used as the new register format.
93                 break;
94             default:
95                 m_jit.load32(JITCompiler::tagFor(virtualRegister), tagGPR);
96                 break;
97             }
98             m_jit.load32(JITCompiler::payloadFor(virtualRegister), payloadGPR);
99             m_gprs.retain(tagGPR, virtualRegister, SpillOrderSpilled);
100             m_gprs.retain(payloadGPR, virtualRegister, SpillOrderSpilled);
101             info.fillJSValue(*m_stream, tagGPR, payloadGPR, spillFormat == DataFormatJSDouble ? DataFormatJS : spillFormat);
102         }
103
104         return true;
105     }
106
107     case DataFormatInt32:
108     case DataFormatCell:
109     case DataFormatBoolean: {
110         GPRReg gpr = info.gpr();
111         // If the register has already been locked we need to take a copy.
112         if (m_gprs.isLocked(gpr)) {
113             payloadGPR = allocate();
114             m_jit.move(gpr, payloadGPR);
115         } else {
116             payloadGPR = gpr;
117             m_gprs.lock(gpr);
118         }
119         tagGPR = allocate();
120         int32_t tag = JSValue::EmptyValueTag;
121         DataFormat fillFormat = DataFormatJS;
122         switch (info.registerFormat()) {
123         case DataFormatInt32:
124             tag = JSValue::Int32Tag;
125             fillFormat = DataFormatJSInt32;
126             break;
127         case DataFormatCell:
128             tag = JSValue::CellTag;
129             fillFormat = DataFormatJSCell;
130             break;
131         case DataFormatBoolean:
132             tag = JSValue::BooleanTag;
133             fillFormat = DataFormatJSBoolean;
134             break;
135         default:
136             RELEASE_ASSERT_NOT_REACHED();
137             break;
138         }
139         m_jit.move(TrustedImm32(tag), tagGPR);
140         m_gprs.release(gpr);
141         m_gprs.retain(tagGPR, virtualRegister, SpillOrderJS);
142         m_gprs.retain(payloadGPR, virtualRegister, SpillOrderJS);
143         info.fillJSValue(*m_stream, tagGPR, payloadGPR, fillFormat);
144         return true;
145     }
146
147     case DataFormatJSDouble:
148     case DataFormatJS:
149     case DataFormatJSInt32:
150     case DataFormatJSCell:
151     case DataFormatJSBoolean: {
152         tagGPR = info.tagGPR();
153         payloadGPR = info.payloadGPR();
154         m_gprs.lock(tagGPR);
155         m_gprs.lock(payloadGPR);
156         return true;
157     }
158         
159     case DataFormatStorage:
160     case DataFormatDouble:
161         // this type currently never occurs
162         RELEASE_ASSERT_NOT_REACHED();
163
164     default:
165         RELEASE_ASSERT_NOT_REACHED();
166         return true;
167     }
168 }
169
170 void SpeculativeJIT::cachedGetById(CodeOrigin origin, JSValueRegs base, JSValueRegs result, unsigned identifierNumber, JITCompiler::Jump slowPathTarget , SpillRegistersMode mode, AccessType type)
171 {
172     cachedGetById(origin, base.tagGPR(), base.payloadGPR(), result.tagGPR(), result.payloadGPR(), identifierNumber, slowPathTarget, mode, type);
173 }
174
175 void SpeculativeJIT::cachedGetById(
176     CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR,
177     unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode, AccessType type)
178 {
179     // This is a hacky fix for when the register allocator decides to alias the base payload with the result tag. This only happens
180     // in the case of GetByIdFlush, which has a relatively expensive register allocation story already so we probably don't need to
181     // trip over one move instruction.
182     if (basePayloadGPR == resultTagGPR) {
183         RELEASE_ASSERT(basePayloadGPR != resultPayloadGPR);
184         
185         if (baseTagGPROrNone == resultPayloadGPR) {
186             m_jit.swap(basePayloadGPR, baseTagGPROrNone);
187             baseTagGPROrNone = resultTagGPR;
188         } else
189             m_jit.move(basePayloadGPR, resultPayloadGPR);
190         basePayloadGPR = resultPayloadGPR;
191     }
192     
193     RegisterSet usedRegisters = this->usedRegisters();
194     if (spillMode == DontSpill) {
195         // We've already flushed registers to the stack, we don't need to spill these.
196         usedRegisters.set(JSValueRegs(baseTagGPROrNone, basePayloadGPR), false);
197         usedRegisters.set(JSValueRegs(resultTagGPR, resultPayloadGPR), false);
198     }
199     
200     CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
201     JITGetByIdGenerator gen(
202         m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifierUID(identifierNumber),
203         JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(resultTagGPR, resultPayloadGPR), type);
204     
205     gen.generateFastPath(m_jit);
206     
207     JITCompiler::JumpList slowCases;
208     if (slowPathTarget.isSet())
209         slowCases.append(slowPathTarget);
210     slowCases.append(gen.slowPathJump());
211
212     J_JITOperation_ESsiJI getByIdFunction;
213     if (type == AccessType::Get)
214         getByIdFunction = operationGetByIdOptimize;
215     else
216         getByIdFunction = operationTryGetByIdOptimize;
217
218     std::unique_ptr<SlowPathGenerator> slowPath;
219     if (baseTagGPROrNone == InvalidGPRReg) {
220         slowPath = slowPathCall(
221             slowCases, this, getByIdFunction,
222             JSValueRegs(resultTagGPR, resultPayloadGPR), gen.stubInfo(),
223             static_cast<int32_t>(JSValue::CellTag), basePayloadGPR,
224             identifierUID(identifierNumber));
225     } else {
226         slowPath = slowPathCall(
227             slowCases, this, getByIdFunction,
228             JSValueRegs(resultTagGPR, resultPayloadGPR), gen.stubInfo(), JSValueRegs(baseTagGPROrNone, basePayloadGPR), identifierUID(identifierNumber));
229     }
230
231     m_jit.addGetById(gen, slowPath.get());
232     addSlowPathGenerator(WTFMove(slowPath));
233 }
234
235 void SpeculativeJIT::cachedGetByIdWithThis(
236     CodeOrigin codeOrigin, GPRReg baseTagGPROrNone, GPRReg basePayloadGPR, GPRReg thisTagGPR, GPRReg thisPayloadGPR, GPRReg resultTagGPR, GPRReg resultPayloadGPR,
237     unsigned identifierNumber, JITCompiler::JumpList slowPathTarget)
238 {
239     RegisterSet usedRegisters = this->usedRegisters();
240     
241     CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
242     JITGetByIdWithThisGenerator gen(
243         m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifierUID(identifierNumber),
244         JSValueRegs(resultTagGPR, resultPayloadGPR), JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(thisTagGPR, thisPayloadGPR), AccessType::GetWithThis);
245     
246     gen.generateFastPath(m_jit);
247     
248     JITCompiler::JumpList slowCases;
249     if (!slowPathTarget.empty())
250         slowCases.append(slowPathTarget);
251     slowCases.append(gen.slowPathJump());
252
253     std::unique_ptr<SlowPathGenerator> slowPath;
254     if (baseTagGPROrNone == InvalidGPRReg && thisTagGPR == InvalidGPRReg) {
255         slowPath = slowPathCall(
256             slowCases, this, operationGetByIdWithThisOptimize,
257             JSValueRegs(resultTagGPR, resultPayloadGPR), gen.stubInfo(),
258             static_cast<int32_t>(JSValue::CellTag), basePayloadGPR,
259             static_cast<int32_t>(JSValue::CellTag), thisPayloadGPR,
260             identifierUID(identifierNumber));
261     } else {
262         ASSERT(baseTagGPROrNone != InvalidGPRReg);
263         ASSERT(thisTagGPR != InvalidGPRReg);
264         
265         slowPath = slowPathCall(
266             slowCases, this, operationGetByIdWithThisOptimize,
267             JSValueRegs(resultTagGPR, resultPayloadGPR), gen.stubInfo(), JSValueRegs(baseTagGPROrNone, basePayloadGPR), JSValueRegs(thisTagGPR, thisPayloadGPR), identifierUID(identifierNumber));
268     }
269
270     m_jit.addGetByIdWithThis(gen, slowPath.get());
271     addSlowPathGenerator(WTFMove(slowPath));
272 }
273
274 void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
275 {
276     RegisterSet usedRegisters = this->usedRegisters();
277     if (spillMode == DontSpill) {
278         // We've already flushed registers to the stack, we don't need to spill these.
279         usedRegisters.set(basePayloadGPR, false);
280         usedRegisters.set(JSValueRegs(valueTagGPR, valuePayloadGPR), false);
281     }
282     CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
283     JITPutByIdGenerator gen(
284         m_jit.codeBlock(), codeOrigin, callSite, usedRegisters,
285         JSValueRegs::payloadOnly(basePayloadGPR), JSValueRegs(valueTagGPR, valuePayloadGPR),
286         scratchGPR, m_jit.ecmaModeFor(codeOrigin), putKind);
287     
288     gen.generateFastPath(m_jit);
289     
290     JITCompiler::JumpList slowCases;
291     if (slowPathTarget.isSet())
292         slowCases.append(slowPathTarget);
293     slowCases.append(gen.slowPathJump());
294
295     auto slowPath = slowPathCall(
296         slowCases, this, gen.slowPathFunction(), NoResult, gen.stubInfo(), JSValueRegs(valueTagGPR, valuePayloadGPR),
297         basePayloadGPR, identifierUID(identifierNumber));
298
299     m_jit.addPutById(gen, slowPath.get());
300     addSlowPathGenerator(WTFMove(slowPath));
301 }
302
303 void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operand)
304 {
305     JSValueOperand arg(this, operand, ManualOperandSpeculation);
306     GPRReg argTagGPR = arg.tagGPR();
307     GPRReg argPayloadGPR = arg.payloadGPR();
308
309     GPRTemporary resultPayload(this, Reuse, arg, PayloadWord);
310     GPRReg resultPayloadGPR = resultPayload.gpr();
311
312     JITCompiler::Jump notCell;
313     JITCompiler::Jump notMasqueradesAsUndefined;   
314     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
315         if (!isKnownCell(operand.node()))
316             notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
317         
318         m_jit.move(TrustedImm32(0), resultPayloadGPR);
319         notMasqueradesAsUndefined = m_jit.jump();
320     } else {
321         GPRTemporary localGlobalObject(this);
322         GPRTemporary remoteGlobalObject(this);
323
324         if (!isKnownCell(operand.node()))
325             notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
326         
327         JITCompiler::Jump isMasqueradesAsUndefined = m_jit.branchTest8(
328             JITCompiler::NonZero, 
329             JITCompiler::Address(argPayloadGPR, JSCell::typeInfoFlagsOffset()), 
330             JITCompiler::TrustedImm32(MasqueradesAsUndefined));
331         
332         m_jit.move(TrustedImm32(0), resultPayloadGPR);
333         notMasqueradesAsUndefined = m_jit.jump();
334
335         isMasqueradesAsUndefined.link(&m_jit);
336         GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
337         GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
338         m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)), localGlobalObjectGPR);
339         m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureIDOffset()), resultPayloadGPR);
340         m_jit.loadPtr(JITCompiler::Address(resultPayloadGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
341         m_jit.compare32(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, resultPayloadGPR);
342     }
343  
344     if (!isKnownCell(operand.node())) {
345         JITCompiler::Jump done = m_jit.jump();
346         
347         notCell.link(&m_jit);
348         // null or undefined?
349         COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
350         m_jit.or32(TrustedImm32(1), argTagGPR, resultPayloadGPR);
351         m_jit.compare32(JITCompiler::Equal, resultPayloadGPR, TrustedImm32(JSValue::NullTag), resultPayloadGPR);
352
353         done.link(&m_jit);
354     }
355     
356     notMasqueradesAsUndefined.link(&m_jit);
357  
358     booleanResult(resultPayloadGPR, m_currentNode);
359 }
360
361 void SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, Node* branchNode)
362 {
363     BasicBlock* taken = branchNode->branchData()->taken.block;
364     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
365
366     bool invert = false;
367     if (taken == nextBlock()) {
368         invert = !invert;
369         BasicBlock* tmp = taken;
370         taken = notTaken;
371         notTaken = tmp;
372     }
373
374     JSValueOperand arg(this, operand, ManualOperandSpeculation);
375     GPRReg argTagGPR = arg.tagGPR();
376     GPRReg argPayloadGPR = arg.payloadGPR();
377     
378     GPRTemporary result(this, Reuse, arg, TagWord);
379     GPRReg resultGPR = result.gpr();
380
381     JITCompiler::Jump notCell;
382
383     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
384         if (!isKnownCell(operand.node()))
385             notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
386         
387         jump(invert ? taken : notTaken, ForceJump);
388     } else {
389         GPRTemporary localGlobalObject(this);
390         GPRTemporary remoteGlobalObject(this);
391
392         if (!isKnownCell(operand.node()))
393             notCell = m_jit.branchIfNotCell(arg.jsValueRegs());
394         
395         branchTest8(JITCompiler::Zero, 
396             JITCompiler::Address(argPayloadGPR, JSCell::typeInfoFlagsOffset()), 
397             JITCompiler::TrustedImm32(MasqueradesAsUndefined), 
398             invert ? taken : notTaken);
399    
400         GPRReg localGlobalObjectGPR = localGlobalObject.gpr();
401         GPRReg remoteGlobalObjectGPR = remoteGlobalObject.gpr();
402         m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic)), localGlobalObjectGPR);
403         m_jit.loadPtr(JITCompiler::Address(argPayloadGPR, JSCell::structureIDOffset()), resultGPR);
404         m_jit.loadPtr(JITCompiler::Address(resultGPR, Structure::globalObjectOffset()), remoteGlobalObjectGPR);
405         branchPtr(JITCompiler::Equal, localGlobalObjectGPR, remoteGlobalObjectGPR, invert ? notTaken : taken);
406     }
407  
408     if (!isKnownCell(operand.node())) {
409         jump(notTaken, ForceJump);
410         
411         notCell.link(&m_jit);
412         // null or undefined?
413         COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
414         m_jit.or32(TrustedImm32(1), argTagGPR, resultGPR);
415         branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImm32(JSValue::NullTag), taken);
416     }
417     
418     jump(notTaken);
419 }
420
421 void SpeculativeJIT::nonSpeculativePeepholeBranch(Node* node, Node* branchNode, MacroAssembler::RelationalCondition cond, S_JITOperation_EJJ helperFunction)
422 {
423     BasicBlock* taken = branchNode->branchData()->taken.block;
424     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
425
426     JITCompiler::ResultCondition callResultCondition = JITCompiler::NonZero;
427
428     // The branch instruction will branch to the taken block.
429     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
430     if (taken == nextBlock()) {
431         cond = JITCompiler::invert(cond);
432         callResultCondition = JITCompiler::Zero;
433         BasicBlock* tmp = taken;
434         taken = notTaken;
435         notTaken = tmp;
436     }
437
438     JSValueOperand arg1(this, node->child1());
439     JSValueOperand arg2(this, node->child2());
440     JSValueRegs arg1Regs = arg1.jsValueRegs();
441     JSValueRegs arg2Regs = arg2.jsValueRegs();
442     GPRReg arg1TagGPR = arg1.tagGPR();
443     GPRReg arg1PayloadGPR = arg1.payloadGPR();
444     GPRReg arg2TagGPR = arg2.tagGPR();
445     GPRReg arg2PayloadGPR = arg2.payloadGPR();
446     
447     JITCompiler::JumpList slowPath;
448     
449     if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
450         GPRFlushedCallResult result(this);
451         GPRReg resultGPR = result.gpr();
452
453         arg1.use();
454         arg2.use();
455
456         flushRegisters();
457         callOperation(helperFunction, resultGPR, arg1Regs, arg2Regs);
458         m_jit.exceptionCheck();
459
460         branchTest32(callResultCondition, resultGPR, taken);
461     } else {
462         GPRTemporary result(this);
463         GPRReg resultGPR = result.gpr();
464     
465         arg1.use();
466         arg2.use();
467
468         if (!isKnownInteger(node->child1().node()))
469             slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg1TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
470         if (!isKnownInteger(node->child2().node()))
471             slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg2TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
472     
473         branch32(cond, arg1PayloadGPR, arg2PayloadGPR, taken);
474     
475         if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
476             jump(notTaken, ForceJump);
477     
478             slowPath.link(&m_jit);
479     
480             silentSpillAllRegisters(resultGPR);
481             callOperation(helperFunction, resultGPR, arg1Regs, arg2Regs);
482             m_jit.exceptionCheck();
483             silentFillAllRegisters();
484         
485             branchTest32(callResultCondition, resultGPR, taken);
486         }
487     }
488
489     jump(notTaken);
490     
491     m_indexInBlock = m_block->size() - 1;
492     m_currentNode = branchNode;
493 }
494
495 template<typename JumpType>
496 class CompareAndBoxBooleanSlowPathGenerator
497     : public CallSlowPathGenerator<JumpType, S_JITOperation_EJJ, GPRReg> {
498 public:
499     CompareAndBoxBooleanSlowPathGenerator(
500         JumpType from, SpeculativeJIT* jit,
501         S_JITOperation_EJJ function, GPRReg result, GPRReg arg1Tag, GPRReg arg1Payload,
502         GPRReg arg2Tag, GPRReg arg2Payload)
503         : CallSlowPathGenerator<JumpType, S_JITOperation_EJJ, GPRReg>(
504             from, jit, function, NeedToSpill, ExceptionCheckRequirement::CheckNeeded, result)
505         , m_arg1Tag(arg1Tag)
506         , m_arg1Payload(arg1Payload)
507         , m_arg2Tag(arg2Tag)
508         , m_arg2Payload(arg2Payload)
509     {
510     }
511     
512 protected:
513     virtual void generateInternal(SpeculativeJIT* jit)
514     {
515         this->setUp(jit);
516         this->recordCall(
517             jit->callOperation(
518                 this->m_function, this->m_result, JSValueRegs(m_arg1Tag, m_arg1Payload), JSValueRegs(m_arg2Tag, m_arg2Payload)));
519         jit->m_jit.and32(JITCompiler::TrustedImm32(1), this->m_result);
520         this->tearDown(jit);
521     }
522    
523 private:
524     GPRReg m_arg1Tag;
525     GPRReg m_arg1Payload;
526     GPRReg m_arg2Tag;
527     GPRReg m_arg2Payload;
528 };
529
530 void SpeculativeJIT::nonSpeculativeNonPeepholeCompare(Node* node, MacroAssembler::RelationalCondition cond, S_JITOperation_EJJ helperFunction)
531 {
532     JSValueOperand arg1(this, node->child1());
533     JSValueOperand arg2(this, node->child2());
534     GPRReg arg1TagGPR = arg1.tagGPR();
535     GPRReg arg1PayloadGPR = arg1.payloadGPR();
536     GPRReg arg2TagGPR = arg2.tagGPR();
537     GPRReg arg2PayloadGPR = arg2.payloadGPR();
538     
539     JITCompiler::JumpList slowPath;
540     
541     if (isKnownNotInteger(node->child1().node()) || isKnownNotInteger(node->child2().node())) {
542         GPRFlushedCallResult result(this);
543         GPRReg resultPayloadGPR = result.gpr();
544     
545         arg1.use();
546         arg2.use();
547
548         flushRegisters();
549         callOperation(helperFunction, resultPayloadGPR, arg1.jsValueRegs(), arg2.jsValueRegs());
550         m_jit.exceptionCheck();
551         
552         booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
553     } else {
554         GPRTemporary resultPayload(this, Reuse, arg1, PayloadWord);
555         GPRReg resultPayloadGPR = resultPayload.gpr();
556
557         arg1.use();
558         arg2.use();
559     
560         if (!isKnownInteger(node->child1().node()))
561             slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg1TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
562         if (!isKnownInteger(node->child2().node()))
563             slowPath.append(m_jit.branch32(MacroAssembler::NotEqual, arg2TagGPR, JITCompiler::TrustedImm32(JSValue::Int32Tag)));
564
565         m_jit.compare32(cond, arg1PayloadGPR, arg2PayloadGPR, resultPayloadGPR);
566     
567         if (!isKnownInteger(node->child1().node()) || !isKnownInteger(node->child2().node())) {
568             addSlowPathGenerator(std::make_unique<CompareAndBoxBooleanSlowPathGenerator<JITCompiler::JumpList>>(
569                     slowPath, this, helperFunction, resultPayloadGPR, arg1TagGPR,
570                     arg1PayloadGPR, arg2TagGPR, arg2PayloadGPR));
571         }
572         
573         booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
574     }
575 }
576
577 void SpeculativeJIT::nonSpeculativePeepholeStrictEq(Node* node, Node* branchNode, bool invert)
578 {
579     BasicBlock* taken = branchNode->branchData()->taken.block;
580     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
581
582     // The branch instruction will branch to the taken block.
583     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
584     if (taken == nextBlock()) {
585         invert = !invert;
586         BasicBlock* tmp = taken;
587         taken = notTaken;
588         notTaken = tmp;
589     }
590     
591     JSValueOperand arg1(this, node->child1());
592     JSValueOperand arg2(this, node->child2());
593     GPRReg arg1PayloadGPR = arg1.payloadGPR();
594     GPRReg arg2PayloadGPR = arg2.payloadGPR();
595     JSValueRegs arg1Regs = arg1.jsValueRegs();
596     JSValueRegs arg2Regs = arg2.jsValueRegs();
597     
598     GPRTemporary resultPayload(this, Reuse, arg1, PayloadWord);
599     GPRReg resultPayloadGPR = resultPayload.gpr();
600     
601     arg1.use();
602     arg2.use();
603     
604     if (isKnownCell(node->child1().node()) && isKnownCell(node->child2().node())) {
605         // see if we get lucky: if the arguments are cells and they reference the same
606         // cell, then they must be strictly equal.
607         branchPtr(JITCompiler::Equal, arg1PayloadGPR, arg2PayloadGPR, invert ? notTaken : taken);
608         
609         silentSpillAllRegisters(resultPayloadGPR);
610         callOperation(operationCompareStrictEqCell, resultPayloadGPR, arg1Regs, arg2Regs);
611         m_jit.exceptionCheck();
612         silentFillAllRegisters();
613
614         branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, resultPayloadGPR, taken);
615     } else {
616         // FIXME: Add fast paths for twoCells, number etc.
617
618         silentSpillAllRegisters(resultPayloadGPR);
619         callOperation(operationCompareStrictEq, resultPayloadGPR, arg1Regs, arg2Regs);
620         m_jit.exceptionCheck();
621         silentFillAllRegisters();
622
623         branchTest32(invert ? JITCompiler::Zero : JITCompiler::NonZero, resultPayloadGPR, taken);
624     }
625     
626     jump(notTaken);
627 }
628
629 void SpeculativeJIT::nonSpeculativeNonPeepholeStrictEq(Node* node, bool invert)
630 {
631     JSValueOperand arg1(this, node->child1());
632     JSValueOperand arg2(this, node->child2());
633     GPRReg arg1PayloadGPR = arg1.payloadGPR();
634     GPRReg arg2PayloadGPR = arg2.payloadGPR();
635     JSValueRegs arg1Regs = arg1.jsValueRegs();
636     JSValueRegs arg2Regs = arg2.jsValueRegs();
637     
638     GPRTemporary resultPayload(this, Reuse, arg1, PayloadWord);
639     GPRReg resultPayloadGPR = resultPayload.gpr();
640     
641     arg1.use();
642     arg2.use();
643     
644     if (isKnownCell(node->child1().node()) && isKnownCell(node->child2().node())) {
645         // see if we get lucky: if the arguments are cells and they reference the same
646         // cell, then they must be strictly equal.
647         // FIXME: this should flush registers instead of silent spill/fill.
648         JITCompiler::Jump notEqualCase = m_jit.branchPtr(JITCompiler::NotEqual, arg1PayloadGPR, arg2PayloadGPR);
649         
650         m_jit.move(JITCompiler::TrustedImm32(!invert), resultPayloadGPR);
651         JITCompiler::Jump done = m_jit.jump();
652
653         notEqualCase.link(&m_jit);
654         
655         silentSpillAllRegisters(resultPayloadGPR);
656         callOperation(operationCompareStrictEqCell, resultPayloadGPR, arg1Regs, arg2Regs);
657         m_jit.exceptionCheck();
658         silentFillAllRegisters();
659
660         m_jit.andPtr(JITCompiler::TrustedImm32(1), resultPayloadGPR);
661         
662         done.link(&m_jit);
663     } else {
664         // FIXME: Add fast paths.
665
666         silentSpillAllRegisters(resultPayloadGPR);
667         callOperation(operationCompareStrictEq, resultPayloadGPR, arg1Regs, arg2Regs);
668         silentFillAllRegisters();
669         m_jit.exceptionCheck();
670         
671         m_jit.andPtr(JITCompiler::TrustedImm32(1), resultPayloadGPR);
672     }
673
674     booleanResult(resultPayloadGPR, node, UseChildrenCalledExplicitly);
675 }
676
677 void SpeculativeJIT::compileMiscStrictEq(Node* node)
678 {
679     JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
680     JSValueOperand op2(this, node->child2(), ManualOperandSpeculation);
681     GPRTemporary result(this);
682     
683     if (node->child1().useKind() == MiscUse)
684         speculateMisc(node->child1(), op1.jsValueRegs());
685     if (node->child2().useKind() == MiscUse)
686         speculateMisc(node->child2(), op2.jsValueRegs());
687     
688     m_jit.move(TrustedImm32(0), result.gpr());
689     JITCompiler::Jump notEqual = m_jit.branch32(JITCompiler::NotEqual, op1.tagGPR(), op2.tagGPR());
690     m_jit.compare32(JITCompiler::Equal, op1.payloadGPR(), op2.payloadGPR(), result.gpr());
691     notEqual.link(&m_jit);
692     booleanResult(result.gpr(), node);
693 }
694
695 void SpeculativeJIT::emitCall(Node* node)
696 {
697     CallLinkInfo::CallType callType;
698     bool isVarargs = false;
699     bool isForwardVarargs = false;
700     bool isTail = false;
701     bool isDirect = false;
702     bool isEmulatedTail = false;
703     switch (node->op()) {
704     case Call:
705     case CallEval:
706         callType = CallLinkInfo::Call;
707         break;
708     case TailCall:
709         callType = CallLinkInfo::TailCall;
710         isTail = true;
711         break;
712     case TailCallInlinedCaller:
713         callType = CallLinkInfo::Call;
714         isEmulatedTail = true;
715         break;
716     case Construct:
717         callType = CallLinkInfo::Construct;
718         break;
719     case CallVarargs:
720         callType = CallLinkInfo::CallVarargs;
721         isVarargs = true;
722         break;
723     case TailCallVarargs:
724         callType = CallLinkInfo::TailCallVarargs;
725         isVarargs = true;
726         isTail = true;
727         break;
728     case TailCallVarargsInlinedCaller:
729         callType = CallLinkInfo::CallVarargs;
730         isVarargs = true;
731         isEmulatedTail = true;
732         break;
733     case ConstructVarargs:
734         callType = CallLinkInfo::ConstructVarargs;
735         isVarargs = true;
736         break;
737     case CallForwardVarargs:
738         callType = CallLinkInfo::CallVarargs;
739         isForwardVarargs = true;
740         break;
741     case TailCallForwardVarargs:
742         callType = CallLinkInfo::TailCallVarargs;
743         isTail = true;
744         isForwardVarargs = true;
745         break;
746     case TailCallForwardVarargsInlinedCaller:
747         callType = CallLinkInfo::CallVarargs;
748         isEmulatedTail = true;
749         isForwardVarargs = true;
750         break;
751     case ConstructForwardVarargs:
752         callType = CallLinkInfo::ConstructVarargs;
753         isForwardVarargs = true;
754         break;
755     case DirectCall:
756         callType = CallLinkInfo::DirectCall;
757         isDirect = true;
758         break;
759     case DirectConstruct:
760         callType = CallLinkInfo::DirectConstruct;
761         isDirect = true;
762         break;
763     case DirectTailCall:
764         callType = CallLinkInfo::DirectTailCall;
765         isTail = true;
766         isDirect = true;
767         break;
768     case DirectTailCallInlinedCaller:
769         callType = CallLinkInfo::DirectCall;
770         isEmulatedTail = true;
771         isDirect = true;
772         break;
773     default:
774         DFG_CRASH(m_jit.graph(), node, "bad node type");
775         break;
776     }
777
778     Edge calleeEdge = m_jit.graph().child(node, 0);
779     GPRReg calleeTagGPR = InvalidGPRReg;
780     GPRReg calleePayloadGPR = InvalidGPRReg;
781     CallFrameShuffleData shuffleData;
782     
783     ExecutableBase* executable = nullptr;
784     FunctionExecutable* functionExecutable = nullptr;
785     if (isDirect) {
786         executable = node->castOperand<ExecutableBase*>();
787         functionExecutable = jsDynamicCast<FunctionExecutable*>(*m_jit.vm(), executable);
788     }
789     
790     unsigned numPassedArgs = 0;
791     unsigned numAllocatedArgs = 0;
792     
793     // Gotta load the arguments somehow. Varargs is trickier.
794     if (isVarargs || isForwardVarargs) {
795         RELEASE_ASSERT(!isDirect);
796         CallVarargsData* data = node->callVarargsData();
797
798         unsigned numUsedStackSlots = m_jit.graph().m_nextMachineLocal;
799         
800         if (isForwardVarargs) {
801             flushRegisters();
802             if (node->child3())
803                 use(node->child3());
804             
805             GPRReg scratchGPR1;
806             GPRReg scratchGPR2;
807             GPRReg scratchGPR3;
808             
809             scratchGPR1 = JITCompiler::selectScratchGPR();
810             scratchGPR2 = JITCompiler::selectScratchGPR(scratchGPR1);
811             scratchGPR3 = JITCompiler::selectScratchGPR(scratchGPR1, scratchGPR2);
812             
813             m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR2);
814             JITCompiler::JumpList slowCase;
815             InlineCallFrame* inlineCallFrame;
816             if (node->child3())
817                 inlineCallFrame = node->child3()->origin.semantic.inlineCallFrame;
818             else
819                 inlineCallFrame = node->origin.semantic.inlineCallFrame;
820             // emitSetupVarargsFrameFastCase modifies the stack pointer if it succeeds.
821             emitSetupVarargsFrameFastCase(*m_jit.vm(), m_jit, scratchGPR2, scratchGPR1, scratchGPR2, scratchGPR3, inlineCallFrame, data->firstVarArgOffset, slowCase);
822             JITCompiler::Jump done = m_jit.jump();
823             slowCase.link(&m_jit);
824             callOperation(operationThrowStackOverflowForVarargs);
825             m_jit.exceptionCheck();
826             m_jit.abortWithReason(DFGVarargsThrowingPathDidNotThrow);
827             done.link(&m_jit);
828         } else {
829             GPRReg argumentsPayloadGPR;
830             GPRReg argumentsTagGPR;
831             GPRReg scratchGPR1;
832             GPRReg scratchGPR2;
833             GPRReg scratchGPR3;
834         
835             auto loadArgumentsGPR = [&] (GPRReg reservedGPR) {
836                 if (reservedGPR != InvalidGPRReg)
837                     lock(reservedGPR);
838                 JSValueOperand arguments(this, node->child3());
839                 argumentsTagGPR = arguments.tagGPR();
840                 argumentsPayloadGPR = arguments.payloadGPR();
841                 if (reservedGPR != InvalidGPRReg)
842                     unlock(reservedGPR);
843                 flushRegisters();
844                 
845                 scratchGPR1 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, reservedGPR);
846                 scratchGPR2 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, reservedGPR);
847                 scratchGPR3 = JITCompiler::selectScratchGPR(argumentsPayloadGPR, argumentsTagGPR, scratchGPR1, scratchGPR2, reservedGPR);
848             };
849             
850             loadArgumentsGPR(InvalidGPRReg);
851         
852             DFG_ASSERT(m_jit.graph(), node, isFlushed());
853
854             // Right now, arguments is in argumentsTagGPR/argumentsPayloadGPR and the register file is
855             // flushed.
856             callOperation(operationSizeFrameForVarargs, GPRInfo::returnValueGPR, JSValueRegs(argumentsTagGPR, argumentsPayloadGPR), numUsedStackSlots, data->firstVarArgOffset);
857             m_jit.exceptionCheck();
858             
859             // Now we have the argument count of the callee frame, but we've lost the arguments operand.
860             // Reconstruct the arguments operand while preserving the callee frame.
861             loadArgumentsGPR(GPRInfo::returnValueGPR);
862             m_jit.move(TrustedImm32(numUsedStackSlots), scratchGPR1);
863             emitSetVarargsFrame(m_jit, GPRInfo::returnValueGPR, false, scratchGPR1, scratchGPR1);
864             m_jit.addPtr(TrustedImm32(-(sizeof(CallerFrameAndPC) + WTF::roundUpToMultipleOf(stackAlignmentBytes(), 6 * sizeof(void*)))), scratchGPR1, JITCompiler::stackPointerRegister);
865             
866             callOperation(operationSetupVarargsFrame, GPRInfo::returnValueGPR, scratchGPR1, JSValueRegs(argumentsTagGPR, argumentsPayloadGPR), data->firstVarArgOffset, GPRInfo::returnValueGPR);
867             m_jit.exceptionCheck();
868             m_jit.addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), GPRInfo::returnValueGPR, JITCompiler::stackPointerRegister);
869         }
870         
871         DFG_ASSERT(m_jit.graph(), node, isFlushed());
872         
873         // We don't need the arguments array anymore.
874         if (isVarargs)
875             use(node->child3());
876
877         // Now set up the "this" argument.
878         JSValueOperand thisArgument(this, node->child2());
879         GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
880         GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
881         thisArgument.use();
882         
883         m_jit.store32(thisArgumentTagGPR, JITCompiler::calleeArgumentTagSlot(0));
884         m_jit.store32(thisArgumentPayloadGPR, JITCompiler::calleeArgumentPayloadSlot(0));
885     } else {        
886         // The call instruction's first child is either the function (normal call) or the
887         // receiver (method call). subsequent children are the arguments.
888         numPassedArgs = node->numChildren() - 1;
889         numAllocatedArgs = numPassedArgs;
890         
891         if (functionExecutable) {
892             // Allocate more args if this would let us avoid arity checks. This is throttled by
893             // CallLinkInfo's limit. It's probably good to throttle it - if the callee wants a
894             // ginormous amount of argument space then it's better for them to do it so that when we
895             // make calls to other things, we don't waste space.
896             unsigned desiredNumAllocatedArgs = static_cast<unsigned>(functionExecutable->parameterCount()) + 1;
897             if (desiredNumAllocatedArgs <= Options::maximumDirectCallStackSize()) {
898                 numAllocatedArgs = std::max(numAllocatedArgs, desiredNumAllocatedArgs);
899                 
900                 // Whoever converts to DirectCall should do this adjustment. It's too late for us to
901                 // do this adjustment now since we will have already emitted code that relied on the
902                 // value of m_parameterSlots.
903                 DFG_ASSERT(
904                     m_jit.graph(), node,
905                     Graph::parameterSlotsForArgCount(numAllocatedArgs)
906                     <= m_jit.graph().m_parameterSlots);
907             }
908         }
909
910         if (isTail) {
911             JSValueOperand callee(this, calleeEdge);
912             calleeTagGPR = callee.tagGPR();
913             calleePayloadGPR = callee.payloadGPR();
914             if (!isDirect)
915                 use(calleeEdge);
916
917             shuffleData.numLocals = m_jit.graph().frameRegisterCount();
918             shuffleData.callee = ValueRecovery::inPair(calleeTagGPR, calleePayloadGPR);
919             shuffleData.args.resize(numAllocatedArgs);
920             shuffleData.numPassedArgs = numPassedArgs;
921
922             for (unsigned i = 0; i < numPassedArgs; ++i) {
923                 Edge argEdge = m_jit.graph().varArgChild(node, i + 1);
924                 GenerationInfo& info = generationInfo(argEdge.node());
925                 if (!isDirect)
926                     use(argEdge);
927                 shuffleData.args[i] = info.recovery(argEdge->virtualRegister());
928             }
929             
930             for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i)
931                 shuffleData.args[i] = ValueRecovery::constant(jsUndefined());
932         } else {
933             m_jit.store32(MacroAssembler::TrustedImm32(numPassedArgs), m_jit.calleeFramePayloadSlot(CallFrameSlot::argumentCount));
934         
935             for (unsigned i = 0; i < numPassedArgs; i++) {
936                 Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
937                 JSValueOperand arg(this, argEdge);
938                 GPRReg argTagGPR = arg.tagGPR();
939                 GPRReg argPayloadGPR = arg.payloadGPR();
940                 use(argEdge);
941             
942                 m_jit.store32(argTagGPR, m_jit.calleeArgumentTagSlot(i));
943                 m_jit.store32(argPayloadGPR, m_jit.calleeArgumentPayloadSlot(i));
944             }
945             
946             for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i)
947                 m_jit.storeTrustedValue(jsUndefined(), JITCompiler::calleeArgumentSlot(i));
948         }
949     }
950
951     if (!isTail || isVarargs || isForwardVarargs) {
952         JSValueOperand callee(this, calleeEdge);
953         calleeTagGPR = callee.tagGPR();
954         calleePayloadGPR = callee.payloadGPR();
955         use(calleeEdge);
956         m_jit.store32(calleePayloadGPR, m_jit.calleeFramePayloadSlot(CallFrameSlot::callee));
957         m_jit.store32(calleeTagGPR, m_jit.calleeFrameTagSlot(CallFrameSlot::callee));
958
959         if (!isTail)
960             flushRegisters();
961     }
962
963     JITCompiler::DataLabelPtr targetToCheck;
964     JITCompiler::JumpList slowPath;
965
966     CodeOrigin staticOrigin = node->origin.semantic;
967     ASSERT(!isTail || !staticOrigin.inlineCallFrame || !staticOrigin.inlineCallFrame->getCallerSkippingTailCalls());
968     ASSERT(!isEmulatedTail || (staticOrigin.inlineCallFrame && staticOrigin.inlineCallFrame->getCallerSkippingTailCalls()));
969     CodeOrigin dynamicOrigin =
970         isEmulatedTail ? *staticOrigin.inlineCallFrame->getCallerSkippingTailCalls() : staticOrigin;
971     CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(dynamicOrigin, m_stream->size());
972     
973     CallLinkInfo* info = m_jit.codeBlock()->addCallLinkInfo();
974     info->setUpCall(callType, node->origin.semantic, calleePayloadGPR);
975     
976     auto setResultAndResetStack = [&] () {
977         GPRFlushedCallResult resultPayload(this);
978         GPRFlushedCallResult2 resultTag(this);
979         GPRReg resultPayloadGPR = resultPayload.gpr();
980         GPRReg resultTagGPR = resultTag.gpr();
981         
982         m_jit.setupResults(resultPayloadGPR, resultTagGPR);
983
984         jsValueResult(resultTagGPR, resultPayloadGPR, node, DataFormatJS, UseChildrenCalledExplicitly);
985         // After the calls are done, we need to reestablish our stack
986         // pointer. We rely on this for varargs calls, calls with arity
987         // mismatch (the callframe is slided) and tail calls.
988         m_jit.addPtr(TrustedImm32(m_jit.graph().stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, JITCompiler::stackPointerRegister);
989     };
990     
991     if (node->op() == CallEval) {
992         // We want to call operationCallEval but we don't want to overwrite the parameter area in
993         // which we have created a prototypical eval call frame. This means that we have to
994         // subtract stack to make room for the call. Lucky for us, at this point we have the whole
995         // register file to ourselves.
996         
997         m_jit.emitStoreCallSiteIndex(callSite);
998         m_jit.addPtr(TrustedImm32(-static_cast<ptrdiff_t>(sizeof(CallerFrameAndPC))), JITCompiler::stackPointerRegister, GPRInfo::regT0);
999         m_jit.storePtr(GPRInfo::callFrameRegister, JITCompiler::Address(GPRInfo::regT0, CallFrame::callerFrameOffset()));
1000         
1001         // Now we need to make room for:
1002         // - The caller frame and PC of a call to operationCallEval.
1003         // - Potentially two arguments on the stack.
1004         unsigned requiredBytes = sizeof(CallerFrameAndPC) + sizeof(ExecState*) * 2;
1005         requiredBytes = WTF::roundUpToMultipleOf(stackAlignmentBytes(), requiredBytes);
1006         m_jit.subPtr(TrustedImm32(requiredBytes), JITCompiler::stackPointerRegister);
1007         m_jit.setupArgumentsWithExecState(GPRInfo::regT0);
1008         prepareForExternalCall();
1009         m_jit.appendCall(operationCallEval);
1010         m_jit.exceptionCheck();
1011         JITCompiler::Jump done = m_jit.branch32(JITCompiler::NotEqual, GPRInfo::returnValueGPR2, TrustedImm32(JSValue::EmptyValueTag));
1012         
1013         // This is the part where we meant to make a normal call. Oops.
1014         m_jit.addPtr(TrustedImm32(requiredBytes), JITCompiler::stackPointerRegister);
1015         m_jit.load32(JITCompiler::calleeFrameSlot(CallFrameSlot::callee).withOffset(PayloadOffset), GPRInfo::regT0);
1016         m_jit.load32(JITCompiler::calleeFrameSlot(CallFrameSlot::callee).withOffset(TagOffset), GPRInfo::regT1);
1017         m_jit.emitDumbVirtualCall(*m_jit.vm(), info);
1018         
1019         done.link(&m_jit);
1020         setResultAndResetStack();
1021         return;
1022     }
1023
1024     if (isDirect) {
1025         info->setExecutableDuringCompilation(executable);
1026         info->setMaxNumArguments(numAllocatedArgs);
1027
1028         if (isTail) {
1029             RELEASE_ASSERT(node->op() == DirectTailCall);
1030             
1031             JITCompiler::PatchableJump patchableJump = m_jit.patchableJump();
1032             JITCompiler::Label mainPath = m_jit.label();
1033             
1034             m_jit.emitStoreCallSiteIndex(callSite);
1035             
1036             info->setFrameShuffleData(shuffleData);
1037             CallFrameShuffler(m_jit, shuffleData).prepareForTailCall();
1038             
1039             JITCompiler::Call call = m_jit.nearTailCall();
1040             
1041             JITCompiler::Label slowPath = m_jit.label();
1042             patchableJump.m_jump.linkTo(slowPath, &m_jit);
1043             
1044             silentSpillAllRegisters(InvalidGPRReg);
1045             callOperation(operationLinkDirectCall, info, calleePayloadGPR);
1046             silentFillAllRegisters();
1047             m_jit.exceptionCheck();
1048             m_jit.jump().linkTo(mainPath, &m_jit);
1049             
1050             useChildren(node);
1051             
1052             m_jit.addJSDirectTailCall(patchableJump, call, slowPath, info);
1053             return;
1054         }
1055         
1056         JITCompiler::Label mainPath = m_jit.label();
1057         
1058         m_jit.emitStoreCallSiteIndex(callSite);
1059         
1060         JITCompiler::Call call = m_jit.nearCall();
1061         JITCompiler::Jump done = m_jit.jump();
1062         
1063         JITCompiler::Label slowPath = m_jit.label();
1064         if (isX86())
1065             m_jit.pop(JITCompiler::selectScratchGPR(calleePayloadGPR));
1066
1067         callOperation(operationLinkDirectCall, info, calleePayloadGPR);
1068         m_jit.exceptionCheck();
1069         m_jit.jump().linkTo(mainPath, &m_jit);
1070         
1071         done.link(&m_jit);
1072         
1073         setResultAndResetStack();
1074         
1075         m_jit.addJSDirectCall(call, slowPath, info);
1076         return;
1077     }
1078     
1079     m_jit.emitStoreCallSiteIndex(callSite);
1080     
1081     slowPath.append(m_jit.branchIfNotCell(JSValueRegs(calleeTagGPR, calleePayloadGPR)));
1082     slowPath.append(m_jit.branchPtrWithPatch(MacroAssembler::NotEqual, calleePayloadGPR, targetToCheck));
1083
1084     if (isTail) {
1085         if (node->op() == TailCall) {
1086             info->setFrameShuffleData(shuffleData);
1087             CallFrameShuffler(m_jit, shuffleData).prepareForTailCall();
1088         } else {
1089             m_jit.emitRestoreCalleeSaves();
1090             m_jit.prepareForTailCallSlow();
1091         }
1092     }
1093
1094     JITCompiler::Call fastCall = isTail ? m_jit.nearTailCall() : m_jit.nearCall();
1095
1096     JITCompiler::Jump done = m_jit.jump();
1097
1098     slowPath.link(&m_jit);
1099
1100     if (node->op() == TailCall) {
1101         CallFrameShuffler callFrameShuffler(m_jit, shuffleData);
1102         callFrameShuffler.setCalleeJSValueRegs(JSValueRegs(
1103             GPRInfo::regT1, GPRInfo::regT0));
1104         callFrameShuffler.prepareForSlowPath();
1105     } else {
1106         // Callee payload needs to be in regT0, tag in regT1
1107         if (calleeTagGPR == GPRInfo::regT0) {
1108             if (calleePayloadGPR == GPRInfo::regT1)
1109                 m_jit.swap(GPRInfo::regT1, GPRInfo::regT0);
1110             else {
1111                 m_jit.move(calleeTagGPR, GPRInfo::regT1);
1112                 m_jit.move(calleePayloadGPR, GPRInfo::regT0);
1113             }
1114         } else {
1115             m_jit.move(calleePayloadGPR, GPRInfo::regT0);
1116             m_jit.move(calleeTagGPR, GPRInfo::regT1);
1117         }
1118
1119         if (isTail)
1120             m_jit.emitRestoreCalleeSaves();
1121     }
1122
1123     m_jit.move(TrustedImmPtr(info), GPRInfo::regT2);
1124     JITCompiler::Call slowCall = m_jit.nearCall();
1125
1126     done.link(&m_jit);
1127
1128     if (isTail)
1129         m_jit.abortWithReason(JITDidReturnFromTailCall);
1130     else
1131         setResultAndResetStack();
1132
1133     m_jit.addJSCall(fastCall, slowCall, targetToCheck, info);
1134 }
1135
1136 template<bool strict>
1137 GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnFormat)
1138 {
1139     AbstractValue& value = m_state.forNode(edge);
1140     SpeculatedType type = value.m_type;
1141     ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32Only));
1142
1143     m_interpreter.filter(value, SpecInt32Only);
1144     if (value.isClear()) {
1145         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1146         returnFormat = DataFormatInt32;
1147         return allocate();
1148     }
1149
1150     VirtualRegister virtualRegister = edge->virtualRegister();
1151     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1152
1153     switch (info.registerFormat()) {
1154     case DataFormatNone: {
1155         if (edge->hasConstant()) {
1156             ASSERT(edge->isInt32Constant());
1157             GPRReg gpr = allocate();
1158             m_jit.move(MacroAssembler::Imm32(edge->asInt32()), gpr);
1159             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1160             info.fillInt32(*m_stream, gpr);
1161             returnFormat = DataFormatInt32;
1162             return gpr;
1163         }
1164
1165         DataFormat spillFormat = info.spillFormat();
1166
1167         ASSERT_UNUSED(spillFormat, (spillFormat & DataFormatJS) || spillFormat == DataFormatInt32);
1168
1169         // If we know this was spilled as an integer we can fill without checking.
1170         if (type & ~SpecInt32Only)
1171             speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::Int32Tag)));
1172
1173         GPRReg gpr = allocate();
1174         m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
1175         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1176         info.fillInt32(*m_stream, gpr);
1177         returnFormat = DataFormatInt32;
1178         return gpr;
1179     }
1180
1181     case DataFormatJSInt32:
1182     case DataFormatJS: {
1183         // Check the value is an integer.
1184         GPRReg tagGPR = info.tagGPR();
1185         GPRReg payloadGPR = info.payloadGPR();
1186         m_gprs.lock(tagGPR);
1187         m_gprs.lock(payloadGPR);
1188         if (type & ~SpecInt32Only)
1189             speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::Int32Tag)));
1190         m_gprs.unlock(tagGPR);
1191         m_gprs.release(tagGPR);
1192         m_gprs.release(payloadGPR);
1193         m_gprs.retain(payloadGPR, virtualRegister, SpillOrderInteger);
1194         info.fillInt32(*m_stream, payloadGPR);
1195         // If !strict we're done, return.
1196         returnFormat = DataFormatInt32;
1197         return payloadGPR;
1198     }
1199
1200     case DataFormatInt32: {
1201         GPRReg gpr = info.gpr();
1202         m_gprs.lock(gpr);
1203         returnFormat = DataFormatInt32;
1204         return gpr;
1205     }
1206
1207     case DataFormatCell:
1208     case DataFormatBoolean:
1209     case DataFormatJSDouble:
1210     case DataFormatJSCell:
1211     case DataFormatJSBoolean:
1212     case DataFormatDouble:
1213     case DataFormatStorage:
1214     default:
1215         RELEASE_ASSERT_NOT_REACHED();
1216         return InvalidGPRReg;
1217     }
1218 }
1219
1220 GPRReg SpeculativeJIT::fillSpeculateInt32(Edge edge, DataFormat& returnFormat)
1221 {
1222     return fillSpeculateInt32Internal<false>(edge, returnFormat);
1223 }
1224
1225 GPRReg SpeculativeJIT::fillSpeculateInt32Strict(Edge edge)
1226 {
1227     DataFormat mustBeDataFormatInt32;
1228     GPRReg result = fillSpeculateInt32Internal<true>(edge, mustBeDataFormatInt32);
1229     ASSERT(mustBeDataFormatInt32 == DataFormatInt32);
1230     return result;
1231 }
1232
1233 FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
1234 {
1235     ASSERT(isDouble(edge.useKind()));
1236     ASSERT(edge->hasDoubleResult());
1237     VirtualRegister virtualRegister = edge->virtualRegister();
1238     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1239
1240     if (info.registerFormat() == DataFormatNone) {
1241
1242         if (edge->hasConstant()) {
1243             RELEASE_ASSERT(edge->isNumberConstant());
1244             FPRReg fpr = fprAllocate();
1245             m_jit.loadDouble(TrustedImmPtr(m_jit.addressOfDoubleConstant(edge.node())), fpr);
1246             m_fprs.retain(fpr, virtualRegister, SpillOrderConstant);
1247             info.fillDouble(*m_stream, fpr);
1248             return fpr;
1249         }
1250         
1251         RELEASE_ASSERT(info.spillFormat() == DataFormatDouble);
1252         FPRReg fpr = fprAllocate();
1253         m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
1254         m_fprs.retain(fpr, virtualRegister, SpillOrderSpilled);
1255         info.fillDouble(*m_stream, fpr);
1256         return fpr;
1257     }
1258
1259     RELEASE_ASSERT(info.registerFormat() == DataFormatDouble);
1260     FPRReg fpr = info.fpr();
1261     m_fprs.lock(fpr);
1262     return fpr;
1263 }
1264
1265 GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
1266 {
1267     AbstractValue& value = m_state.forNode(edge);
1268     SpeculatedType type = value.m_type;
1269     ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCell));
1270
1271     m_interpreter.filter(value, SpecCell);
1272     if (value.isClear()) {
1273         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1274         return allocate();
1275     }
1276
1277     VirtualRegister virtualRegister = edge->virtualRegister();
1278     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1279
1280     switch (info.registerFormat()) {
1281     case DataFormatNone: {
1282         if (edge->hasConstant()) {
1283             GPRReg gpr = allocate();
1284             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1285             m_jit.move(TrustedImmPtr(edge->constant()), gpr);
1286             info.fillCell(*m_stream, gpr);
1287             return gpr;
1288         }
1289
1290         ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatCell);
1291         if (type & ~SpecCell) {
1292             speculationCheck(
1293                 BadType,
1294                 JSValueSource(JITCompiler::addressFor(virtualRegister)),
1295                 edge,
1296                 m_jit.branch32(
1297                     MacroAssembler::NotEqual,
1298                     JITCompiler::tagFor(virtualRegister),
1299                     TrustedImm32(JSValue::CellTag)));
1300         }
1301         GPRReg gpr = allocate();
1302         m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
1303         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1304         info.fillCell(*m_stream, gpr);
1305         return gpr;
1306     }
1307
1308     case DataFormatCell: {
1309         GPRReg gpr = info.gpr();
1310         m_gprs.lock(gpr);
1311         return gpr;
1312     }
1313
1314     case DataFormatJSCell:
1315     case DataFormatJS: {
1316         GPRReg tagGPR = info.tagGPR();
1317         GPRReg payloadGPR = info.payloadGPR();
1318         m_gprs.lock(tagGPR);
1319         m_gprs.lock(payloadGPR);
1320         if (type & ~SpecCell) {
1321             speculationCheck(
1322                 BadType, JSValueRegs(tagGPR, payloadGPR), edge,
1323                 m_jit.branchIfNotCell(info.jsValueRegs()));
1324         }
1325         m_gprs.unlock(tagGPR);
1326         m_gprs.release(tagGPR);
1327         m_gprs.release(payloadGPR);
1328         m_gprs.retain(payloadGPR, virtualRegister, SpillOrderCell);
1329         info.fillCell(*m_stream, payloadGPR);
1330         return payloadGPR;
1331     }
1332
1333     case DataFormatJSInt32:
1334     case DataFormatInt32:
1335     case DataFormatJSDouble:
1336     case DataFormatJSBoolean:
1337     case DataFormatBoolean:
1338     case DataFormatDouble:
1339     case DataFormatStorage:
1340         RELEASE_ASSERT_NOT_REACHED();
1341
1342     default:
1343         RELEASE_ASSERT_NOT_REACHED();
1344         return InvalidGPRReg;
1345     }
1346 }
1347
1348 GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
1349 {
1350     AbstractValue& value = m_state.forNode(edge);
1351     SpeculatedType type = value.m_type;
1352     ASSERT(edge.useKind() != KnownBooleanUse || !(value.m_type & ~SpecBoolean));
1353
1354     m_interpreter.filter(value, SpecBoolean);
1355     if (value.isClear()) {
1356         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1357         return allocate();
1358     }
1359
1360     VirtualRegister virtualRegister = edge->virtualRegister();
1361     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1362
1363     switch (info.registerFormat()) {
1364     case DataFormatNone: {
1365         if (edge->hasConstant()) {
1366             JSValue jsValue = edge->asJSValue();
1367             GPRReg gpr = allocate();
1368             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1369             m_jit.move(MacroAssembler::TrustedImm32(jsValue.asBoolean()), gpr);
1370             info.fillBoolean(*m_stream, gpr);
1371             return gpr;
1372         }
1373
1374         ASSERT((info.spillFormat() & DataFormatJS) || info.spillFormat() == DataFormatBoolean);
1375
1376         if (type & ~SpecBoolean)
1377             speculationCheck(BadType, JSValueSource(JITCompiler::addressFor(virtualRegister)), edge, m_jit.branch32(MacroAssembler::NotEqual, JITCompiler::tagFor(virtualRegister), TrustedImm32(JSValue::BooleanTag)));
1378
1379         GPRReg gpr = allocate();
1380         m_jit.load32(JITCompiler::payloadFor(virtualRegister), gpr);
1381         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1382         info.fillBoolean(*m_stream, gpr);
1383         return gpr;
1384     }
1385
1386     case DataFormatBoolean: {
1387         GPRReg gpr = info.gpr();
1388         m_gprs.lock(gpr);
1389         return gpr;
1390     }
1391
1392     case DataFormatJSBoolean:
1393     case DataFormatJS: {
1394         GPRReg tagGPR = info.tagGPR();
1395         GPRReg payloadGPR = info.payloadGPR();
1396         m_gprs.lock(tagGPR);
1397         m_gprs.lock(payloadGPR);
1398         if (type & ~SpecBoolean)
1399             speculationCheck(BadType, JSValueRegs(tagGPR, payloadGPR), edge, m_jit.branch32(MacroAssembler::NotEqual, tagGPR, TrustedImm32(JSValue::BooleanTag)));
1400
1401         m_gprs.unlock(tagGPR);
1402         m_gprs.release(tagGPR);
1403         m_gprs.release(payloadGPR);
1404         m_gprs.retain(payloadGPR, virtualRegister, SpillOrderBoolean);
1405         info.fillBoolean(*m_stream, payloadGPR);
1406         return payloadGPR;
1407     }
1408
1409     case DataFormatJSInt32:
1410     case DataFormatInt32:
1411     case DataFormatJSDouble:
1412     case DataFormatJSCell:
1413     case DataFormatCell:
1414     case DataFormatDouble:
1415     case DataFormatStorage:
1416         RELEASE_ASSERT_NOT_REACHED();
1417
1418     default:
1419         RELEASE_ASSERT_NOT_REACHED();
1420         return InvalidGPRReg;
1421     }
1422 }
1423
1424 void SpeculativeJIT::compileObjectEquality(Node* node)
1425 {
1426     SpeculateCellOperand op1(this, node->child1());
1427     SpeculateCellOperand op2(this, node->child2());
1428     GPRReg op1GPR = op1.gpr();
1429     GPRReg op2GPR = op2.gpr();
1430     
1431     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
1432         DFG_TYPE_CHECK(
1433             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
1434         DFG_TYPE_CHECK(
1435             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
1436     } else {
1437         DFG_TYPE_CHECK(
1438             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
1439         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
1440             m_jit.branchTest8(
1441                 MacroAssembler::NonZero, 
1442                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()),
1443                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1444
1445         DFG_TYPE_CHECK(
1446             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
1447         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
1448             m_jit.branchTest8(
1449                 MacroAssembler::NonZero,
1450                 MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()),
1451                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1452     }
1453     
1454     GPRTemporary resultPayload(this, Reuse, op2);
1455     GPRReg resultPayloadGPR = resultPayload.gpr();
1456     
1457     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR);
1458     m_jit.move(TrustedImm32(1), resultPayloadGPR);
1459     MacroAssembler::Jump done = m_jit.jump();
1460     falseCase.link(&m_jit);
1461     m_jit.move(TrustedImm32(0), resultPayloadGPR);
1462     done.link(&m_jit);
1463
1464     booleanResult(resultPayloadGPR, node);
1465 }
1466
1467 void SpeculativeJIT::compileObjectStrictEquality(Edge objectChild, Edge otherChild)
1468 {
1469     SpeculateCellOperand op1(this, objectChild);
1470     JSValueOperand op2(this, otherChild);
1471
1472     GPRReg op1GPR = op1.gpr();
1473     GPRReg op2GPR = op2.payloadGPR();
1474
1475     DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1476
1477     GPRTemporary resultPayload(this, Reuse, op1);
1478     GPRReg resultPayloadGPR = resultPayload.gpr();
1479     
1480     MacroAssembler::Jump op2CellJump = m_jit.branchIfCell(op2.jsValueRegs());
1481     
1482     m_jit.move(TrustedImm32(0), resultPayloadGPR);
1483     MacroAssembler::Jump op2NotCellJump = m_jit.jump();
1484     
1485     // At this point we know that we can perform a straight-forward equality comparison on pointer
1486     // values because we are doing strict equality.
1487     op2CellJump.link(&m_jit);
1488     m_jit.compare32(MacroAssembler::Equal, op1GPR, op2GPR, resultPayloadGPR);
1489     
1490     op2NotCellJump.link(&m_jit);
1491     booleanResult(resultPayloadGPR, m_currentNode);
1492 }
1493     
1494 void SpeculativeJIT::compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode)
1495 {
1496     BasicBlock* taken = branchNode->branchData()->taken.block;
1497     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
1498
1499     SpeculateCellOperand op1(this, objectChild);
1500     JSValueOperand op2(this, otherChild);
1501     
1502     GPRReg op1GPR = op1.gpr();
1503     GPRReg op2GPR = op2.payloadGPR();
1504
1505     DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1506
1507     branch32(MacroAssembler::NotEqual, op2.tagGPR(), TrustedImm32(JSValue::CellTag), notTaken);
1508     
1509     if (taken == nextBlock()) {
1510         branch32(MacroAssembler::NotEqual, op1GPR, op2GPR, notTaken);
1511         jump(taken);
1512     } else {
1513         branch32(MacroAssembler::Equal, op1GPR, op2GPR, taken);
1514         jump(notTaken);
1515     }
1516 }
1517
1518 void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
1519 {
1520     SpeculateCellOperand op1(this, leftChild);
1521     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
1522     GPRTemporary result(this);
1523     
1524     GPRReg op1GPR = op1.gpr();
1525     GPRReg op2TagGPR = op2.tagGPR();
1526     GPRReg op2PayloadGPR = op2.payloadGPR();
1527     GPRReg resultGPR = result.gpr();
1528
1529     bool masqueradesAsUndefinedWatchpointValid =
1530         masqueradesAsUndefinedWatchpointIsStillValid();
1531
1532     if (masqueradesAsUndefinedWatchpointValid) {
1533         DFG_TYPE_CHECK(
1534             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1535     } else {
1536         DFG_TYPE_CHECK(
1537             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1538         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild, 
1539             m_jit.branchTest8(
1540                 MacroAssembler::NonZero, 
1541                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
1542                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1543     }
1544     
1545     
1546     // It seems that most of the time when programs do a == b where b may be either null/undefined
1547     // or an object, b is usually an object. Balance the branches to make that case fast.
1548     MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(op2.jsValueRegs());
1549     
1550     // We know that within this branch, rightChild must be a cell.
1551     if (masqueradesAsUndefinedWatchpointValid) {
1552         DFG_TYPE_CHECK(
1553             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2PayloadGPR));
1554     } else {
1555         DFG_TYPE_CHECK(
1556             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(op2PayloadGPR));
1557         speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, 
1558             m_jit.branchTest8(
1559                 MacroAssembler::NonZero, 
1560                 MacroAssembler::Address(op2PayloadGPR, JSCell::typeInfoFlagsOffset()), 
1561                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1562     }
1563     
1564     // At this point we know that we can perform a straight-forward equality comparison on pointer
1565     // values because both left and right are pointers to objects that have no special equality
1566     // protocols.
1567     MacroAssembler::Jump falseCase = m_jit.branchPtr(MacroAssembler::NotEqual, op1GPR, op2PayloadGPR);
1568     MacroAssembler::Jump trueCase = m_jit.jump();
1569     
1570     rightNotCell.link(&m_jit);
1571     
1572     // We know that within this branch, rightChild must not be a cell. Check if that is enough to
1573     // prove that it is either null or undefined.
1574     if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
1575         m_jit.or32(TrustedImm32(1), op2TagGPR, resultGPR);
1576         
1577         typeCheck(
1578             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
1579             m_jit.branch32(
1580                 MacroAssembler::NotEqual, resultGPR,
1581                 MacroAssembler::TrustedImm32(JSValue::NullTag)));
1582     }
1583     
1584     falseCase.link(&m_jit);
1585     m_jit.move(TrustedImm32(0), resultGPR);
1586     MacroAssembler::Jump done = m_jit.jump();
1587     trueCase.link(&m_jit);
1588     m_jit.move(TrustedImm32(1), resultGPR);
1589     done.link(&m_jit);
1590     
1591     booleanResult(resultGPR, m_currentNode);
1592 }
1593
1594 void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
1595 {
1596     BasicBlock* taken = branchNode->branchData()->taken.block;
1597     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
1598     
1599     SpeculateCellOperand op1(this, leftChild);
1600     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
1601     GPRTemporary result(this);
1602     
1603     GPRReg op1GPR = op1.gpr();
1604     GPRReg op2TagGPR = op2.tagGPR();
1605     GPRReg op2PayloadGPR = op2.payloadGPR();
1606     GPRReg resultGPR = result.gpr();
1607
1608     bool masqueradesAsUndefinedWatchpointValid =
1609         masqueradesAsUndefinedWatchpointIsStillValid();
1610
1611     if (masqueradesAsUndefinedWatchpointValid) {
1612         DFG_TYPE_CHECK(
1613             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1614     } else {
1615         DFG_TYPE_CHECK(
1616             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1617         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1618             m_jit.branchTest8(
1619                 MacroAssembler::NonZero, 
1620                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
1621                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1622     }
1623     
1624     // It seems that most of the time when programs do a == b where b may be either null/undefined
1625     // or an object, b is usually an object. Balance the branches to make that case fast.
1626     MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(op2.jsValueRegs());
1627     
1628     // We know that within this branch, rightChild must be a cell.
1629     if (masqueradesAsUndefinedWatchpointValid) {
1630         DFG_TYPE_CHECK(
1631             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
1632             m_jit.branchIfNotObject(op2PayloadGPR));
1633     } else {
1634         DFG_TYPE_CHECK(
1635             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, (~SpecCell) | SpecObject,
1636             m_jit.branchIfNotObject(op2PayloadGPR));
1637         speculationCheck(BadType, JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild,
1638             m_jit.branchTest8(
1639                 MacroAssembler::NonZero, 
1640                 MacroAssembler::Address(op2PayloadGPR, JSCell::typeInfoFlagsOffset()), 
1641                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1642     }
1643     
1644     // At this point we know that we can perform a straight-forward equality comparison on pointer
1645     // values because both left and right are pointers to objects that have no special equality
1646     // protocols.
1647     branch32(MacroAssembler::Equal, op1GPR, op2PayloadGPR, taken);
1648     
1649     // We know that within this branch, rightChild must not be a cell. Check if that is enough to
1650     // prove that it is either null or undefined.
1651     if (!needsTypeCheck(rightChild, SpecCell | SpecOther))
1652         rightNotCell.link(&m_jit);
1653     else {
1654         jump(notTaken, ForceJump);
1655         
1656         rightNotCell.link(&m_jit);
1657         m_jit.or32(TrustedImm32(1), op2TagGPR, resultGPR);
1658         
1659         typeCheck(
1660             JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
1661             m_jit.branch32(
1662                 MacroAssembler::NotEqual, resultGPR,
1663                 MacroAssembler::TrustedImm32(JSValue::NullTag)));
1664     }
1665     
1666     jump(notTaken);
1667 }
1668
1669 void SpeculativeJIT::compileSymbolUntypedEquality(Node* node, Edge symbolEdge, Edge untypedEdge)
1670 {
1671     SpeculateCellOperand symbol(this, symbolEdge);
1672     JSValueOperand untyped(this, untypedEdge);
1673
1674     GPRReg symbolGPR = symbol.gpr();
1675     GPRReg untypedGPR = untyped.payloadGPR();
1676
1677     speculateSymbol(symbolEdge, symbolGPR);
1678
1679     GPRTemporary resultPayload(this, Reuse, symbol);
1680     GPRReg resultPayloadGPR = resultPayload.gpr();
1681
1682     MacroAssembler::Jump untypedCellJump = m_jit.branchIfCell(untyped.jsValueRegs());
1683
1684     m_jit.move(TrustedImm32(0), resultPayloadGPR);
1685     MacroAssembler::Jump untypedNotCellJump = m_jit.jump();
1686
1687     // At this point we know that we can perform a straight-forward equality comparison on pointer
1688     // values because we are doing strict equality.
1689     untypedCellJump.link(&m_jit);
1690     m_jit.compare32(MacroAssembler::Equal, symbolGPR, untypedGPR, resultPayloadGPR);
1691
1692     untypedNotCellJump.link(&m_jit);
1693     booleanResult(resultPayloadGPR, node);
1694 }
1695
1696 void SpeculativeJIT::compileInt32Compare(Node* node, MacroAssembler::RelationalCondition condition)
1697 {
1698     SpeculateInt32Operand op1(this, node->child1());
1699     SpeculateInt32Operand op2(this, node->child2());
1700     GPRTemporary resultPayload(this);
1701     
1702     m_jit.compare32(condition, op1.gpr(), op2.gpr(), resultPayload.gpr());
1703     
1704     // If we add a DataFormatBool, we should use it here.
1705     booleanResult(resultPayload.gpr(), node);
1706 }
1707
1708 void SpeculativeJIT::compileDoubleCompare(Node* node, MacroAssembler::DoubleCondition condition)
1709 {
1710     SpeculateDoubleOperand op1(this, node->child1());
1711     SpeculateDoubleOperand op2(this, node->child2());
1712     GPRTemporary resultPayload(this);
1713     
1714     m_jit.move(TrustedImm32(1), resultPayload.gpr());
1715     MacroAssembler::Jump trueCase = m_jit.branchDouble(condition, op1.fpr(), op2.fpr());
1716     m_jit.move(TrustedImm32(0), resultPayload.gpr());
1717     trueCase.link(&m_jit);
1718     
1719     booleanResult(resultPayload.gpr(), node);
1720 }
1721
1722 void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
1723 {
1724     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
1725     GPRTemporary resultPayload(this);
1726     GPRReg valueTagGPR = value.tagGPR();
1727     GPRReg valuePayloadGPR = value.payloadGPR();
1728     GPRReg resultPayloadGPR = resultPayload.gpr();
1729     GPRTemporary structure;
1730     GPRReg structureGPR = InvalidGPRReg;
1731
1732     bool masqueradesAsUndefinedWatchpointValid =
1733         masqueradesAsUndefinedWatchpointIsStillValid();
1734
1735     if (!masqueradesAsUndefinedWatchpointValid) {
1736         // The masquerades as undefined case will use the structure register, so allocate it here.
1737         // Do this at the top of the function to avoid branching around a register allocation.
1738         GPRTemporary realStructure(this);
1739         structure.adopt(realStructure);
1740         structureGPR = structure.gpr();
1741     }
1742
1743     MacroAssembler::Jump notCell = m_jit.branchIfNotCell(value.jsValueRegs());
1744     if (masqueradesAsUndefinedWatchpointValid) {
1745         DFG_TYPE_CHECK(
1746             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
1747             m_jit.branchIfNotObject(valuePayloadGPR));
1748     } else {
1749         DFG_TYPE_CHECK(
1750             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
1751             m_jit.branchIfNotObject(valuePayloadGPR));
1752
1753         MacroAssembler::Jump isNotMasqueradesAsUndefined = 
1754             m_jit.branchTest8(
1755                 MacroAssembler::Zero, 
1756                 MacroAssembler::Address(valuePayloadGPR, JSCell::typeInfoFlagsOffset()), 
1757                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined));
1758
1759         m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), structureGPR);
1760         speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, 
1761             m_jit.branchPtr(
1762                 MacroAssembler::Equal, 
1763                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
1764                 TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic))));
1765
1766         isNotMasqueradesAsUndefined.link(&m_jit);
1767     }
1768     m_jit.move(TrustedImm32(0), resultPayloadGPR);
1769     MacroAssembler::Jump done = m_jit.jump();
1770     
1771     notCell.link(&m_jit);
1772  
1773     COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
1774     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
1775         m_jit.or32(TrustedImm32(1), valueTagGPR, resultPayloadGPR);
1776         typeCheck(
1777             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
1778             m_jit.branch32(
1779                 MacroAssembler::NotEqual, 
1780                 resultPayloadGPR, 
1781                 TrustedImm32(JSValue::NullTag)));
1782     }
1783     m_jit.move(TrustedImm32(1), resultPayloadGPR);
1784     
1785     done.link(&m_jit);
1786     
1787     booleanResult(resultPayloadGPR, m_currentNode);
1788 }
1789
1790 void SpeculativeJIT::compileLogicalNot(Node* node)
1791 {
1792     switch (node->child1().useKind()) {
1793     case BooleanUse:
1794     case KnownBooleanUse: {
1795         SpeculateBooleanOperand value(this, node->child1());
1796         GPRTemporary result(this, Reuse, value);
1797         m_jit.xor32(TrustedImm32(1), value.gpr(), result.gpr());
1798         booleanResult(result.gpr(), node);
1799         return;
1800     }
1801         
1802     case ObjectOrOtherUse: {
1803         compileObjectOrOtherLogicalNot(node->child1());
1804         return;
1805     }
1806         
1807     case Int32Use: {
1808         SpeculateInt32Operand value(this, node->child1());
1809         GPRTemporary resultPayload(this, Reuse, value);
1810         m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), resultPayload.gpr());
1811         booleanResult(resultPayload.gpr(), node);
1812         return;
1813     }
1814         
1815     case DoubleRepUse: {
1816         SpeculateDoubleOperand value(this, node->child1());
1817         FPRTemporary scratch(this);
1818         GPRTemporary resultPayload(this);
1819         m_jit.move(TrustedImm32(0), resultPayload.gpr());
1820         MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
1821         m_jit.move(TrustedImm32(1), resultPayload.gpr());
1822         nonZero.link(&m_jit);
1823         booleanResult(resultPayload.gpr(), node);
1824         return;
1825     }
1826
1827     case UntypedUse: {
1828         JSValueOperand arg1(this, node->child1());
1829         GPRTemporary result(this);
1830         GPRTemporary temp(this);
1831         FPRTemporary valueFPR(this);
1832         FPRTemporary tempFPR(this);
1833
1834         GPRReg resultGPR = result.gpr();
1835
1836         bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
1837         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
1838         bool negateResult = true;
1839         m_jit.emitConvertValueToBoolean(*m_jit.vm(), arg1.jsValueRegs(), resultGPR, temp.gpr(), valueFPR.fpr(), tempFPR.fpr(), shouldCheckMasqueradesAsUndefined, globalObject, negateResult);
1840         booleanResult(resultGPR, node);
1841         return;
1842     }
1843     case StringUse:
1844         return compileStringZeroLength(node);
1845
1846     case StringOrOtherUse:
1847         return compileLogicalNotStringOrOther(node);
1848
1849     default:
1850         RELEASE_ASSERT_NOT_REACHED();
1851         break;
1852     }
1853 }
1854
1855 void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
1856 {
1857     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
1858     GPRTemporary scratch(this);
1859     GPRReg valueTagGPR = value.tagGPR();
1860     GPRReg valuePayloadGPR = value.payloadGPR();
1861     GPRReg scratchGPR = scratch.gpr();
1862     
1863     MacroAssembler::Jump notCell = m_jit.branchIfNotCell(value.jsValueRegs());
1864     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
1865         DFG_TYPE_CHECK(
1866             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
1867             m_jit.branchIfNotObject(valuePayloadGPR));
1868     } else {
1869         DFG_TYPE_CHECK(
1870             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, (~SpecCell) | SpecObject,
1871             m_jit.branchIfNotObject(valuePayloadGPR));
1872
1873         JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
1874             JITCompiler::Zero, 
1875             MacroAssembler::Address(valuePayloadGPR, JSCell::typeInfoFlagsOffset()), 
1876             TrustedImm32(MasqueradesAsUndefined));
1877
1878         m_jit.loadPtr(MacroAssembler::Address(valuePayloadGPR, JSCell::structureIDOffset()), scratchGPR);
1879         speculationCheck(BadType, JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse,
1880             m_jit.branchPtr(
1881                 MacroAssembler::Equal, 
1882                 MacroAssembler::Address(scratchGPR, Structure::globalObjectOffset()), 
1883                 TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic))));
1884
1885         isNotMasqueradesAsUndefined.link(&m_jit);
1886     }
1887     jump(taken, ForceJump);
1888     
1889     notCell.link(&m_jit);
1890     
1891     COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
1892     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
1893         m_jit.or32(TrustedImm32(1), valueTagGPR, scratchGPR);
1894         typeCheck(
1895             JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
1896             m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
1897     }
1898
1899     jump(notTaken);
1900     
1901     noResult(m_currentNode);
1902 }
1903
1904 void SpeculativeJIT::emitBranch(Node* node)
1905 {
1906     BasicBlock* taken = node->branchData()->taken.block;
1907     BasicBlock* notTaken = node->branchData()->notTaken.block;
1908
1909     switch (node->child1().useKind()) {
1910     case BooleanUse:
1911     case KnownBooleanUse: {
1912         SpeculateBooleanOperand value(this, node->child1());
1913         MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1914
1915         if (taken == nextBlock()) {
1916             condition = MacroAssembler::Zero;
1917             BasicBlock* tmp = taken;
1918             taken = notTaken;
1919             notTaken = tmp;
1920         }
1921
1922         branchTest32(condition, value.gpr(), TrustedImm32(1), taken);
1923         jump(notTaken);
1924
1925         noResult(node);
1926         return;
1927     }
1928     
1929     case ObjectOrOtherUse: {
1930         emitObjectOrOtherBranch(node->child1(), taken, notTaken);
1931         return;
1932     }
1933
1934     case StringUse: {
1935         emitStringBranch(node->child1(), taken, notTaken);
1936         return;
1937     }
1938
1939     case StringOrOtherUse: {
1940         emitStringOrOtherBranch(node->child1(), taken, notTaken);
1941         return;
1942     }
1943
1944     case DoubleRepUse:
1945     case Int32Use: {
1946         if (node->child1().useKind() == Int32Use) {
1947             bool invert = false;
1948             
1949             if (taken == nextBlock()) {
1950                 invert = true;
1951                 BasicBlock* tmp = taken;
1952                 taken = notTaken;
1953                 notTaken = tmp;
1954             }
1955
1956             SpeculateInt32Operand value(this, node->child1());
1957             branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr(), taken);
1958         } else {
1959             SpeculateDoubleOperand value(this, node->child1());
1960             FPRTemporary scratch(this);
1961             branchDoubleNonZero(value.fpr(), scratch.fpr(), taken);
1962         }
1963         
1964         jump(notTaken);
1965         
1966         noResult(node);
1967         return;
1968     }
1969     
1970     case UntypedUse: {
1971         JSValueOperand value(this, node->child1());
1972         FPRTemporary valueFPR(this);
1973         FPRTemporary tempFPR(this);
1974         GPRTemporary result(this);
1975         GPRTemporary temp(this);
1976
1977         JSValueRegs valueRegs = value.jsValueRegs();
1978         GPRReg resultGPR = result.gpr();
1979     
1980         use(node->child1());
1981
1982         bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
1983         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
1984         m_jit.emitConvertValueToBoolean(*m_jit.vm(), valueRegs, resultGPR, temp.gpr(), valueFPR.fpr(), tempFPR.fpr(), shouldCheckMasqueradesAsUndefined, globalObject);
1985         branchTest32(JITCompiler::Zero, resultGPR, notTaken);
1986         jump(taken, ForceJump);
1987
1988         noResult(node, UseChildrenCalledExplicitly);
1989         return;
1990     }
1991         
1992     default:
1993         RELEASE_ASSERT_NOT_REACHED();
1994         break;
1995     }
1996 }
1997
1998 template<typename BaseOperandType, typename PropertyOperandType, typename ValueOperandType, typename TagType>
1999 void SpeculativeJIT::compileContiguousPutByVal(Node* node, BaseOperandType& base, PropertyOperandType& property, ValueOperandType& value, GPRReg valuePayloadReg, TagType valueTag)
2000 {
2001     Edge child4 = m_jit.graph().varArgChild(node, 3);
2002
2003     ArrayMode arrayMode = node->arrayMode();
2004     
2005     GPRReg baseReg = base.gpr();
2006     GPRReg propertyReg = property.gpr();
2007     
2008     StorageOperand storage(this, child4);
2009     GPRReg storageReg = storage.gpr();
2010
2011     if (node->op() == PutByValAlias) {
2012         // Store the value to the array.
2013         GPRReg propertyReg = property.gpr();
2014         m_jit.store32(valueTag, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
2015         m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
2016         
2017         noResult(node);
2018         return;
2019     }
2020     
2021     MacroAssembler::Jump slowCase;
2022
2023     if (arrayMode.isInBounds()) {
2024         speculationCheck(
2025             OutOfBounds, JSValueRegs(), 0,
2026             m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2027     } else {
2028         MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2029         
2030         slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
2031         
2032         if (!arrayMode.isOutOfBounds())
2033             speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
2034         
2035         m_jit.add32(TrustedImm32(1), propertyReg);
2036         m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2037         m_jit.sub32(TrustedImm32(1), propertyReg);
2038         
2039         inBounds.link(&m_jit);
2040     }
2041     
2042     m_jit.store32(valueTag, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
2043     m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
2044     
2045     base.use();
2046     property.use();
2047     value.use();
2048     storage.use();
2049     
2050     if (arrayMode.isOutOfBounds()) {
2051         if (node->op() == PutByValDirect) {
2052             addSlowPathGenerator(slowPathCall(
2053                 slowCase, this,
2054                 m_jit.codeBlock()->isStrictMode() ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValDirectBeyondArrayBoundsNonStrict,
2055                 NoResult, baseReg, propertyReg, valueTag, valuePayloadReg));
2056         } else {
2057             addSlowPathGenerator(slowPathCall(
2058                 slowCase, this,
2059                 m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
2060                 NoResult, baseReg, propertyReg, valueTag, valuePayloadReg));
2061         }
2062     }
2063
2064     noResult(node, UseChildrenCalledExplicitly);    
2065 }
2066
2067 void SpeculativeJIT::compile(Node* node)
2068 {
2069     NodeType op = node->op();
2070
2071 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
2072     m_jit.clearRegisterAllocationOffsets();
2073 #endif
2074
2075     switch (op) {
2076     case JSConstant:
2077     case DoubleConstant:
2078     case PhantomDirectArguments:
2079     case PhantomClonedArguments:
2080         initConstantInfo(node);
2081         break;
2082
2083     case LazyJSConstant:
2084         compileLazyJSConstant(node);
2085         break;
2086
2087     case Identity: {
2088         speculate(node, node->child1());
2089         switch (node->child1().useKind()) {
2090         case DoubleRepUse:
2091         case DoubleRepRealUse: {
2092             SpeculateDoubleOperand op(this, node->child1());
2093             doubleResult(op.fpr(), node);
2094             break;
2095         }
2096         case Int52RepUse: 
2097         case AnyIntUse:
2098         case DoubleRepAnyIntUse: {
2099             RELEASE_ASSERT_NOT_REACHED();   
2100             break;
2101         }
2102         default: {
2103             JSValueOperand op(this, node->child1(), ManualOperandSpeculation);
2104             GPRTemporary resultTag(this, Reuse, op, TagWord);
2105             GPRTemporary resultPayload(this, Reuse, op, PayloadWord);
2106             GPRReg sourceTag = op.tagGPR();
2107             GPRReg sourcePayload = op.payloadGPR();
2108             GPRReg resultTagGPR = resultTag.gpr();
2109             GPRReg resultPayloadGPR = resultPayload.gpr();
2110             m_jit.move(sourceTag, resultTagGPR);
2111             m_jit.move(sourcePayload, resultPayloadGPR);
2112             jsValueResult(resultTagGPR, resultPayloadGPR, node);
2113             break;
2114         }
2115         } // switch
2116         break;
2117     }
2118
2119     case GetLocal: {
2120         AbstractValue& value = m_state.variables().operand(node->local());
2121
2122         // If the CFA is tracking this variable and it found that the variable
2123         // cannot have been assigned, then don't attempt to proceed.
2124         if (value.isClear()) {
2125             m_compileOkay = false;
2126             break;
2127         }
2128         
2129         switch (node->variableAccessData()->flushFormat()) {
2130         case FlushedDouble: {
2131             FPRTemporary result(this);
2132             m_jit.loadDouble(JITCompiler::addressFor(node->machineLocal()), result.fpr());
2133             VirtualRegister virtualRegister = node->virtualRegister();
2134             m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
2135             generationInfoFromVirtualRegister(virtualRegister).initDouble(node, node->refCount(), result.fpr());
2136             break;
2137         }
2138         
2139         case FlushedInt32: {
2140             GPRTemporary result(this);
2141             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
2142             
2143             // Like int32Result, but don't useChildren - our children are phi nodes,
2144             // and don't represent values within this dataflow with virtual registers.
2145             VirtualRegister virtualRegister = node->virtualRegister();
2146             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
2147             generationInfoFromVirtualRegister(virtualRegister).initInt32(node, node->refCount(), result.gpr());
2148             break;
2149         }
2150         
2151         case FlushedCell: {
2152             GPRTemporary result(this);
2153             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
2154             
2155             // Like cellResult, but don't useChildren - our children are phi nodes,
2156             // and don't represent values within this dataflow with virtual registers.
2157             VirtualRegister virtualRegister = node->virtualRegister();
2158             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderCell);
2159             generationInfoFromVirtualRegister(virtualRegister).initCell(node, node->refCount(), result.gpr());
2160             break;
2161         }
2162             
2163         case FlushedBoolean: {
2164             GPRTemporary result(this);
2165             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
2166             
2167             // Like booleanResult, but don't useChildren - our children are phi nodes,
2168             // and don't represent values within this dataflow with virtual registers.
2169             VirtualRegister virtualRegister = node->virtualRegister();
2170             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderBoolean);
2171             generationInfoFromVirtualRegister(virtualRegister).initBoolean(node, node->refCount(), result.gpr());
2172             break;
2173         }
2174             
2175         case FlushedJSValue: {
2176             GPRTemporary result(this);
2177             GPRTemporary tag(this);
2178             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
2179             m_jit.load32(JITCompiler::tagFor(node->machineLocal()), tag.gpr());
2180             
2181             // Like jsValueResult, but don't useChildren - our children are phi nodes,
2182             // and don't represent values within this dataflow with virtual registers.
2183             VirtualRegister virtualRegister = node->virtualRegister();
2184             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
2185             m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
2186             
2187             generationInfoFromVirtualRegister(virtualRegister).initJSValue(node, node->refCount(), tag.gpr(), result.gpr(), DataFormatJS);
2188             break;
2189         }
2190             
2191         default:
2192             RELEASE_ASSERT_NOT_REACHED();
2193         }
2194         break;
2195     }
2196         
2197     case GetLocalUnlinked: {
2198         GPRTemporary payload(this);
2199         GPRTemporary tag(this);
2200         m_jit.load32(JITCompiler::payloadFor(node->unlinkedMachineLocal()), payload.gpr());
2201         m_jit.load32(JITCompiler::tagFor(node->unlinkedMachineLocal()), tag.gpr());
2202         jsValueResult(tag.gpr(), payload.gpr(), node);
2203         break;
2204     }
2205
2206     case MovHint: {
2207         compileMovHint(m_currentNode);
2208         noResult(node);
2209         break;
2210     }
2211         
2212     case ZombieHint: {
2213         recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
2214         noResult(node);
2215         break;
2216     }
2217
2218     case ExitOK: {
2219         noResult(node);
2220         break;
2221     }
2222         
2223     case SetLocal: {
2224         switch (node->variableAccessData()->flushFormat()) {
2225         case FlushedDouble: {
2226             SpeculateDoubleOperand value(this, node->child1());
2227             m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->machineLocal()));
2228             noResult(node);
2229             // Indicate that it's no longer necessary to retrieve the value of
2230             // this bytecode variable from registers or other locations in the stack,
2231             // but that it is stored as a double.
2232             recordSetLocal(DataFormatDouble);
2233             break;
2234         }
2235             
2236         case FlushedInt32: {
2237             SpeculateInt32Operand value(this, node->child1());
2238             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->machineLocal()));
2239             noResult(node);
2240             recordSetLocal(DataFormatInt32);
2241             break;
2242         }
2243             
2244         case FlushedCell: {
2245             SpeculateCellOperand cell(this, node->child1());
2246             GPRReg cellGPR = cell.gpr();
2247             m_jit.storePtr(cellGPR, JITCompiler::payloadFor(node->machineLocal()));
2248             noResult(node);
2249             recordSetLocal(DataFormatCell);
2250             break;
2251         }
2252             
2253         case FlushedBoolean: {
2254             SpeculateBooleanOperand value(this, node->child1());
2255             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->machineLocal()));
2256             noResult(node);
2257             recordSetLocal(DataFormatBoolean);
2258             break;
2259         }
2260             
2261         case FlushedJSValue: {
2262             JSValueOperand value(this, node->child1());
2263             m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->machineLocal()));
2264             m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node->machineLocal()));
2265             noResult(node);
2266             recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
2267             break;
2268         }
2269             
2270         default:
2271             RELEASE_ASSERT_NOT_REACHED();
2272             break;
2273         }
2274         break;
2275     }
2276
2277     case SetArgument:
2278         // This is a no-op; it just marks the fact that the argument is being used.
2279         // But it may be profitable to use this as a hook to run speculation checks
2280         // on arguments, thereby allowing us to trivially eliminate such checks if
2281         // the argument is not used.
2282         recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
2283         break;
2284
2285     case BitAnd:
2286     case BitOr:
2287     case BitXor:
2288         compileBitwiseOp(node);
2289         break;
2290
2291     case BitRShift:
2292     case BitLShift:
2293     case BitURShift:
2294         compileShiftOp(node);
2295         break;
2296
2297     case UInt32ToNumber: {
2298         compileUInt32ToNumber(node);
2299         break;
2300     }
2301         
2302     case DoubleAsInt32: {
2303         compileDoubleAsInt32(node);
2304         break;
2305     }
2306
2307     case ValueToInt32: {
2308         compileValueToInt32(node);
2309         break;
2310     }
2311         
2312     case DoubleRep: {
2313         compileDoubleRep(node);
2314         break;
2315     }
2316         
2317     case ValueRep: {
2318         compileValueRep(node);
2319         break;
2320     }
2321
2322     case ValueAdd:
2323         compileValueAdd(node);
2324         break;
2325
2326     case StrCat: {
2327         JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
2328         JSValueOperand op2(this, node->child2(), ManualOperandSpeculation);
2329         JSValueOperand op3(this, node->child3(), ManualOperandSpeculation);
2330         
2331         JSValueRegs op1Regs = op1.jsValueRegs();
2332         JSValueRegs op2Regs = op2.jsValueRegs();
2333         JSValueRegs op3Regs;
2334
2335         if (node->child3())
2336             op3Regs = op3.jsValueRegs();
2337         
2338         flushRegisters();
2339
2340         GPRFlushedCallResult result(this);
2341         if (node->child3())
2342             callOperation(operationStrCat3, result.gpr(), op1Regs, op2Regs, op3Regs);
2343         else
2344             callOperation(operationStrCat2, result.gpr(), op1Regs, op2Regs);
2345         m_jit.exceptionCheck();
2346         
2347         cellResult(result.gpr(), node);
2348         break;
2349     }
2350
2351     case ArithAdd:
2352         compileArithAdd(node);
2353         break;
2354
2355     case ArithClz32:
2356         compileArithClz32(node);
2357         break;
2358
2359     case MakeRope:
2360         compileMakeRope(node);
2361         break;
2362
2363     case ArithSub:
2364         compileArithSub(node);
2365         break;
2366
2367     case ArithNegate:
2368         compileArithNegate(node);
2369         break;
2370
2371     case ArithMul:
2372         compileArithMul(node);
2373         break;
2374
2375     case ArithDiv: {
2376         compileArithDiv(node);
2377         break;
2378     }
2379
2380     case ArithMod: {
2381         compileArithMod(node);
2382         break;
2383     }
2384
2385     case ArithPow: {
2386         compileArithPow(node);
2387         break;
2388     }
2389
2390     case ArithAbs:
2391         compileArithAbs(node);
2392         break;
2393
2394     case ArithMin:
2395     case ArithMax: {
2396         switch (node->binaryUseKind()) {
2397         case Int32Use: {
2398             SpeculateStrictInt32Operand op1(this, node->child1());
2399             SpeculateStrictInt32Operand op2(this, node->child2());
2400             GPRTemporary result(this, Reuse, op1);
2401
2402             GPRReg op1GPR = op1.gpr();
2403             GPRReg op2GPR = op2.gpr();
2404             GPRReg resultGPR = result.gpr();
2405
2406             MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1GPR, op2GPR);
2407             m_jit.move(op2GPR, resultGPR);
2408             if (op1GPR != resultGPR) {
2409                 MacroAssembler::Jump done = m_jit.jump();
2410                 op1Less.link(&m_jit);
2411                 m_jit.move(op1GPR, resultGPR);
2412                 done.link(&m_jit);
2413             } else
2414                 op1Less.link(&m_jit);
2415             
2416             int32Result(resultGPR, node);
2417             break;
2418         }
2419         
2420         case DoubleRepUse: {
2421             SpeculateDoubleOperand op1(this, node->child1());
2422             SpeculateDoubleOperand op2(this, node->child2());
2423             FPRTemporary result(this, op1);
2424
2425             FPRReg op1FPR = op1.fpr();
2426             FPRReg op2FPR = op2.fpr();
2427             FPRReg resultFPR = result.fpr();
2428
2429             MacroAssembler::JumpList done;
2430         
2431             MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1FPR, op2FPR);
2432         
2433             // op2 is eather the lesser one or one of then is NaN
2434             MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1FPR, op2FPR);
2435         
2436             // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding 
2437             // op1 + op2 and putting it into result.
2438             m_jit.addDouble(op1FPR, op2FPR, resultFPR);
2439             done.append(m_jit.jump());
2440         
2441             op2Less.link(&m_jit);
2442             m_jit.moveDouble(op2FPR, resultFPR);
2443         
2444             if (op1FPR != resultFPR) {
2445                 done.append(m_jit.jump());
2446             
2447                 op1Less.link(&m_jit);
2448                 m_jit.moveDouble(op1FPR, resultFPR);
2449             } else
2450                 op1Less.link(&m_jit);
2451         
2452             done.link(&m_jit);
2453         
2454             doubleResult(resultFPR, node);
2455             break;
2456         }
2457             
2458         default:
2459             RELEASE_ASSERT_NOT_REACHED();
2460             break;
2461         }
2462         break;
2463     }
2464
2465     case ArithSqrt:
2466         compileArithSqrt(node);
2467         break;
2468
2469     case ArithFRound:
2470         compileArithFRound(node);
2471         break;
2472
2473     case ArithRandom:
2474         compileArithRandom(node);
2475         break;
2476
2477     case ArithRound:
2478     case ArithFloor:
2479     case ArithCeil:
2480     case ArithTrunc:
2481         compileArithRounding(node);
2482         break;
2483
2484     case ArithUnary:
2485         compileArithUnary(node);
2486         break;
2487
2488     case LogicalNot:
2489         compileLogicalNot(node);
2490         break;
2491
2492     case CompareLess:
2493         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
2494             return;
2495         break;
2496
2497     case CompareLessEq:
2498         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
2499             return;
2500         break;
2501
2502     case CompareGreater:
2503         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
2504             return;
2505         break;
2506
2507     case CompareGreaterEq:
2508         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
2509             return;
2510         break;
2511
2512     case CompareEq:
2513         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
2514             return;
2515         break;
2516
2517     case CompareStrictEq:
2518         if (compileStrictEq(node))
2519             return;
2520         break;
2521         
2522     case CompareEqPtr:
2523         compileCompareEqPtr(node);
2524         break;
2525
2526     case StringCharCodeAt: {
2527         compileGetCharCodeAt(node);
2528         break;
2529     }
2530
2531     case StringCharAt: {
2532         // Relies on StringCharAt node having same basic layout as GetByVal
2533         compileGetByValOnString(node);
2534         break;
2535     }
2536
2537     case StringFromCharCode: {
2538         compileFromCharCode(node);
2539         break;
2540     }
2541         
2542     case CheckArray: {
2543         checkArray(node);
2544         break;
2545     }
2546         
2547     case Arrayify:
2548     case ArrayifyToStructure: {
2549         arrayify(node);
2550         break;
2551     }
2552
2553     case GetByVal: {
2554         switch (node->arrayMode().type()) {
2555         case Array::SelectUsingPredictions:
2556         case Array::ForceExit:
2557             RELEASE_ASSERT_NOT_REACHED();
2558 #if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
2559             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
2560 #endif
2561             break;
2562         case Array::Undecided: {
2563             SpeculateStrictInt32Operand index(this, node->child2());
2564             GPRTemporary resultTag(this, Reuse, index);
2565             GPRTemporary resultPayload(this);
2566
2567             GPRReg indexGPR = index.gpr();
2568             GPRReg resultTagGPR = resultTag.gpr();
2569             GPRReg resultPayloadGPR = resultPayload.gpr();
2570
2571             speculationCheck(OutOfBounds, JSValueRegs(), node,
2572                 m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
2573
2574             use(node->child1());
2575             index.use();
2576
2577             m_jit.move(MacroAssembler::TrustedImm32(JSValue::UndefinedTag), resultTagGPR);
2578             m_jit.move(MacroAssembler::TrustedImm32(0), resultPayloadGPR);
2579             jsValueResult(resultTagGPR, resultPayloadGPR, node, UseChildrenCalledExplicitly);
2580             break;
2581         }
2582         case Array::Generic: {
2583             SpeculateCellOperand base(this, node->child1()); // Save a register, speculate cell. We'll probably be right.
2584             JSValueOperand property(this, node->child2());
2585             GPRReg baseGPR = base.gpr();
2586             JSValueRegs propertyRegs = property.jsValueRegs();
2587             
2588             flushRegisters();
2589             GPRFlushedCallResult2 resultTag(this);
2590             GPRFlushedCallResult resultPayload(this);
2591             callOperation(operationGetByValCell, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), baseGPR, propertyRegs);
2592             m_jit.exceptionCheck();
2593             
2594             jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
2595             break;
2596         }
2597         case Array::Int32:
2598         case Array::Contiguous: {
2599             if (node->arrayMode().isInBounds()) {
2600                 SpeculateStrictInt32Operand property(this, node->child2());
2601                 StorageOperand storage(this, node->child3());
2602             
2603                 GPRReg propertyReg = property.gpr();
2604                 GPRReg storageReg = storage.gpr();
2605             
2606                 if (!m_compileOkay)
2607                     return;
2608             
2609                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2610             
2611                 GPRTemporary resultPayload(this);
2612                 if (node->arrayMode().type() == Array::Int32) {
2613                     ASSERT(!node->arrayMode().isSaneChain());
2614                     
2615                     speculationCheck(
2616                         OutOfBounds, JSValueRegs(), 0,
2617                         m_jit.branch32(
2618                             MacroAssembler::Equal,
2619                             MacroAssembler::BaseIndex(
2620                                 storageReg, propertyReg, MacroAssembler::TimesEight, TagOffset),
2621                             TrustedImm32(JSValue::EmptyValueTag)));
2622                     m_jit.load32(
2623                         MacroAssembler::BaseIndex(
2624                             storageReg, propertyReg, MacroAssembler::TimesEight, PayloadOffset),
2625                         resultPayload.gpr());
2626                     int32Result(resultPayload.gpr(), node);
2627                     break;
2628                 }
2629                 
2630                 GPRTemporary resultTag(this);
2631                 m_jit.load32(
2632                     MacroAssembler::BaseIndex(
2633                         storageReg, propertyReg, MacroAssembler::TimesEight, TagOffset),
2634                     resultTag.gpr());
2635                 m_jit.load32(
2636                     MacroAssembler::BaseIndex(
2637                         storageReg, propertyReg, MacroAssembler::TimesEight, PayloadOffset),
2638                     resultPayload.gpr());
2639                 if (node->arrayMode().isSaneChain()) {
2640                     JITCompiler::Jump notHole = m_jit.branch32(
2641                         MacroAssembler::NotEqual, resultTag.gpr(),
2642                         TrustedImm32(JSValue::EmptyValueTag));
2643                     m_jit.move(TrustedImm32(JSValue::UndefinedTag), resultTag.gpr());
2644                     m_jit.move(TrustedImm32(0), resultPayload.gpr());
2645                     notHole.link(&m_jit);
2646                 } else {
2647                     speculationCheck(
2648                         LoadFromHole, JSValueRegs(), 0,
2649                         m_jit.branch32(
2650                             MacroAssembler::Equal, resultTag.gpr(),
2651                             TrustedImm32(JSValue::EmptyValueTag)));
2652                 }
2653                 jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
2654                 break;
2655             }
2656
2657             SpeculateCellOperand base(this, node->child1());
2658             SpeculateStrictInt32Operand property(this, node->child2());
2659             StorageOperand storage(this, node->child3());
2660             
2661             GPRReg baseReg = base.gpr();
2662             GPRReg propertyReg = property.gpr();
2663             GPRReg storageReg = storage.gpr();
2664             
2665             if (!m_compileOkay)
2666                 return;
2667             
2668             GPRTemporary resultTag(this);
2669             GPRTemporary resultPayload(this);
2670             GPRReg resultTagReg = resultTag.gpr();
2671             GPRReg resultPayloadReg = resultPayload.gpr();
2672             
2673             MacroAssembler::JumpList slowCases;
2674
2675             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2676             
2677             m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg);
2678             m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg);
2679             slowCases.append(m_jit.branch32(MacroAssembler::Equal, resultTagReg, TrustedImm32(JSValue::EmptyValueTag)));
2680             
2681             addSlowPathGenerator(
2682                 slowPathCall(
2683                     slowCases, this, operationGetByValObjectInt,
2684                     JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg));
2685             
2686             jsValueResult(resultTagReg, resultPayloadReg, node);
2687             break;
2688         }
2689         case Array::Double: {
2690             if (node->arrayMode().isInBounds()) {
2691                 SpeculateStrictInt32Operand property(this, node->child2());
2692                 StorageOperand storage(this, node->child3());
2693             
2694                 GPRReg propertyReg = property.gpr();
2695                 GPRReg storageReg = storage.gpr();
2696             
2697                 if (!m_compileOkay)
2698                     return;
2699             
2700                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2701             
2702                 FPRTemporary result(this);
2703                 m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr());
2704                 if (!node->arrayMode().isSaneChain())
2705                     speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr()));
2706                 doubleResult(result.fpr(), node);
2707                 break;
2708             }
2709
2710             SpeculateCellOperand base(this, node->child1());
2711             SpeculateStrictInt32Operand property(this, node->child2());
2712             StorageOperand storage(this, node->child3());
2713             
2714             GPRReg baseReg = base.gpr();
2715             GPRReg propertyReg = property.gpr();
2716             GPRReg storageReg = storage.gpr();
2717             
2718             if (!m_compileOkay)
2719                 return;
2720             
2721             GPRTemporary resultTag(this);
2722             GPRTemporary resultPayload(this);
2723             FPRTemporary temp(this);
2724             GPRReg resultTagReg = resultTag.gpr();
2725             GPRReg resultPayloadReg = resultPayload.gpr();
2726             FPRReg tempReg = temp.fpr();
2727             
2728             MacroAssembler::JumpList slowCases;
2729             
2730             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2731             
2732             m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), tempReg);
2733             slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempReg, tempReg));
2734             boxDouble(tempReg, resultTagReg, resultPayloadReg);
2735
2736             addSlowPathGenerator(
2737                 slowPathCall(
2738                     slowCases, this, operationGetByValObjectInt,
2739                     JSValueRegs(resultTagReg, resultPayloadReg), baseReg, propertyReg));
2740             
2741             jsValueResult(resultTagReg, resultPayloadReg, node);
2742             break;
2743         }
2744         case Array::ArrayStorage:
2745         case Array::SlowPutArrayStorage: {
2746             if (node->arrayMode().isInBounds()) {
2747                 SpeculateStrictInt32Operand property(this, node->child2());
2748                 StorageOperand storage(this, node->child3());
2749                 GPRReg propertyReg = property.gpr();
2750                 GPRReg storageReg = storage.gpr();
2751         
2752                 if (!m_compileOkay)
2753                     return;
2754
2755                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2756
2757                 GPRTemporary resultTag(this);
2758                 GPRTemporary resultPayload(this);
2759
2760                 m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag.gpr());
2761                 speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag)));
2762                 m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload.gpr());
2763             
2764                 jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
2765                 break;
2766             }
2767
2768             SpeculateCellOperand base(this, node->child1());
2769             SpeculateStrictInt32Operand property(this, node->child2());
2770             StorageOperand storage(this, node->child3());
2771             GPRReg propertyReg = property.gpr();
2772             GPRReg storageReg = storage.gpr();
2773             GPRReg baseReg = base.gpr();
2774
2775             if (!m_compileOkay)
2776                 return;
2777
2778             GPRTemporary resultTag(this);
2779             GPRTemporary resultPayload(this);
2780             GPRReg resultTagReg = resultTag.gpr();
2781             GPRReg resultPayloadReg = resultPayload.gpr();
2782
2783             JITCompiler::Jump outOfBounds = m_jit.branch32(
2784                 MacroAssembler::AboveOrEqual, propertyReg,
2785                 MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
2786
2787             m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTagReg);
2788             JITCompiler::Jump hole = m_jit.branch32(
2789                 MacroAssembler::Equal, resultTag.gpr(), TrustedImm32(JSValue::EmptyValueTag));
2790             m_jit.load32(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayloadReg);
2791             
2792             JITCompiler::JumpList slowCases;
2793             slowCases.append(outOfBounds);
2794             slowCases.append(hole);
2795             addSlowPathGenerator(
2796                 slowPathCall(
2797                     slowCases, this, operationGetByValObjectInt,
2798                     JSValueRegs(resultTagReg, resultPayloadReg),
2799                     baseReg, propertyReg));
2800
2801             jsValueResult(resultTagReg, resultPayloadReg, node);
2802             break;
2803         }
2804         case Array::String:
2805             compileGetByValOnString(node);
2806             break;
2807         case Array::DirectArguments:
2808             compileGetByValOnDirectArguments(node);
2809             break;
2810         case Array::ScopedArguments:
2811             compileGetByValOnScopedArguments(node);
2812             break;
2813         default: {
2814             TypedArrayType type = node->arrayMode().typedArrayType();
2815             if (isInt(type))
2816                 compileGetByValOnIntTypedArray(node, type);
2817             else
2818                 compileGetByValOnFloatTypedArray(node, type);
2819         } }
2820         break;
2821     }
2822     
2823     case ToLowerCase: {
2824         compileToLowerCase(node);
2825         break;
2826     }
2827
2828     case NumberToStringWithRadix: {
2829         compileNumberToStringWithRadix(node);
2830         break;
2831     }
2832
2833     case GetByValWithThis: {
2834         JSValueOperand base(this, node->child1());
2835         JSValueRegs baseRegs = base.jsValueRegs();
2836         JSValueOperand thisValue(this, node->child2());
2837         JSValueRegs thisValueRegs = thisValue.jsValueRegs();
2838         JSValueOperand subscript(this, node->child3());
2839         JSValueRegs subscriptRegs = subscript.jsValueRegs();
2840
2841         GPRFlushedCallResult resultPayload(this);
2842         GPRFlushedCallResult2 resultTag(this);
2843         GPRReg resultPayloadGPR = resultPayload.gpr();
2844         GPRReg resultTagGPR = resultTag.gpr();
2845
2846         flushRegisters();
2847         callOperation(operationGetByValWithThis, JSValueRegs(resultTagGPR, resultPayloadGPR), baseRegs, thisValueRegs, subscriptRegs);
2848         m_jit.exceptionCheck();
2849
2850         jsValueResult(resultTagGPR, resultPayloadGPR, node);
2851         break;
2852     }
2853
2854     case PutByValDirect:
2855     case PutByVal:
2856     case PutByValAlias: {
2857         Edge child1 = m_jit.graph().varArgChild(node, 0);
2858         Edge child2 = m_jit.graph().varArgChild(node, 1);
2859         Edge child3 = m_jit.graph().varArgChild(node, 2);
2860         Edge child4 = m_jit.graph().varArgChild(node, 3);
2861         
2862         ArrayMode arrayMode = node->arrayMode().modeForPut();
2863         bool alreadyHandled = false;
2864         
2865         switch (arrayMode.type()) {
2866         case Array::SelectUsingPredictions:
2867         case Array::ForceExit:
2868             RELEASE_ASSERT_NOT_REACHED();
2869 #if COMPILER_QUIRK(CONSIDERS_UNREACHABLE_CODE)
2870             terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
2871             alreadyHandled = true;
2872 #endif
2873             break;
2874         case Array::Generic: {
2875             ASSERT(node->op() == PutByVal || node->op() == PutByValDirect);
2876             
2877             SpeculateCellOperand base(this, child1); // Save a register, speculate cell. We'll probably be right.
2878             JSValueOperand property(this, child2);
2879             JSValueOperand value(this, child3);
2880             GPRReg baseGPR = base.gpr();
2881             JSValueRegs propertyRegs = property.jsValueRegs();
2882             JSValueRegs valueRegs = value.jsValueRegs();
2883             
2884             flushRegisters();
2885             if (node->op() == PutByValDirect)
2886                 callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValDirectCellStrict : operationPutByValDirectCellNonStrict, baseGPR, propertyRegs, valueRegs);
2887             else
2888                 callOperation(m_jit.codeBlock()->isStrictMode() ? operationPutByValCellStrict : operationPutByValCellNonStrict, baseGPR, propertyRegs, valueRegs);
2889             m_jit.exceptionCheck();
2890             
2891             noResult(node);
2892             alreadyHandled = true;
2893             break;
2894         }
2895         default:
2896             break;
2897         }
2898         
2899         if (alreadyHandled)
2900             break;
2901         
2902         SpeculateCellOperand base(this, child1);
2903         SpeculateStrictInt32Operand property(this, child2);
2904         
2905         GPRReg baseReg = base.gpr();
2906         GPRReg propertyReg = property.gpr();
2907
2908         switch (arrayMode.type()) {
2909         case Array::Int32: {
2910             SpeculateInt32Operand value(this, child3);
2911
2912             GPRReg valuePayloadReg = value.gpr();
2913         
2914             if (!m_compileOkay)
2915                 return;
2916             
2917             compileContiguousPutByVal(node, base, property, value, valuePayloadReg, TrustedImm32(JSValue::Int32Tag));
2918             break;
2919         }
2920         case Array::Contiguous: {
2921             JSValueOperand value(this, child3);
2922
2923             GPRReg valueTagReg = value.tagGPR();
2924             GPRReg valuePayloadReg = value.payloadGPR();
2925         
2926             if (!m_compileOkay)
2927                 return;
2928
2929             compileContiguousPutByVal(node, base, property, value, valuePayloadReg, valueTagReg);
2930             break;
2931         }
2932         case Array::Double: {
2933             compileDoublePutByVal(node, base, property);
2934             break;
2935         }
2936         case Array::ArrayStorage:
2937         case Array::SlowPutArrayStorage: {
2938             JSValueOperand value(this, child3);
2939
2940             GPRReg valueTagReg = value.tagGPR();
2941             GPRReg valuePayloadReg = value.payloadGPR();
2942             
2943             if (!m_compileOkay)
2944                 return;
2945
2946             StorageOperand storage(this, child4);
2947             GPRReg storageReg = storage.gpr();
2948
2949             if (node->op() == PutByValAlias) {
2950                 // Store the value to the array.
2951                 GPRReg propertyReg = property.gpr();
2952                 m_jit.store32(value.tagGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
2953                 m_jit.store32(value.payloadGPR(), MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
2954                 
2955                 noResult(node);
2956                 break;
2957             }
2958
2959             MacroAssembler::JumpList slowCases;
2960
2961             MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
2962             if (!arrayMode.isOutOfBounds())
2963                 speculationCheck(OutOfBounds, JSValueRegs(), 0, beyondArrayBounds);
2964             else
2965                 slowCases.append(beyondArrayBounds);
2966
2967             // Check if we're writing to a hole; if so increment m_numValuesInVector.
2968             if (arrayMode.isInBounds()) {
2969                 speculationCheck(
2970                     StoreToHole, JSValueRegs(), 0,
2971                     m_jit.branch32(MacroAssembler::Equal, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag)));
2972             } else {
2973                 MacroAssembler::Jump notHoleValue = m_jit.branch32(MacroAssembler::NotEqual, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), TrustedImm32(JSValue::EmptyValueTag));
2974                 if (arrayMode.isSlowPut()) {
2975                     // This is sort of strange. If we wanted to optimize this code path, we would invert
2976                     // the above branch. But it's simply not worth it since this only happens if we're
2977                     // already having a bad time.
2978                     slowCases.append(m_jit.jump());
2979                 } else {
2980                     m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
2981                 
2982                     // If we're writing to a hole we might be growing the array; 
2983                     MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2984                     m_jit.add32(TrustedImm32(1), propertyReg);
2985                     m_jit.store32(propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2986                     m_jit.sub32(TrustedImm32(1), propertyReg);
2987                 
2988                     lengthDoesNotNeedUpdate.link(&m_jit);
2989                 }
2990                 notHoleValue.link(&m_jit);
2991             }
2992     
2993             // Store the value to the array.
2994             m_jit.store32(valueTagReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
2995             m_jit.store32(valuePayloadReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
2996
2997             base.use();
2998             property.use();
2999             value.use();
3000             storage.use();
3001             
3002             if (!slowCases.empty()) {
3003                 if (node->op() == PutByValDirect) {
3004                     addSlowPathGenerator(slowPathCall(
3005                         slowCases, this,
3006                         m_jit.codeBlock()->isStrictMode() ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValDirectBeyondArrayBoundsNonStrict,
3007                         NoResult, baseReg, propertyReg, JSValueRegs(valueTagReg, valuePayloadReg)));
3008                 } else {
3009                     addSlowPathGenerator(slowPathCall(
3010                         slowCases, this,
3011                         m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
3012                         NoResult, baseReg, propertyReg, JSValueRegs(valueTagReg, valuePayloadReg)));
3013                 }
3014             }
3015
3016             noResult(node, UseChildrenCalledExplicitly);
3017             break;
3018         }
3019             
3020         default: {
3021             TypedArrayType type = arrayMode.typedArrayType();
3022             if (isInt(type))
3023                 compilePutByValForIntTypedArray(base.gpr(), property.gpr(), node, type);
3024             else
3025                 compilePutByValForFloatTypedArray(base.gpr(), property.gpr(), node, type);
3026         } }
3027         break;
3028     }
3029
3030     case PutByValWithThis: {
3031 #if CPU(X86)
3032         // We don't have enough registers on X86 to do this
3033         // without setting up the call frame incrementally.
3034         unsigned index = 0;
3035         m_jit.poke(GPRInfo::callFrameRegister, index++);
3036
3037         {
3038             JSValueOperand base(this, m_jit.graph().varArgChild(node, 0));
3039             GPRReg baseTag = base.tagGPR();
3040             GPRReg basePayload = base.payloadGPR();
3041
3042             JSValueOperand thisValue(this, m_jit.graph().varArgChild(node, 1));
3043             GPRReg thisValueTag = thisValue.tagGPR();
3044             GPRReg thisValuePayload = thisValue.payloadGPR();
3045
3046             JSValueOperand property(this, m_jit.graph().varArgChild(node, 2));
3047             GPRReg propertyTag = property.tagGPR();
3048             GPRReg propertyPayload = property.payloadGPR();
3049
3050             m_jit.poke(basePayload, index++);
3051             m_jit.poke(baseTag, index++);
3052
3053             m_jit.poke(thisValuePayload, index++);
3054             m_jit.poke(thisValueTag, index++);
3055
3056             m_jit.poke(propertyPayload, index++);
3057             m_jit.poke(propertyTag, index++);
3058
3059             flushRegisters();
3060         }
3061
3062         JSValueOperand value(this, m_jit.graph().varArgChild(node, 3));
3063         GPRReg valueTag = value.tagGPR();
3064         GPRReg valuePayload = value.payloadGPR();
3065         m_jit.poke(valuePayload, index++);
3066         m_jit.poke(valueTag, index++);
3067
3068         flushRegisters();
3069         appendCall(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis);
3070         m_jit.exceptionCheck();
3071 #elif CPU(MIPS)
3072         // We don't have enough registers on MIPS either but the ABI is a little different.
3073         unsigned index = 4;
3074         m_jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
3075         {
3076             JSValueOperand base(this, m_jit.graph().varArgChild(node, 0));
3077             GPRReg baseTag = base.tagGPR();
3078             GPRReg basePayload = base.payloadGPR();
3079
3080             JSValueOperand thisValue(this, m_jit.graph().varArgChild(node, 1));
3081             GPRReg thisValueTag = thisValue.tagGPR();
3082             GPRReg thisValuePayload = thisValue.payloadGPR();
3083
3084             JSValueOperand property(this, m_jit.graph().varArgChild(node, 2));
3085             GPRReg propertyTag = property.tagGPR();
3086             GPRReg propertyPayload = property.payloadGPR();
3087
3088             // for operationPutByValWithThis[Strict](), base is a 64 bits
3089             // argument, so it should be double word aligned on the stack.
3090             // This requirement still applies when it's in argument registers
3091             // instead of on the stack.
3092             m_jit.move(basePayload, GPRInfo::argumentGPR2);
3093             m_jit.move(baseTag, GPRInfo::argumentGPR3);
3094
3095             m_jit.poke(thisValuePayload, index++);
3096             m_jit.poke(thisValueTag, index++);
3097
3098             m_jit.poke(propertyPayload, index++);
3099             m_jit.poke(propertyTag, index++);
3100
3101             flushRegisters();
3102         }
3103
3104         JSValueOperand value(this, m_jit.graph().varArgChild(node, 3));
3105         GPRReg valueTag = value.tagGPR();
3106         GPRReg valuePayload = value.payloadGPR();
3107         m_jit.poke(valuePayload, index++);
3108         m_jit.poke(valueTag, index++);
3109
3110         flushRegisters();
3111         appendCall(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis);
3112         m_jit.exceptionCheck();
3113 #else
3114         static_assert(GPRInfo::numberOfRegisters >= 8, "We are assuming we have enough registers to make this call without incrementally setting up the arguments.");
3115
3116         JSValueOperand base(this, m_jit.graph().varArgChild(node, 0));
3117         JSValueRegs baseRegs = base.jsValueRegs();
3118
3119         JSValueOperand thisValue(this, m_jit.graph().varArgChild(node, 1));
3120         JSValueRegs thisRegs = thisValue.jsValueRegs();
3121
3122         JSValueOperand property(this, m_jit.graph().varArgChild(node, 2));
3123         JSValueRegs propertyRegs = property.jsValueRegs();
3124
3125         JSValueOperand value(this, m_jit.graph().varArgChild(node, 3));
3126         JSValueRegs valueRegs = value.jsValueRegs();
3127
3128         flushRegisters();
3129         callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValWithThisStrict : operationPutByValWithThis,
3130             NoResult, baseRegs, thisRegs, propertyRegs, valueRegs);
3131         m_jit.exceptionCheck();
3132 #endif // CPU(X86)
3133
3134         noResult(node);
3135         break;
3136     }
3137
3138     case RegExpExec: {
3139         SpeculateCellOperand globalObject(this, node->child1());
3140         GPRReg globalObjectGPR = globalObject.gpr();
3141         
3142         if (node->child2().useKind() == RegExpObjectUse) {
3143             if (node->child3().useKind() == StringUse) {
3144                 SpeculateCellOperand base(this, node->child2());
3145                 SpeculateCellOperand argument(this, node->child3());
3146                 GPRReg baseGPR = base.gpr();
3147                 GPRReg argumentGPR = argument.gpr();
3148                 speculateRegExpObject(node->child2(), baseGPR);
3149                 speculateString(node->child3(), argumentGPR);
3150                 
3151                 flushRegisters();
3152                 GPRFlushedCallResult2 resultTag(this);
3153                 GPRFlushedCallResult resultPayload(this);
3154                 callOperation(
3155                     operationRegExpExecString, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
3156                     globalObjectGPR, baseGPR, argumentGPR);
3157                 m_jit.exceptionCheck();
3158                 
3159                 jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
3160                 break;
3161             }
3162             
3163             SpeculateCellOperand base(this, node->child2());
3164             JSValueOperand argument(this, node->child3());
3165             GPRReg baseGPR = base.gpr();
3166             JSValueRegs argumentRegs = argument.jsValueRegs();
3167             speculateRegExpObject(node->child2(), baseGPR);
3168         
3169             flushRegisters();
3170             GPRFlushedCallResult2 resultTag(this);
3171             GPRFlushedCallResult resultPayload(this);
3172             callOperation(
3173                 operationRegExpExec, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), globalObjectGPR, baseGPR, argumentRegs);
3174             m_jit.exceptionCheck();
3175         
3176             jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
3177             break;
3178         }
3179         
3180         JSValueOperand base(this, node->child2());
3181         JSValueOperand argument(this, node->child3());
3182         JSValueRegs baseRegs = base.jsValueRegs();
3183         JSValueRegs argumentRegs = argument.jsValueRegs();
3184         
3185         flushRegisters();
3186         GPRFlushedCallResult2 resultTag(this);
3187         GPRFlushedCallResult resultPayload(this);
3188         callOperation(
3189             operationRegExpExecGeneric, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), globalObjectGPR, baseRegs, argumentRegs);
3190         m_jit.exceptionCheck();
3191         
3192         jsValueResult(resultTag.gpr(), resultPayload.gpr(), node);
3193         break;
3194     }
3195         
3196     case RegExpTest: {
3197         SpeculateCellOperand globalObject(this, node->child1());
3198         GPRReg globalObjectGPR = globalObject.gpr();
3199         
3200         if (node->child2().useKind() == RegExpObjectUse) {
3201             if (node->child3().useKind() == StringUse) {
3202                 SpeculateCellOperand base(this, node->child2());
3203                 SpeculateCellOperand argument(this, node->child3());
3204                 GPRReg baseGPR = base.gpr();
3205                 GPRReg argumentGPR = argument.gpr();
3206                 speculateRegExpObject(node->child2(), baseGPR);
3207                 speculateString(node->child3(), argumentGPR);
3208                 
3209                 flushRegisters();
3210                 GPRFlushedCallResult result(this);
3211                 callOperation(
3212                     operationRegExpTestString, result.gpr(), globalObjectGPR, baseGPR, argumentGPR);
3213                 m_jit.exceptionCheck();
3214                 
3215                 booleanResult(result.gpr(), node);
3216                 break;
3217             }
3218             
3219             SpeculateCellOperand base(this, node->child2());
3220             JSValueOperand argument(this, node->child3());
3221             GPRReg baseGPR = base.gpr();
3222             JSValueRegs argumentRegs = argument.jsValueRegs();
3223             speculateRegExpObject(node->child2(), baseGPR);
3224         
3225             flushRegisters();
3226             GPRFlushedCallResult result(this);
3227             callOperation(
3228                 operationRegExpTest, result.gpr(), globalObjectGPR, baseGPR, argumentRegs);
3229             m_jit.exceptionCheck();
3230         
3231             booleanResult(result.gpr(), node);
3232             break;
3233         }
3234         
3235         JSValueOperand base(this, node->child2());
3236         JSValueOperand argument(this, node->child3());
3237         JSValueRegs baseRegs = base.jsValueRegs();
3238         JSValueRegs argumentRegs = argument.jsValueRegs();
3239
3240         flushRegisters();
3241         GPRFlushedCallResult result(this);
3242         callOperation(
3243             operationRegExpTestGeneric, result.gpr(), globalObjectGPR, baseRegs, argumentRegs);
3244         m_jit.exceptionCheck();
3245         
3246         booleanResult(result.gpr(), node);
3247         break;
3248     }
3249
3250     case StringReplace:
3251     case StringReplaceRegExp: {
3252         if (node->child1().useKind() == StringUse
3253             && node->child2().useKind() == RegExpObjectUse
3254             && node->child3().useKind() == StringUse) {
3255             if (JSString* replace = node->child3()->dynamicCastConstant<JSString*>(*m_jit.vm())) {
3256                 if (!replace->length()) {
3257                     SpeculateCellOperand string(this, node->child1());
3258                     SpeculateCellOperand regExp(this, node->child2());
3259                     GPRReg stringGPR = string.gpr();
3260                     GPRReg regExpGPR = regExp.gpr();
3261                     speculateString(node->child1(), stringGPR);
3262                     speculateRegExpObject(node->child2(), regExpGPR);
3263
3264                     flushRegisters();
3265                     GPRFlushedCallResult2 resultTag(this);
3266                     GPRFlushedCallResult resultPayload(this);
3267                     callOperation(
3268                         operationStringProtoFuncReplaceRegExpEmptyStr, JSValueRegs(resultTag.gpr(), resultPayload.gpr()), stringGPR, regExpGPR);
3269                     m_jit.exceptionCheck();
3270                     cellResult(resultPayload.gpr(), node);
3271                     break;
3272                 }
3273             }
3274             
3275             SpeculateCellOperand string(this, node->child1());
3276             SpeculateCellOperand regExp(this, node->child2());
3277             SpeculateCellOperand replace(this, node->child3());
3278             GPRReg stringGPR = string.gpr();
3279             GPRReg regExpGPR = regExp.gpr();
3280             GPRReg replaceGPR = replace.gpr();
3281             speculateString(node->child1(), stringGPR);
3282             speculateRegExpObject(node->child2(), regExpGPR);
3283             speculateString(node->child3(), replaceGPR);
3284             
3285             flushRegisters();
3286             GPRFlushedCallResult2 resultTag(this);
3287             GPRFlushedCallResult resultPayload(this);
3288             callOperation(
3289                 operationStringProtoFuncReplaceRegExpString, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
3290                 stringGPR, regExpGPR, replaceGPR);
3291             m_jit.exceptionCheck();
3292             cellResult(resultPayload.gpr(), node);
3293             break;
3294         }
3295
3296         // If we fixed up the edge of child2, we inserted a Check(@child2, String).
3297         OperandSpeculationMode child2SpeculationMode = AutomaticOperandSpeculation;
3298         if (node->child2().useKind() == StringUse)
3299             child2SpeculationMode = ManualOperandSpeculation;
3300         
3301         JSValueOperand string(this, node->child1());
3302         JSValueOperand search(this, node->child2(), child2SpeculationMode);
3303         JSValueOperand replace(this, node->child3());
3304         JSValueRegs stringRegs = string.jsValueRegs();
3305         JSValueRegs searchRegs = search.jsValueRegs();
3306         JSValueRegs replaceRegs = replace.jsValueRegs();
3307         
3308         flushRegisters();
3309         GPRFlushedCallResult2 resultTag(this);
3310         GPRFlushedCallResult resultPayload(this);
3311         callOperation(
3312             operationStringProtoFuncReplaceGeneric, JSValueRegs(resultTag.gpr(), resultPayload.gpr()),
3313             stringRegs, searchRegs, replaceRegs); 
3314         m_jit.exceptionCheck();
3315         cellResult(resultPayload.gpr(), node);
3316         break;
3317     }
3318
3319     case GetRegExpObjectLastIndex: {
3320         compileGetRegExpObjectLastIndex(node);
3321         break;
3322     }
3323         
3324     case SetRegExpObjectLastIndex: {
3325         compileSetRegExpObjectLastIndex(node);
3326         break;
3327     }
3328         
3329     case RecordRegExpCachedResult: {
3330         compileRecordRegExpCachedResult(node);
3331         break;
3332     }
3333         
3334     case ArrayPush: {
3335         ASSERT(node->arrayMode().isJSArray());
3336         
3337         SpeculateCellOperand base(this, node->child1());
3338         GPRTemporary storageLength(this);
3339         
3340         GPRReg baseGPR = base.gpr();
3341         GPRReg storageLengthGPR = storageLength.gpr();
3342         
3343         StorageOperand storage(this, node->child3());
3344         GPRReg storageGPR = storage.gpr();
3345         
3346         switch (node->arrayMode().type()) {
3347         case Array::Int32: {
3348             SpeculateInt32Operand value(this, node->child2());
3349             GPRReg valuePayloadGPR = value.gpr();
3350             
3351             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3352             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
3353             m_jit.store32(TrustedImm32(JSValue::Int32Tag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
3354             m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
3355             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3356             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3357             m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
3358             
3359             addSlowPathGenerator(
3360                 slowPathCall(
3361                     slowPath, this, operationArrayPush,
3362                     JSValueRegs(storageGPR, storageLengthGPR),
3363                     TrustedImm32(JSValue::Int32Tag), valuePayloadGPR, baseGPR));
3364         
3365             jsValueResult(storageGPR, storageLengthGPR, node);
3366             break;
3367         }
3368             
3369         case Array::Contiguous: {
3370             JSValueOperand value(this, node->child2());
3371             GPRReg valueTagGPR = value.tagGPR();
3372             GPRReg valuePayloadGPR = value.payloadGPR();
3373
3374             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3375             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
3376             m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
3377             m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
3378             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3379             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3380             m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
3381             
3382             addSlowPathGenerator(
3383                 slowPathCall(
3384                     slowPath, this, operationArrayPush,
3385                     JSValueRegs(storageGPR, storageLengthGPR),
3386                     JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
3387         
3388             jsValueResult(storageGPR, storageLengthGPR, node);
3389             break;
3390         }
3391             
3392         case Array::Double: {
3393             SpeculateDoubleOperand value(this, node->child2());
3394             FPRReg valueFPR = value.fpr();
3395
3396             DFG_TYPE_CHECK(
3397                 JSValueRegs(), node->child2(), SpecDoubleReal,
3398                 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
3399             
3400             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3401             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
3402             m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3403             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3404             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3405             m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
3406             
3407             addSlowPathGenerator(
3408                 slowPathCall(
3409                     slowPath, this, operationArrayPushDouble,
3410                     JSValueRegs(storageGPR, storageLengthGPR),
3411                     valueFPR, baseGPR));
3412         
3413             jsValueResult(storageGPR, storageLengthGPR, node);
3414             break;
3415         }
3416             
3417         case Array::ArrayStorage: {
3418             JSValueOperand value(this, node->child2());
3419             GPRReg valueTagGPR = value.tagGPR();
3420             GPRReg valuePayloadGPR = value.payloadGPR();
3421
3422             m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
3423         
3424             // Refuse to handle bizarre lengths.
3425             speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
3426         
3427             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
3428         
3429             m_jit.store32(valueTagGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
3430             m_jit.store32(valuePayloadGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
3431         
3432             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3433             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
3434             m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
3435             m_jit.move(TrustedImm32(JSValue::Int32Tag), storageGPR);
3436         
3437             addSlowPathGenerator(slowPathCall(slowPath, this, operationArrayPush, JSValueRegs(storageGPR, storageLengthGPR),
3438                 JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
3439         
3440             jsValueResult(storageGPR, storageLengthGPR, node);
3441             break;
3442         }
3443             
3444         default:
3445             CRASH();
3446             break;
3447         }
3448         break;
3449     }
3450         
3451     case ArrayPop: {
3452         ASSERT(node->arrayMode().isJSArray());
3453         
3454         SpeculateCellOperand base(this, node->child1());
3455         StorageOperand storage(this, node->child2());
3456         GPRTemporary valueTag(this);
3457         GPRTemporary valuePayload(this);
3458         
3459         GPRReg baseGPR = base.gpr();
3460         GPRReg valueTagGPR = valueTag.gpr();
3461         GPRReg valuePayloadGPR = valuePayload.gpr();
3462         GPRReg storageGPR = storage.gpr();
3463         
3464         switch (node->arrayMode().type()) {
3465         case Array::Int32:
3466         case Array::Contiguous: {
3467             m_jit.load32(
3468                 MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), valuePayloadGPR);
3469             MacroAssembler::Jump undefinedCase =
3470                 m_jit.branchTest32(MacroAssembler::Zero, valuePayloadGPR);
3471             m_jit.sub32(TrustedImm32(1), valuePayloadGPR);
3472             m_jit.store32(
3473                 valuePayloadGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3474             m_jit.load32(
3475                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)),
3476                 valueTagGPR);
3477             MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::Equal, valueTagGPR, TrustedImm32(JSValue::EmptyValueTag));
3478             m_jit.store32(
3479                 MacroAssembler::TrustedImm32(JSValue::EmptyValueTag),
3480                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
3481             m_jit.load32(
3482                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)),
3483                 valuePayloadGPR);
3484
3485             addSlowPathGenerator(
3486                 slowPathMove(
3487                     undefinedCase, this,
3488                     MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR,
3489                     MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR));
3490             addSlowPathGenerator(
3491                 slowPathCall(
3492                     slowCase, this, operationArrayPopAndRecoverLength,
3493                     JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
3494             
3495             jsValueResult(valueTagGPR, valuePayloadGPR, node);
3496             break;
3497         }
3498             
3499         case Array::Double: {
3500             FPRTemporary temp(this);
3501             FPRReg tempFPR = temp.fpr();
3502             
3503             m_jit.load32(
3504                 MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), valuePayloadGPR);
3505             MacroAssembler::Jump undefinedCase =
3506                 m_jit.branchTest32(MacroAssembler::Zero, valuePayloadGPR);
3507             m_jit.sub32(TrustedImm32(1), valuePayloadGPR);
3508             m_jit.store32(
3509                 valuePayloadGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3510             m_jit.loadDouble(
3511                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight),
3512                 tempFPR);
3513             MacroAssembler::Jump slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR);
3514             JSValue nan = JSValue(JSValue::EncodeAsDouble, PNaN);
3515             m_jit.store32(
3516                 MacroAssembler::TrustedImm32(nan.u.asBits.tag),
3517                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
3518             m_jit.store32(
3519                 MacroAssembler::TrustedImm32(nan.u.asBits.payload),
3520                 MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
3521             boxDouble(tempFPR, valueTagGPR, valuePayloadGPR);
3522
3523             addSlowPathGenerator(
3524                 slowPathMove(
3525                     undefinedCase, this,
3526                     MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR,
3527                     MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR));
3528             addSlowPathGenerator(
3529                 slowPathCall(
3530                     slowCase, this, operationArrayPopAndRecoverLength,
3531                     JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
3532             
3533             jsValueResult(valueTagGPR, valuePayloadGPR, node);
3534             break;
3535         }
3536
3537         case Array::ArrayStorage: {
3538             GPRTemporary storageLength(this);
3539             GPRReg storageLengthGPR = storageLength.gpr();
3540
3541             m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
3542         
3543             JITCompiler::JumpList setUndefinedCases;
3544             setUndefinedCases.append(m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR));
3545         
3546             m_jit.sub32(TrustedImm32(1), storageLengthGPR);
3547         
3548             MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
3549         
3550             m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), valueTagGPR);
3551             m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), valuePayloadGPR);
3552         
3553             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
3554
3555             setUndefinedCases.append(m_jit.branch32(MacroAssembler::Equal, TrustedImm32(JSValue::EmptyValueTag), valueTagGPR));
3556         
3557             m_jit.store32(TrustedImm32(JSValue::EmptyValueTag), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
3558
3559             m_jit.sub32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
3560         
3561             addSlowPathGenerator(
3562                 slowPathMove(
3563                     setUndefinedCases, this,
3564                     MacroAssembler::TrustedImm32(jsUndefined().tag()), valueTagGPR,
3565                     MacroAssembler::TrustedImm32(jsUndefined().payload()), valuePayloadGPR));
3566         
3567             addSlowPathGenerator(
3568                 slowPathCall(
3569                     slowCase, this, operationArrayPop,
3570                     JSValueRegs(valueTagGPR, valuePayloadGPR), baseGPR));
3571
3572             jsValueResult(valueTagGPR, valuePayloadGPR, node);
3573             break;
3574         }
3575             
3576         default:
3577             CRASH();
3578             break;
3579         }
3580         break;
3581     }
3582
3583     case ArraySlice: {
3584         compileArraySlice(node);
3585         break;
3586     }
3587
3588     case ArrayIndexOf: {
3589         compileArrayIndexOf(node);
3590         break;
3591     }
3592
3593     case DFG::Jump: {
3594         jump(node->targetBlock());
3595         noResult(node);
3596         break;
3597     }
3598
3599     case Branch:
3600         emitBranch(node);
3601         break;
3602         
3603     case Switch:
3604         emitSwitch(node);
3605         break;
3606
3607     case Return: {
3608         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT2);
3609         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
3610         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
3611
3612         // Return the result in returnValueGPR.
3613         JSValueOperand op1(this, node->child1());
3614         op1.fill();
3615         if (op1.isDouble())
3616             boxDouble(op1.fpr(), GPRInfo::returnValueGPR2, GPRInfo::returnValueGPR);
3617         else {
3618             if (op1.payloadGPR() == GPRInfo::returnValueGPR2 && op1.tagGPR() == GPRInfo::returnValueGPR)
3619                 m_jit.swap(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR2);
3620             else if (op1.payloadGPR() == GPRInfo::returnValueGPR2) {
3621                 m_jit.move(op1.payloadGPR(), GPRInfo::returnValueGPR);
3622                 m_jit.move(op1.tagGPR(), GPRInfo::returnValueGPR2);
3623             } else {
3624                 m_jit.move(op1.tagGPR(), GPRInfo::returnValueGPR2);
3625                 m_jit.move(op1.payloadGPR(), GPRInfo::returnValueGPR);
3626             }
3627         }
3628
3629         m_jit.emitRestoreCalleeSaves();
3630         m_jit.emitFunctionEpilogue();
3631         m_jit.ret();
3632         
3633         noResult(node);
3634         break;
3635     }
3636         
3637     case Throw:
3638     case ThrowStaticError: {
3639         // We expect that throw statements are rare and are intended to exit the code block
3640         // anyway, so we just OSR back to the old JIT for now.
3641         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
3642         break;
3643     }
3644         
3645     case BooleanToNumber: {
3646         switch (node->child1().useKind()) {
3647         case BooleanUse: {
3648             SpeculateBooleanOperand value(this, node->child1());
3649             GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
3650             
3651             m_jit.move(value.gpr(), result.gpr());
3652
3653             int32Result(result.gpr(), node);
3654             break;
3655         }
3656             
3657         case UntypedUse: {
3658             JSValueOperand value(this, node->child1());
3659             
3660             if (!m_interpreter.needsTypeCheck(node->child1(), SpecBoolInt32 | SpecBoolean)) {
3661                 GPRTemporary result(this);
3662                 
3663                 GPRReg valueGPR = value.payloadGPR();
3664                 GPRReg resultGPR = result.gpr();
3665                 
3666                 m_jit.move(valueGPR, resultGPR);
3667                 int32Result(result.gpr(), node);
3668                 break;
3669             }
3670             
3671             GPRTemporary resultTag(this);
3672             GPRTemporary resultPayload(this);
3673             
3674             GPRReg valueTagGPR = value.tagGPR();
3675             GPRReg valuePayloadGPR = value.payloadGPR();
3676             GPRReg resultTagGPR = resultTag.gpr();
3677             GPRReg resultPayloadGPR = resultPayload.gpr();
3678             
3679             m_jit.move(valuePayloadGPR, resultPayloadGPR);
3680             JITCompiler::Jump isBoolean = m_jit.branch32(
3681                 JITCompiler::Equal, valueTagGPR, TrustedImm32(JSValue::BooleanTag));
3682             m_jit.move(valueTagGPR, resultTagGPR);
3683             JITCompiler::Jump done = m_jit.jump();
3684             isBoolean.link(&m_jit);
3685             m_jit.move(TrustedImm32(JSValue::Int32Tag), resultTagGPR);
3686             done.link(&m_jit);
3687             
3688             jsValueResult(resultTagGPR, resultPayloadGPR, node);
3689             break;
3690         }
3691