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