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