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