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