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