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