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