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