cc49bb2df198df6245eafbf028ab2ac13bb7267d
[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     if (node->child1()->isInt32Constant()) {
1474         SpeculateInt32Operand op2(this, node->child2());
1475         GPRTemporary result(this, Reuse, op2);
1476         int32_t imm = node->child1()->asInt32();
1477         m_jit.compare32(condition, JITCompiler::Imm32(imm), 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     } else if (node->child2()->isInt32Constant()) {
1483         SpeculateInt32Operand op1(this, node->child1());
1484         GPRTemporary result(this, Reuse, op1);
1485         int32_t imm = node->child2()->asInt32();
1486         m_jit.compare32(condition, op1.gpr(), JITCompiler::Imm32(imm), result.gpr());
1487
1488         // If we add a DataFormatBool, we should use it here.
1489         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1490         jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1491     } else {
1492         SpeculateInt32Operand op1(this, node->child1());
1493         SpeculateInt32Operand op2(this, node->child2());
1494         GPRTemporary result(this, Reuse, op1, op2);
1495         m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
1496
1497         // If we add a DataFormatBool, we should use it here.
1498         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1499         jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1500     }
1501 }
1502
1503 void SpeculativeJIT::compileInt52Compare(Node* node, MacroAssembler::RelationalCondition condition)
1504 {
1505     SpeculateWhicheverInt52Operand op1(this, node->child1());
1506     SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
1507     GPRTemporary result(this, Reuse, op1, op2);
1508     
1509     m_jit.compare64(condition, op1.gpr(), op2.gpr(), result.gpr());
1510     
1511     // If we add a DataFormatBool, we should use it here.
1512     m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1513     jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1514 }
1515
1516 void SpeculativeJIT::compilePeepHoleInt52Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
1517 {
1518     BasicBlock* taken = branchNode->branchData()->taken.block;
1519     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
1520
1521     // The branch instruction will branch to the taken block.
1522     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
1523     if (taken == nextBlock()) {
1524         condition = JITCompiler::invert(condition);
1525         BasicBlock* tmp = taken;
1526         taken = notTaken;
1527         notTaken = tmp;
1528     }
1529     
1530     SpeculateWhicheverInt52Operand op1(this, node->child1());
1531     SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
1532     
1533     branch64(condition, op1.gpr(), op2.gpr(), taken);
1534     jump(notTaken);
1535 }
1536
1537 void SpeculativeJIT::compileDoubleCompare(Node* node, MacroAssembler::DoubleCondition condition)
1538 {
1539     SpeculateDoubleOperand op1(this, node->child1());
1540     SpeculateDoubleOperand op2(this, node->child2());
1541     GPRTemporary result(this);
1542     
1543     m_jit.move(TrustedImm32(ValueTrue), result.gpr());
1544     MacroAssembler::Jump trueCase = m_jit.branchDouble(condition, op1.fpr(), op2.fpr());
1545     m_jit.xor64(TrustedImm32(true), result.gpr());
1546     trueCase.link(&m_jit);
1547     
1548     jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1549 }
1550
1551 void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
1552 {
1553     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
1554     GPRTemporary result(this);
1555     GPRReg valueGPR = value.gpr();
1556     GPRReg resultGPR = result.gpr();
1557     GPRTemporary structure;
1558     GPRReg structureGPR = InvalidGPRReg;
1559     GPRTemporary scratch;
1560     GPRReg scratchGPR = InvalidGPRReg;
1561
1562     bool masqueradesAsUndefinedWatchpointValid =
1563         masqueradesAsUndefinedWatchpointIsStillValid();
1564
1565     if (!masqueradesAsUndefinedWatchpointValid) {
1566         // The masquerades as undefined case will use the structure register, so allocate it here.
1567         // Do this at the top of the function to avoid branching around a register allocation.
1568         GPRTemporary realStructure(this);
1569         GPRTemporary realScratch(this);
1570         structure.adopt(realStructure);
1571         scratch.adopt(realScratch);
1572         structureGPR = structure.gpr();
1573         scratchGPR = scratch.gpr();
1574     }
1575
1576     MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
1577     if (masqueradesAsUndefinedWatchpointValid) {
1578         DFG_TYPE_CHECK(
1579             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1580     } else {
1581         DFG_TYPE_CHECK(
1582             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1583
1584         MacroAssembler::Jump isNotMasqueradesAsUndefined = 
1585             m_jit.branchTest8(
1586                 MacroAssembler::Zero, 
1587                 MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), 
1588                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined));
1589
1590         m_jit.emitLoadStructure(valueGPR, structureGPR, scratchGPR);
1591         speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, 
1592             m_jit.branchPtr(
1593                 MacroAssembler::Equal, 
1594                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
1595                 MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->origin.semantic))));
1596
1597         isNotMasqueradesAsUndefined.link(&m_jit);
1598     }
1599     m_jit.move(TrustedImm32(ValueFalse), resultGPR);
1600     MacroAssembler::Jump done = m_jit.jump();
1601     
1602     notCell.link(&m_jit);
1603
1604     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
1605         m_jit.move(valueGPR, resultGPR);
1606         m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
1607         typeCheck(
1608             JSValueRegs(valueGPR), nodeUse, SpecCell | SpecOther, m_jit.branch64(
1609                 MacroAssembler::NotEqual, 
1610                 resultGPR, 
1611                 MacroAssembler::TrustedImm64(ValueNull)));
1612     }
1613     m_jit.move(TrustedImm32(ValueTrue), resultGPR);
1614     
1615     done.link(&m_jit);
1616     
1617     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
1618 }
1619
1620 void SpeculativeJIT::compileLogicalNot(Node* node)
1621 {
1622     switch (node->child1().useKind()) {
1623     case ObjectOrOtherUse: {
1624         compileObjectOrOtherLogicalNot(node->child1());
1625         return;
1626     }
1627         
1628     case Int32Use: {
1629         SpeculateInt32Operand value(this, node->child1());
1630         GPRTemporary result(this, Reuse, value);
1631         m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), result.gpr());
1632         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1633         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1634         return;
1635     }
1636         
1637     case DoubleRepUse: {
1638         SpeculateDoubleOperand value(this, node->child1());
1639         FPRTemporary scratch(this);
1640         GPRTemporary result(this);
1641         m_jit.move(TrustedImm32(ValueFalse), result.gpr());
1642         MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
1643         m_jit.xor32(TrustedImm32(true), result.gpr());
1644         nonZero.link(&m_jit);
1645         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1646         return;
1647     }
1648     
1649     case BooleanUse:
1650     case KnownBooleanUse: {
1651         if (!needsTypeCheck(node->child1(), SpecBoolean)) {
1652             SpeculateBooleanOperand value(this, node->child1());
1653             GPRTemporary result(this, Reuse, value);
1654             
1655             m_jit.move(value.gpr(), result.gpr());
1656             m_jit.xor64(TrustedImm32(true), result.gpr());
1657             
1658             jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1659             return;
1660         }
1661         
1662         JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
1663         GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
1664         
1665         m_jit.move(value.gpr(), result.gpr());
1666         m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
1667         typeCheck(
1668             JSValueRegs(value.gpr()), node->child1(), SpecBoolean, m_jit.branchTest64(
1669                 JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1670         m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
1671         
1672         // If we add a DataFormatBool, we should use it here.
1673         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1674         return;
1675     }
1676         
1677     case UntypedUse: {
1678         JSValueOperand arg1(this, node->child1());
1679         GPRTemporary result(this);
1680     
1681         GPRReg arg1GPR = arg1.gpr();
1682         GPRReg resultGPR = result.gpr();
1683     
1684         arg1.use();
1685     
1686         m_jit.move(arg1GPR, resultGPR);
1687         m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), resultGPR);
1688         JITCompiler::Jump slowCase = m_jit.branchTest64(JITCompiler::NonZero, resultGPR, TrustedImm32(static_cast<int32_t>(~1)));
1689     
1690         addSlowPathGenerator(
1691             slowPathCall(slowCase, this, operationConvertJSValueToBoolean, resultGPR, arg1GPR, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded));
1692     
1693         m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), resultGPR);
1694         jsValueResult(resultGPR, node, DataFormatJSBoolean, UseChildrenCalledExplicitly);
1695         return;
1696     }
1697     case StringUse:
1698         return compileStringZeroLength(node);
1699
1700     default:
1701         DFG_CRASH(m_jit.graph(), node, "Bad use kind");
1702         break;
1703     }
1704 }
1705
1706 void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
1707 {
1708     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
1709     GPRTemporary scratch(this);
1710     GPRTemporary structure;
1711     GPRReg valueGPR = value.gpr();
1712     GPRReg scratchGPR = scratch.gpr();
1713     GPRReg structureGPR = InvalidGPRReg;
1714
1715     if (!masqueradesAsUndefinedWatchpointIsStillValid()) {
1716         GPRTemporary realStructure(this);
1717         structure.adopt(realStructure);
1718         structureGPR = structure.gpr();
1719     }
1720
1721     MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
1722     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
1723         DFG_TYPE_CHECK(
1724             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1725     } else {
1726         DFG_TYPE_CHECK(
1727             JSValueRegs(valueGPR), nodeUse, (~SpecCell) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1728
1729         JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
1730             JITCompiler::Zero, 
1731             MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), 
1732             TrustedImm32(MasqueradesAsUndefined));
1733
1734         m_jit.emitLoadStructure(valueGPR, structureGPR, scratchGPR);
1735         speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1736             m_jit.branchPtr(
1737                 MacroAssembler::Equal, 
1738                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
1739                 MacroAssembler::TrustedImmPtr(m_jit.graph().globalObjectFor(m_currentNode->origin.semantic))));
1740
1741         isNotMasqueradesAsUndefined.link(&m_jit);
1742     }
1743     jump(taken, ForceJump);
1744     
1745     notCell.link(&m_jit);
1746     
1747     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
1748         m_jit.move(valueGPR, scratchGPR);
1749         m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
1750         typeCheck(
1751             JSValueRegs(valueGPR), nodeUse, SpecCell | SpecOther, m_jit.branch64(
1752                 MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
1753     }
1754     jump(notTaken);
1755     
1756     noResult(m_currentNode);
1757 }
1758
1759 void SpeculativeJIT::emitBranch(Node* node)
1760 {
1761     BasicBlock* taken = node->branchData()->taken.block;
1762     BasicBlock* notTaken = node->branchData()->notTaken.block;
1763     
1764     switch (node->child1().useKind()) {
1765     case ObjectOrOtherUse: {
1766         emitObjectOrOtherBranch(node->child1(), taken, notTaken);
1767         return;
1768     }
1769         
1770     case Int32Use:
1771     case DoubleRepUse: {
1772         if (node->child1().useKind() == Int32Use) {
1773             bool invert = false;
1774             
1775             if (taken == nextBlock()) {
1776                 invert = true;
1777                 BasicBlock* tmp = taken;
1778                 taken = notTaken;
1779                 notTaken = tmp;
1780             }
1781
1782             SpeculateInt32Operand value(this, node->child1());
1783             branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr(), taken);
1784         } else {
1785             SpeculateDoubleOperand value(this, node->child1());
1786             FPRTemporary scratch(this);
1787             branchDoubleNonZero(value.fpr(), scratch.fpr(), taken);
1788         }
1789         
1790         jump(notTaken);
1791         
1792         noResult(node);
1793         return;
1794     }
1795
1796     case StringUse: {
1797         emitStringBranch(node->child1(), taken, notTaken);
1798         return;
1799     }
1800
1801     case UntypedUse:
1802     case BooleanUse:
1803     case KnownBooleanUse: {
1804         JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
1805         GPRReg valueGPR = value.gpr();
1806         
1807         if (node->child1().useKind() == BooleanUse || node->child1().useKind() == KnownBooleanUse) {
1808             if (!needsTypeCheck(node->child1(), SpecBoolean)) {
1809                 MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1810                 
1811                 if (taken == nextBlock()) {
1812                     condition = MacroAssembler::Zero;
1813                     BasicBlock* tmp = taken;
1814                     taken = notTaken;
1815                     notTaken = tmp;
1816                 }
1817                 
1818                 branchTest32(condition, valueGPR, TrustedImm32(true), taken);
1819                 jump(notTaken);
1820             } else {
1821                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
1822                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
1823                 
1824                 typeCheck(JSValueRegs(valueGPR), node->child1(), SpecBoolean, m_jit.jump());
1825             }
1826             value.use();
1827         } else {
1828             GPRTemporary result(this);
1829             GPRReg resultGPR = result.gpr();
1830             
1831             if (node->child1()->prediction() & SpecInt32) {
1832                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
1833                 branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
1834             }
1835     
1836             if (node->child1()->prediction() & SpecBoolean) {
1837                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
1838                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
1839             }
1840     
1841             value.use();
1842     
1843             silentSpillAllRegisters(resultGPR);
1844             callOperation(operationConvertJSValueToBoolean, resultGPR, valueGPR);
1845             silentFillAllRegisters(resultGPR);
1846     
1847             branchTest32(MacroAssembler::NonZero, resultGPR, taken);
1848             jump(notTaken);
1849         }
1850         
1851         noResult(node, UseChildrenCalledExplicitly);
1852         return;
1853     }
1854         
1855     default:
1856         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad use kind");
1857     }
1858 }
1859
1860 void SpeculativeJIT::compile(Node* node)
1861 {
1862     NodeType op = node->op();
1863     
1864 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
1865     m_jit.clearRegisterAllocationOffsets();
1866 #endif
1867
1868     switch (op) {
1869     case JSConstant:
1870     case DoubleConstant:
1871     case Int52Constant:
1872     case PhantomDirectArguments:
1873     case PhantomClonedArguments:
1874         initConstantInfo(node);
1875         break;
1876
1877     case Identity: {
1878         speculate(node, node->child1());
1879         switch (node->child1().useKind()) {
1880         case DoubleRepUse:
1881         case DoubleRepRealUse:
1882         case DoubleRepMachineIntUse: {
1883             SpeculateDoubleOperand op(this, node->child1());
1884             FPRTemporary scratch(this, op);
1885             m_jit.moveDouble(op.fpr(), scratch.fpr());
1886             doubleResult(scratch.fpr(), node);
1887             break;
1888         }
1889         case Int52RepUse: {
1890             SpeculateInt52Operand op(this, node->child1());
1891             GPRTemporary result(this, Reuse, op);
1892             m_jit.move(op.gpr(), result.gpr());
1893             int52Result(result.gpr(), node);
1894             break;
1895         }
1896         default: {
1897             JSValueOperand op(this, node->child1());
1898             GPRTemporary result(this, Reuse, op);
1899             m_jit.move(op.gpr(), result.gpr());
1900             jsValueResult(result.gpr(), node);
1901             break;
1902         }
1903         } // switch
1904         break;
1905     }
1906
1907     case GetLocal: {
1908         AbstractValue& value = m_state.variables().operand(node->local());
1909
1910         // If the CFA is tracking this variable and it found that the variable
1911         // cannot have been assigned, then don't attempt to proceed.
1912         if (value.isClear()) {
1913             m_compileOkay = false;
1914             break;
1915         }
1916         
1917         switch (node->variableAccessData()->flushFormat()) {
1918         case FlushedDouble: {
1919             FPRTemporary result(this);
1920             m_jit.loadDouble(JITCompiler::addressFor(node->machineLocal()), result.fpr());
1921             VirtualRegister virtualRegister = node->virtualRegister();
1922             m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
1923             generationInfoFromVirtualRegister(virtualRegister).initDouble(node, node->refCount(), result.fpr());
1924             break;
1925         }
1926         
1927         case FlushedInt32: {
1928             GPRTemporary result(this);
1929             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
1930             
1931             // Like int32Result, but don't useChildren - our children are phi nodes,
1932             // and don't represent values within this dataflow with virtual registers.
1933             VirtualRegister virtualRegister = node->virtualRegister();
1934             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
1935             generationInfoFromVirtualRegister(virtualRegister).initInt32(node, node->refCount(), result.gpr());
1936             break;
1937         }
1938             
1939         case FlushedInt52: {
1940             GPRTemporary result(this);
1941             m_jit.load64(JITCompiler::addressFor(node->machineLocal()), result.gpr());
1942             
1943             VirtualRegister virtualRegister = node->virtualRegister();
1944             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
1945             generationInfoFromVirtualRegister(virtualRegister).initInt52(node, node->refCount(), result.gpr());
1946             break;
1947         }
1948             
1949         default:
1950             GPRTemporary result(this);
1951             m_jit.load64(JITCompiler::addressFor(node->machineLocal()), result.gpr());
1952             
1953             // Like jsValueResult, but don't useChildren - our children are phi nodes,
1954             // and don't represent values within this dataflow with virtual registers.
1955             VirtualRegister virtualRegister = node->virtualRegister();
1956             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
1957             
1958             DataFormat format;
1959             if (isCellSpeculation(value.m_type))
1960                 format = DataFormatJSCell;
1961             else if (isBooleanSpeculation(value.m_type))
1962                 format = DataFormatJSBoolean;
1963             else
1964                 format = DataFormatJS;
1965             
1966             generationInfoFromVirtualRegister(virtualRegister).initJSValue(node, node->refCount(), result.gpr(), format);
1967             break;
1968         }
1969         break;
1970     }
1971
1972     case GetLocalUnlinked: {
1973         GPRTemporary result(this);
1974         
1975         m_jit.load64(JITCompiler::addressFor(node->unlinkedMachineLocal()), result.gpr());
1976         
1977         jsValueResult(result.gpr(), node);
1978         break;
1979     }
1980         
1981     case MovHint: {
1982         compileMovHint(m_currentNode);
1983         noResult(node);
1984         break;
1985     }
1986         
1987     case ZombieHint: {
1988         recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
1989         noResult(node);
1990         break;
1991     }
1992         
1993     case ExitOK: {
1994         noResult(node);
1995         break;
1996     }
1997         
1998     case SetLocal: {
1999         switch (node->variableAccessData()->flushFormat()) {
2000         case FlushedDouble: {
2001             SpeculateDoubleOperand value(this, node->child1());
2002             m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->machineLocal()));
2003             noResult(node);
2004             // Indicate that it's no longer necessary to retrieve the value of
2005             // this bytecode variable from registers or other locations in the stack,
2006             // but that it is stored as a double.
2007             recordSetLocal(DataFormatDouble);
2008             break;
2009         }
2010             
2011         case FlushedInt32: {
2012             SpeculateInt32Operand value(this, node->child1());
2013             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->machineLocal()));
2014             noResult(node);
2015             recordSetLocal(DataFormatInt32);
2016             break;
2017         }
2018             
2019         case FlushedInt52: {
2020             SpeculateInt52Operand value(this, node->child1());
2021             m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
2022             noResult(node);
2023             recordSetLocal(DataFormatInt52);
2024             break;
2025         }
2026             
2027         case FlushedCell: {
2028             SpeculateCellOperand cell(this, node->child1());
2029             GPRReg cellGPR = cell.gpr();
2030             m_jit.store64(cellGPR, JITCompiler::addressFor(node->machineLocal()));
2031             noResult(node);
2032             recordSetLocal(DataFormatCell);
2033             break;
2034         }
2035             
2036         case FlushedBoolean: {
2037             SpeculateBooleanOperand boolean(this, node->child1());
2038             m_jit.store64(boolean.gpr(), JITCompiler::addressFor(node->machineLocal()));
2039             noResult(node);
2040             recordSetLocal(DataFormatBoolean);
2041             break;
2042         }
2043             
2044         case FlushedJSValue: {
2045             JSValueOperand value(this, node->child1());
2046             m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
2047             noResult(node);
2048             recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
2049             break;
2050         }
2051             
2052         default:
2053             DFG_CRASH(m_jit.graph(), node, "Bad flush format");
2054             break;
2055         }
2056
2057         break;
2058     }
2059
2060     case SetArgument:
2061         // This is a no-op; it just marks the fact that the argument is being used.
2062         // But it may be profitable to use this as a hook to run speculation checks
2063         // on arguments, thereby allowing us to trivially eliminate such checks if
2064         // the argument is not used.
2065         recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
2066         break;
2067
2068     case BitAnd:
2069     case BitOr:
2070     case BitXor:
2071         if (node->child1()->isInt32Constant()) {
2072             SpeculateInt32Operand op2(this, node->child2());
2073             GPRTemporary result(this, Reuse, op2);
2074
2075             bitOp(op, node->child1()->asInt32(), op2.gpr(), result.gpr());
2076
2077             int32Result(result.gpr(), node);
2078         } else if (node->child2()->isInt32Constant()) {
2079             SpeculateInt32Operand op1(this, node->child1());
2080             GPRTemporary result(this, Reuse, op1);
2081
2082             bitOp(op, node->child2()->asInt32(), op1.gpr(), result.gpr());
2083
2084             int32Result(result.gpr(), node);
2085         } else {
2086             SpeculateInt32Operand op1(this, node->child1());
2087             SpeculateInt32Operand op2(this, node->child2());
2088             GPRTemporary result(this, Reuse, op1, op2);
2089
2090             GPRReg reg1 = op1.gpr();
2091             GPRReg reg2 = op2.gpr();
2092             bitOp(op, reg1, reg2, result.gpr());
2093
2094             int32Result(result.gpr(), node);
2095         }
2096         break;
2097
2098     case BitRShift:
2099     case BitLShift:
2100     case BitURShift:
2101         if (node->child2()->isInt32Constant()) {
2102             SpeculateInt32Operand op1(this, node->child1());
2103             GPRTemporary result(this, Reuse, op1);
2104
2105             shiftOp(op, op1.gpr(), node->child2()->asInt32() & 0x1f, result.gpr());
2106
2107             int32Result(result.gpr(), node);
2108         } else {
2109             // Do not allow shift amount to be used as the result, MacroAssembler does not permit this.
2110             SpeculateInt32Operand op1(this, node->child1());
2111             SpeculateInt32Operand op2(this, node->child2());
2112             GPRTemporary result(this, Reuse, op1);
2113
2114             GPRReg reg1 = op1.gpr();
2115             GPRReg reg2 = op2.gpr();
2116             shiftOp(op, reg1, reg2, result.gpr());
2117
2118             int32Result(result.gpr(), node);
2119         }
2120         break;
2121
2122     case UInt32ToNumber: {
2123         compileUInt32ToNumber(node);
2124         break;
2125     }
2126
2127     case DoubleAsInt32: {
2128         compileDoubleAsInt32(node);
2129         break;
2130     }
2131
2132     case ValueToInt32: {
2133         compileValueToInt32(node);
2134         break;
2135     }
2136         
2137     case DoubleRep: {
2138         compileDoubleRep(node);
2139         break;
2140     }
2141         
2142     case ValueRep: {
2143         compileValueRep(node);
2144         break;
2145     }
2146         
2147     case Int52Rep: {
2148         switch (node->child1().useKind()) {
2149         case Int32Use: {
2150             SpeculateInt32Operand operand(this, node->child1());
2151             GPRTemporary result(this, Reuse, operand);
2152             
2153             m_jit.signExtend32ToPtr(operand.gpr(), result.gpr());
2154             
2155             strictInt52Result(result.gpr(), node);
2156             break;
2157         }
2158             
2159         case MachineIntUse: {
2160             GPRTemporary result(this);
2161             GPRReg resultGPR = result.gpr();
2162             
2163             convertMachineInt(node->child1(), resultGPR);
2164             
2165             strictInt52Result(resultGPR, node);
2166             break;
2167         }
2168             
2169         case DoubleRepMachineIntUse: {
2170             SpeculateDoubleOperand value(this, node->child1());
2171             FPRReg valueFPR = value.fpr();
2172             
2173             GPRFlushedCallResult result(this);
2174             GPRReg resultGPR = result.gpr();
2175             
2176             flushRegisters();
2177             
2178             callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
2179             
2180             DFG_TYPE_CHECK(
2181                 JSValueRegs(), node->child1(), SpecInt52AsDouble,
2182                 m_jit.branch64(
2183                     JITCompiler::Equal, resultGPR,
2184                     JITCompiler::TrustedImm64(JSValue::notInt52)));
2185             
2186             strictInt52Result(resultGPR, node);
2187             break;
2188         }
2189             
2190         default:
2191             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
2192         }
2193         break;
2194     }
2195         
2196     case ValueAdd: {
2197         JSValueOperand op1(this, node->child1());
2198         JSValueOperand op2(this, node->child2());
2199         
2200         GPRReg op1GPR = op1.gpr();
2201         GPRReg op2GPR = op2.gpr();
2202         
2203         flushRegisters();
2204         
2205         GPRFlushedCallResult result(this);
2206         if (isKnownNotNumber(node->child1().node()) || isKnownNotNumber(node->child2().node()))
2207             callOperation(operationValueAddNotNumber, result.gpr(), op1GPR, op2GPR);
2208         else
2209             callOperation(operationValueAdd, result.gpr(), op1GPR, op2GPR);
2210         m_jit.exceptionCheck();
2211         
2212         jsValueResult(result.gpr(), node);
2213         break;
2214     }
2215         
2216     case StrCat: {
2217         JSValueOperand op1(this, node->child1(), ManualOperandSpeculation);
2218         JSValueOperand op2(this, node->child2(), ManualOperandSpeculation);
2219         JSValueOperand op3(this, node->child3(), ManualOperandSpeculation);
2220         
2221         GPRReg op1GPR = op1.gpr();
2222         GPRReg op2GPR = op2.gpr();
2223         GPRReg op3GPR;
2224         if (node->child3())
2225             op3GPR = op3.gpr();
2226         else
2227             op3GPR = InvalidGPRReg;
2228         
2229         flushRegisters();
2230
2231         GPRFlushedCallResult result(this);
2232         if (node->child3())
2233             callOperation(operationStrCat3, result.gpr(), op1GPR, op2GPR, op3GPR);
2234         else
2235             callOperation(operationStrCat2, result.gpr(), op1GPR, op2GPR);
2236         m_jit.exceptionCheck();
2237         
2238         cellResult(result.gpr(), node);
2239         break;
2240     }
2241
2242     case ArithAdd:
2243         compileAdd(node);
2244         break;
2245
2246     case ArithClz32:
2247         compileArithClz32(node);
2248         break;
2249         
2250     case MakeRope:
2251         compileMakeRope(node);
2252         break;
2253
2254     case ArithSub:
2255         compileArithSub(node);
2256         break;
2257
2258     case ArithNegate:
2259         compileArithNegate(node);
2260         break;
2261
2262     case ArithMul:
2263         compileArithMul(node);
2264         break;
2265
2266     case ArithDiv: {
2267         compileArithDiv(node);
2268         break;
2269     }
2270
2271     case ArithMod: {
2272         compileArithMod(node);
2273         break;
2274     }
2275
2276     case ArithAbs: {
2277         switch (node->child1().useKind()) {
2278         case Int32Use: {
2279             SpeculateStrictInt32Operand op1(this, node->child1());
2280             GPRTemporary result(this);
2281             GPRTemporary scratch(this);
2282             
2283             m_jit.move(op1.gpr(), result.gpr());
2284             m_jit.rshift32(result.gpr(), MacroAssembler::TrustedImm32(31), scratch.gpr());
2285             m_jit.add32(scratch.gpr(), result.gpr());
2286             m_jit.xor32(scratch.gpr(), result.gpr());
2287             speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Equal, result.gpr(), MacroAssembler::TrustedImm32(1 << 31)));
2288             int32Result(result.gpr(), node);
2289             break;
2290         }
2291         
2292         case DoubleRepUse: {
2293             SpeculateDoubleOperand op1(this, node->child1());
2294             FPRTemporary result(this);
2295             
2296             m_jit.absDouble(op1.fpr(), result.fpr());
2297             doubleResult(result.fpr(), node);
2298             break;
2299         }
2300             
2301         default:
2302             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
2303             break;
2304         }
2305         break;
2306     }
2307         
2308     case ArithMin:
2309     case ArithMax: {
2310         switch (node->binaryUseKind()) {
2311         case Int32Use: {
2312             SpeculateStrictInt32Operand op1(this, node->child1());
2313             SpeculateStrictInt32Operand op2(this, node->child2());
2314             GPRTemporary result(this, Reuse, op1);
2315             
2316             MacroAssembler::Jump op1Less = m_jit.branch32(op == ArithMin ? MacroAssembler::LessThan : MacroAssembler::GreaterThan, op1.gpr(), op2.gpr());
2317             m_jit.move(op2.gpr(), result.gpr());
2318             if (op1.gpr() != result.gpr()) {
2319                 MacroAssembler::Jump done = m_jit.jump();
2320                 op1Less.link(&m_jit);
2321                 m_jit.move(op1.gpr(), result.gpr());
2322                 done.link(&m_jit);
2323             } else
2324                 op1Less.link(&m_jit);
2325             
2326             int32Result(result.gpr(), node);
2327             break;
2328         }
2329         
2330         case DoubleRepUse: {
2331             SpeculateDoubleOperand op1(this, node->child1());
2332             SpeculateDoubleOperand op2(this, node->child2());
2333             FPRTemporary result(this, op1);
2334             
2335             FPRReg op1FPR = op1.fpr();
2336             FPRReg op2FPR = op2.fpr();
2337             FPRReg resultFPR = result.fpr();
2338         
2339             MacroAssembler::JumpList done;
2340         
2341             MacroAssembler::Jump op1Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleLessThan : MacroAssembler::DoubleGreaterThan, op1FPR, op2FPR);
2342         
2343             // op2 is eather the lesser one or one of then is NaN
2344             MacroAssembler::Jump op2Less = m_jit.branchDouble(op == ArithMin ? MacroAssembler::DoubleGreaterThanOrEqual : MacroAssembler::DoubleLessThanOrEqual, op1FPR, op2FPR);
2345         
2346             // Unordered case. We don't know which of op1, op2 is NaN. Manufacture NaN by adding 
2347             // op1 + op2 and putting it into result.
2348             m_jit.addDouble(op1FPR, op2FPR, resultFPR);
2349             done.append(m_jit.jump());
2350         
2351             op2Less.link(&m_jit);
2352             m_jit.moveDouble(op2FPR, resultFPR);
2353         
2354             if (op1FPR != resultFPR) {
2355                 done.append(m_jit.jump());
2356             
2357                 op1Less.link(&m_jit);
2358                 m_jit.moveDouble(op1FPR, resultFPR);
2359             } else
2360                 op1Less.link(&m_jit);
2361         
2362             done.link(&m_jit);
2363         
2364             doubleResult(resultFPR, node);
2365             break;
2366         }
2367             
2368         default:
2369             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
2370             break;
2371         }
2372         break;
2373     }
2374
2375     case ArithPow:
2376         compileArithPow(node);
2377         break;
2378
2379     case ArithSqrt:
2380         compileArithSqrt(node);
2381         break;
2382
2383     case ArithFRound: {
2384         SpeculateDoubleOperand op1(this, node->child1());
2385         FPRTemporary result(this, op1);
2386         
2387         m_jit.convertDoubleToFloat(op1.fpr(), result.fpr());
2388         m_jit.convertFloatToDouble(result.fpr(), result.fpr());
2389         
2390         doubleResult(result.fpr(), node);
2391         break;
2392     }
2393
2394     case ArithRound:
2395         compileArithRound(node);
2396         break;
2397
2398     case ArithSin: {
2399         SpeculateDoubleOperand op1(this, node->child1());
2400         FPRReg op1FPR = op1.fpr();
2401
2402         flushRegisters();
2403         
2404         FPRResult result(this);
2405         callOperation(sin, result.fpr(), op1FPR);
2406         doubleResult(result.fpr(), node);
2407         break;
2408     }
2409
2410     case ArithCos: {
2411         SpeculateDoubleOperand op1(this, node->child1());
2412         FPRReg op1FPR = op1.fpr();
2413
2414         flushRegisters();
2415         
2416         FPRResult result(this);
2417         callOperation(cos, result.fpr(), op1FPR);
2418         doubleResult(result.fpr(), node);
2419         break;
2420     }
2421
2422     case ArithLog:
2423         compileArithLog(node);
2424         break;
2425
2426     case LogicalNot:
2427         compileLogicalNot(node);
2428         break;
2429
2430     case CompareLess:
2431         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
2432             return;
2433         break;
2434
2435     case CompareLessEq:
2436         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
2437             return;
2438         break;
2439
2440     case CompareGreater:
2441         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
2442             return;
2443         break;
2444
2445     case CompareGreaterEq:
2446         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
2447             return;
2448         break;
2449
2450     case CompareEq:
2451         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
2452             return;
2453         break;
2454
2455     case CompareStrictEq:
2456         if (compileStrictEq(node))
2457             return;
2458         break;
2459
2460     case StringCharCodeAt: {
2461         compileGetCharCodeAt(node);
2462         break;
2463     }
2464
2465     case StringCharAt: {
2466         // Relies on StringCharAt node having same basic layout as GetByVal
2467         compileGetByValOnString(node);
2468         break;
2469     }
2470
2471     case StringFromCharCode: {
2472         compileFromCharCode(node);
2473         break;
2474     }
2475         
2476     case CheckArray: {
2477         checkArray(node);
2478         break;
2479     }
2480         
2481     case Arrayify:
2482     case ArrayifyToStructure: {
2483         arrayify(node);
2484         break;
2485     }
2486
2487     case GetByVal: {
2488         switch (node->arrayMode().type()) {
2489         case Array::SelectUsingPredictions:
2490         case Array::ForceExit:
2491             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
2492             break;
2493         case Array::Undecided: {
2494             SpeculateStrictInt32Operand index(this, node->child2());
2495             GPRTemporary result(this, Reuse, index);
2496             GPRReg indexGPR = index.gpr();
2497             GPRReg resultGPR = result.gpr();
2498
2499             use(node->child1());
2500             index.use();
2501
2502             speculationCheck(OutOfBounds, JSValueRegs(), node,
2503                 m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
2504
2505             m_jit.move(MacroAssembler::TrustedImm64(ValueUndefined), resultGPR);
2506             jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
2507             break;
2508         }
2509         case Array::Generic: {
2510             JSValueOperand base(this, node->child1());
2511             JSValueOperand property(this, node->child2());
2512             GPRReg baseGPR = base.gpr();
2513             GPRReg propertyGPR = property.gpr();
2514             
2515             flushRegisters();
2516             GPRFlushedCallResult result(this);
2517             callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR);
2518             m_jit.exceptionCheck();
2519             
2520             jsValueResult(result.gpr(), node);
2521             break;
2522         }
2523         case Array::Int32:
2524         case Array::Contiguous: {
2525             if (node->arrayMode().isInBounds()) {
2526                 SpeculateStrictInt32Operand property(this, node->child2());
2527                 StorageOperand storage(this, node->child3());
2528                 
2529                 GPRReg propertyReg = property.gpr();
2530                 GPRReg storageReg = storage.gpr();
2531                 
2532                 if (!m_compileOkay)
2533                     return;
2534                 
2535                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2536                 
2537                 GPRTemporary result(this);
2538                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.gpr());
2539                 if (node->arrayMode().isSaneChain()) {
2540                     ASSERT(node->arrayMode().type() == Array::Contiguous);
2541                     JITCompiler::Jump notHole = m_jit.branchTest64(
2542                         MacroAssembler::NonZero, result.gpr());
2543                     m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), result.gpr());
2544                     notHole.link(&m_jit);
2545                 } else {
2546                     speculationCheck(
2547                         LoadFromHole, JSValueRegs(), 0,
2548                         m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
2549                 }
2550                 jsValueResult(result.gpr(), node, node->arrayMode().type() == Array::Int32 ? DataFormatJSInt32 : DataFormatJS);
2551                 break;
2552             }
2553             
2554             SpeculateCellOperand base(this, node->child1());
2555             SpeculateStrictInt32Operand property(this, node->child2());
2556             StorageOperand storage(this, node->child3());
2557             
2558             GPRReg baseReg = base.gpr();
2559             GPRReg propertyReg = property.gpr();
2560             GPRReg storageReg = storage.gpr();
2561             
2562             if (!m_compileOkay)
2563                 return;
2564             
2565             GPRTemporary result(this);
2566             GPRReg resultReg = result.gpr();
2567             
2568             MacroAssembler::JumpList slowCases;
2569             
2570             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2571             
2572             m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2573             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
2574             
2575             addSlowPathGenerator(
2576                 slowPathCall(
2577                     slowCases, this, operationGetByValArrayInt,
2578                     result.gpr(), baseReg, propertyReg));
2579             
2580             jsValueResult(resultReg, node);
2581             break;
2582         }
2583
2584         case Array::Double: {
2585             if (node->arrayMode().isInBounds()) {
2586                 SpeculateStrictInt32Operand property(this, node->child2());
2587                 StorageOperand storage(this, node->child3());
2588             
2589                 GPRReg propertyReg = property.gpr();
2590                 GPRReg storageReg = storage.gpr();
2591             
2592                 if (!m_compileOkay)
2593                     return;
2594             
2595                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2596             
2597                 FPRTemporary result(this);
2598                 m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.fpr());
2599                 if (!node->arrayMode().isSaneChain())
2600                     speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, result.fpr(), result.fpr()));
2601                 doubleResult(result.fpr(), node);
2602                 break;
2603             }
2604
2605             SpeculateCellOperand base(this, node->child1());
2606             SpeculateStrictInt32Operand property(this, node->child2());
2607             StorageOperand storage(this, node->child3());
2608             
2609             GPRReg baseReg = base.gpr();
2610             GPRReg propertyReg = property.gpr();
2611             GPRReg storageReg = storage.gpr();
2612             
2613             if (!m_compileOkay)
2614                 return;
2615             
2616             GPRTemporary result(this);
2617             FPRTemporary temp(this);
2618             GPRReg resultReg = result.gpr();
2619             FPRReg tempReg = temp.fpr();
2620             
2621             MacroAssembler::JumpList slowCases;
2622             
2623             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2624             
2625             m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), tempReg);
2626             slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempReg, tempReg));
2627             boxDouble(tempReg, resultReg);
2628             
2629             addSlowPathGenerator(
2630                 slowPathCall(
2631                     slowCases, this, operationGetByValArrayInt,
2632                     result.gpr(), baseReg, propertyReg));
2633             
2634             jsValueResult(resultReg, node);
2635             break;
2636         }
2637
2638         case Array::ArrayStorage:
2639         case Array::SlowPutArrayStorage: {
2640             if (node->arrayMode().isInBounds()) {
2641                 SpeculateStrictInt32Operand property(this, node->child2());
2642                 StorageOperand storage(this, node->child3());
2643             
2644                 GPRReg propertyReg = property.gpr();
2645                 GPRReg storageReg = storage.gpr();
2646             
2647                 if (!m_compileOkay)
2648                     return;
2649             
2650                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2651             
2652                 GPRTemporary result(this);
2653                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), result.gpr());
2654                 speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
2655             
2656                 jsValueResult(result.gpr(), node);
2657                 break;
2658             }
2659
2660             SpeculateCellOperand base(this, node->child1());
2661             SpeculateStrictInt32Operand property(this, node->child2());
2662             StorageOperand storage(this, node->child3());
2663             
2664             GPRReg baseReg = base.gpr();
2665             GPRReg propertyReg = property.gpr();
2666             GPRReg storageReg = storage.gpr();
2667             
2668             if (!m_compileOkay)
2669                 return;
2670             
2671             GPRTemporary result(this);
2672             GPRReg resultReg = result.gpr();
2673             
2674             MacroAssembler::JumpList slowCases;
2675             
2676             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2677     
2678             m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), resultReg);
2679             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
2680     
2681             addSlowPathGenerator(
2682                 slowPathCall(
2683                     slowCases, this, operationGetByValArrayInt,
2684                     result.gpr(), baseReg, propertyReg));
2685             
2686             jsValueResult(resultReg, node);
2687             break;
2688         }
2689         case Array::String:
2690             compileGetByValOnString(node);
2691             break;
2692         case Array::DirectArguments:
2693             compileGetByValOnDirectArguments(node);
2694             break;
2695         case Array::ScopedArguments:
2696             compileGetByValOnScopedArguments(node);
2697             break;
2698         default: {
2699             TypedArrayType type = node->arrayMode().typedArrayType();
2700             if (isInt(type))
2701                 compileGetByValOnIntTypedArray(node, type);
2702             else
2703                 compileGetByValOnFloatTypedArray(node, type);
2704         } }
2705         break;
2706     }
2707
2708     case PutByValDirect:
2709     case PutByVal:
2710     case PutByValAlias: {
2711         Edge child1 = m_jit.graph().varArgChild(node, 0);
2712         Edge child2 = m_jit.graph().varArgChild(node, 1);
2713         Edge child3 = m_jit.graph().varArgChild(node, 2);
2714         Edge child4 = m_jit.graph().varArgChild(node, 3);
2715         
2716         ArrayMode arrayMode = node->arrayMode().modeForPut();
2717         bool alreadyHandled = false;
2718         
2719         switch (arrayMode.type()) {
2720         case Array::SelectUsingPredictions:
2721         case Array::ForceExit:
2722             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
2723             break;
2724         case Array::Generic: {
2725             DFG_ASSERT(m_jit.graph(), node, node->op() == PutByVal || node->op() == PutByValDirect);
2726             
2727             JSValueOperand arg1(this, child1);
2728             JSValueOperand arg2(this, child2);
2729             JSValueOperand arg3(this, child3);
2730             GPRReg arg1GPR = arg1.gpr();
2731             GPRReg arg2GPR = arg2.gpr();
2732             GPRReg arg3GPR = arg3.gpr();
2733             flushRegisters();
2734             if (node->op() == PutByValDirect)
2735                 callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValDirectStrict : operationPutByValDirectNonStrict, arg1GPR, arg2GPR, arg3GPR);
2736             else
2737                 callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
2738             m_jit.exceptionCheck();
2739             
2740             noResult(node);
2741             alreadyHandled = true;
2742             break;
2743         }
2744         default:
2745             break;
2746         }
2747         
2748         if (alreadyHandled)
2749             break;
2750         
2751         // FIXME: the base may not be necessary for some array access modes. But we have to
2752         // keep it alive to this point, so it's likely to be in a register anyway. Likely
2753         // no harm in locking it here.
2754         SpeculateCellOperand base(this, child1);
2755         SpeculateStrictInt32Operand property(this, child2);
2756         
2757         GPRReg baseReg = base.gpr();
2758         GPRReg propertyReg = property.gpr();
2759
2760         switch (arrayMode.type()) {
2761         case Array::Int32:
2762         case Array::Contiguous: {
2763             JSValueOperand value(this, child3, ManualOperandSpeculation);
2764
2765             GPRReg valueReg = value.gpr();
2766         
2767             if (!m_compileOkay)
2768                 return;
2769             
2770             if (arrayMode.type() == Array::Int32) {
2771                 DFG_TYPE_CHECK(
2772                     JSValueRegs(valueReg), child3, SpecInt32,
2773                     m_jit.branch64(
2774                         MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
2775             }
2776
2777             StorageOperand storage(this, child4);
2778             GPRReg storageReg = storage.gpr();
2779
2780             if (node->op() == PutByValAlias) {
2781                 // Store the value to the array.
2782                 GPRReg propertyReg = property.gpr();
2783                 GPRReg valueReg = value.gpr();
2784                 m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
2785                 
2786                 noResult(node);
2787                 break;
2788             }
2789             
2790             GPRTemporary temporary;
2791             GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
2792
2793             MacroAssembler::Jump slowCase;
2794             
2795             if (arrayMode.isInBounds()) {
2796                 speculationCheck(
2797                     OutOfBounds, JSValueRegs(), 0,
2798                     m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2799             } else {
2800                 MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2801                 
2802                 slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
2803                 
2804                 if (!arrayMode.isOutOfBounds())
2805                     speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
2806                 
2807                 m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
2808                 m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2809                 
2810                 inBounds.link(&m_jit);
2811             }
2812             
2813             m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
2814
2815             base.use();
2816             property.use();
2817             value.use();
2818             storage.use();
2819             
2820             if (arrayMode.isOutOfBounds()) {
2821                 if (node->op() == PutByValDirect) {
2822                     addSlowPathGenerator(slowPathCall(
2823                         slowCase, this,
2824                         m_jit.codeBlock()->isStrictMode() ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValDirectBeyondArrayBoundsNonStrict,
2825                         NoResult, baseReg, propertyReg, valueReg));
2826                 } else {
2827                     addSlowPathGenerator(slowPathCall(
2828                         slowCase, this,
2829                         m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
2830                         NoResult, baseReg, propertyReg, valueReg));
2831                 }
2832             }
2833
2834             noResult(node, UseChildrenCalledExplicitly);
2835             break;
2836         }
2837             
2838         case Array::Double: {
2839             compileDoublePutByVal(node, base, property);
2840             break;
2841         }
2842             
2843         case Array::ArrayStorage:
2844         case Array::SlowPutArrayStorage: {
2845             JSValueOperand value(this, child3);
2846
2847             GPRReg valueReg = value.gpr();
2848         
2849             if (!m_compileOkay)
2850                 return;
2851
2852             StorageOperand storage(this, child4);
2853             GPRReg storageReg = storage.gpr();
2854
2855             if (node->op() == PutByValAlias) {
2856                 // Store the value to the array.
2857                 GPRReg propertyReg = property.gpr();
2858                 GPRReg valueReg = value.gpr();
2859                 m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2860                 
2861                 noResult(node);
2862                 break;
2863             }
2864             
2865             GPRTemporary temporary;
2866             GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
2867
2868             MacroAssembler::JumpList slowCases;
2869
2870             MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
2871             if (!arrayMode.isOutOfBounds())
2872                 speculationCheck(OutOfBounds, JSValueRegs(), 0, beyondArrayBounds);
2873             else
2874                 slowCases.append(beyondArrayBounds);
2875
2876             // Check if we're writing to a hole; if so increment m_numValuesInVector.
2877             if (arrayMode.isInBounds()) {
2878                 speculationCheck(
2879                     StoreToHole, JSValueRegs(), 0,
2880                     m_jit.branchTest64(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]))));
2881             } else {
2882                 MacroAssembler::Jump notHoleValue = m_jit.branchTest64(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2883                 if (arrayMode.isSlowPut()) {
2884                     // This is sort of strange. If we wanted to optimize this code path, we would invert
2885                     // the above branch. But it's simply not worth it since this only happens if we're
2886                     // already having a bad time.
2887                     slowCases.append(m_jit.jump());
2888                 } else {
2889                     m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
2890                 
2891                     // If we're writing to a hole we might be growing the array; 
2892                     MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2893                     m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
2894                     m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2895                 
2896                     lengthDoesNotNeedUpdate.link(&m_jit);
2897                 }
2898                 notHoleValue.link(&m_jit);
2899             }
2900     
2901             // Store the value to the array.
2902             m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
2903
2904             base.use();
2905             property.use();
2906             value.use();
2907             storage.use();
2908             
2909             if (!slowCases.empty()) {
2910                 if (node->op() == PutByValDirect) {
2911                     addSlowPathGenerator(slowPathCall(
2912                         slowCases, this,
2913                         m_jit.codeBlock()->isStrictMode() ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValDirectBeyondArrayBoundsNonStrict,
2914                         NoResult, baseReg, propertyReg, valueReg));
2915                 } else {
2916                     addSlowPathGenerator(slowPathCall(
2917                         slowCases, this,
2918                         m_jit.codeBlock()->isStrictMode() ? operationPutByValBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsNonStrict,
2919                         NoResult, baseReg, propertyReg, valueReg));
2920                 }
2921             }
2922
2923             noResult(node, UseChildrenCalledExplicitly);
2924             break;
2925         }
2926             
2927         default: {
2928             TypedArrayType type = arrayMode.typedArrayType();
2929             if (isInt(type))
2930                 compilePutByValForIntTypedArray(base.gpr(), property.gpr(), node, type);
2931             else
2932                 compilePutByValForFloatTypedArray(base.gpr(), property.gpr(), node, type);
2933         } }
2934
2935         break;
2936     }
2937
2938     case RegExpExec: {
2939         if (compileRegExpExec(node))
2940             return;
2941         if (!node->adjustedRefCount()) {
2942             SpeculateCellOperand base(this, node->child1());
2943             SpeculateCellOperand argument(this, node->child2());
2944             GPRReg baseGPR = base.gpr();
2945             GPRReg argumentGPR = argument.gpr();
2946             
2947             flushRegisters();
2948             GPRFlushedCallResult result(this);
2949             callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
2950             m_jit.exceptionCheck();
2951             
2952             // Must use jsValueResult because otherwise we screw up register
2953             // allocation, which thinks that this node has a result.
2954             jsValueResult(result.gpr(), node);
2955             break;
2956         }
2957
2958         SpeculateCellOperand base(this, node->child1());
2959         SpeculateCellOperand argument(this, node->child2());
2960         GPRReg baseGPR = base.gpr();
2961         GPRReg argumentGPR = argument.gpr();
2962         
2963         flushRegisters();
2964         GPRFlushedCallResult result(this);
2965         callOperation(operationRegExpExec, result.gpr(), baseGPR, argumentGPR);
2966         m_jit.exceptionCheck();
2967         
2968         jsValueResult(result.gpr(), node);
2969         break;
2970     }
2971
2972     case RegExpTest: {
2973         SpeculateCellOperand base(this, node->child1());
2974         SpeculateCellOperand argument(this, node->child2());
2975         GPRReg baseGPR = base.gpr();
2976         GPRReg argumentGPR = argument.gpr();
2977         
2978         flushRegisters();
2979         GPRFlushedCallResult result(this);
2980         callOperation(operationRegExpTest, result.gpr(), baseGPR, argumentGPR);
2981         m_jit.exceptionCheck();
2982         
2983         // If we add a DataFormatBool, we should use it here.
2984         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
2985         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
2986         break;
2987     }
2988         
2989     case ArrayPush: {
2990         ASSERT(node->arrayMode().isJSArray());
2991         
2992         SpeculateCellOperand base(this, node->child1());
2993         GPRTemporary storageLength(this);
2994         
2995         GPRReg baseGPR = base.gpr();
2996         GPRReg storageLengthGPR = storageLength.gpr();
2997         
2998         StorageOperand storage(this, node->child3());
2999         GPRReg storageGPR = storage.gpr();
3000
3001         switch (node->arrayMode().type()) {
3002         case Array::Int32:
3003         case Array::Contiguous: {
3004             JSValueOperand value(this, node->child2(), ManualOperandSpeculation);
3005             GPRReg valueGPR = value.gpr();
3006
3007             if (node->arrayMode().type() == Array::Int32) {
3008                 DFG_TYPE_CHECK(
3009                     JSValueRegs(valueGPR), node->child2(), SpecInt32,
3010                     m_jit.branch64(
3011                         MacroAssembler::Below, valueGPR, GPRInfo::tagTypeNumberRegister));
3012             }
3013
3014             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3015             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
3016             m_jit.store64(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3017             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3018             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3019             m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
3020             
3021             addSlowPathGenerator(
3022                 slowPathCall(
3023                     slowPath, this, operationArrayPush, storageLengthGPR,
3024                     valueGPR, baseGPR));
3025         
3026             jsValueResult(storageLengthGPR, node);
3027             break;
3028         }
3029             
3030         case Array::Double: {
3031             SpeculateDoubleOperand value(this, node->child2());
3032             FPRReg valueFPR = value.fpr();
3033
3034             DFG_TYPE_CHECK(
3035                 JSValueRegs(), node->child2(), SpecDoubleReal,
3036                 m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, valueFPR, valueFPR));
3037             
3038             m_jit.load32(MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3039             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
3040             m_jit.storeDouble(valueFPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3041             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3042             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3043             m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
3044             
3045             addSlowPathGenerator(
3046                 slowPathCall(
3047                     slowPath, this, operationArrayPushDouble, storageLengthGPR,
3048                     valueFPR, baseGPR));
3049         
3050             jsValueResult(storageLengthGPR, node);
3051             break;
3052         }
3053             
3054         case Array::ArrayStorage: {
3055             JSValueOperand value(this, node->child2());
3056             GPRReg valueGPR = value.gpr();
3057
3058             m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
3059         
3060             // Refuse to handle bizarre lengths.
3061             speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::Above, storageLengthGPR, TrustedImm32(0x7ffffffe)));
3062         
3063             MacroAssembler::Jump slowPath = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
3064         
3065             m_jit.store64(valueGPR, MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
3066         
3067             m_jit.add32(TrustedImm32(1), storageLengthGPR);
3068             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
3069             m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
3070             m_jit.or64(GPRInfo::tagTypeNumberRegister, storageLengthGPR);
3071         
3072             addSlowPathGenerator(
3073                 slowPathCall(
3074                     slowPath, this, operationArrayPush, NoResult, storageLengthGPR,
3075                     valueGPR, baseGPR));
3076         
3077             jsValueResult(storageLengthGPR, node);
3078             break;
3079         }
3080             
3081         default:
3082             CRASH();
3083             break;
3084         }
3085         break;
3086     }
3087         
3088     case ArrayPop: {
3089         ASSERT(node->arrayMode().isJSArray());
3090
3091         SpeculateCellOperand base(this, node->child1());
3092         StorageOperand storage(this, node->child2());
3093         GPRTemporary value(this);
3094         GPRTemporary storageLength(this);
3095         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().
3096         
3097         GPRReg baseGPR = base.gpr();
3098         GPRReg storageGPR = storage.gpr();
3099         GPRReg valueGPR = value.gpr();
3100         GPRReg storageLengthGPR = storageLength.gpr();
3101         FPRReg tempFPR = temp.fpr();
3102         
3103         switch (node->arrayMode().type()) {
3104         case Array::Int32:
3105         case Array::Double:
3106         case Array::Contiguous: {
3107             m_jit.load32(
3108                 MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3109             MacroAssembler::Jump undefinedCase =
3110                 m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
3111             m_jit.sub32(TrustedImm32(1), storageLengthGPR);
3112             m_jit.store32(
3113                 storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3114             MacroAssembler::Jump slowCase;
3115             if (node->arrayMode().type() == Array::Double) {
3116                 m_jit.loadDouble(
3117                     MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight),
3118                     tempFPR);
3119                 // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old
3120                 // length and the new length.
3121                 m_jit.store64(
3122                     MacroAssembler::TrustedImm64(bitwise_cast<int64_t>(PNaN)), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3123                 slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR);
3124                 boxDouble(tempFPR, valueGPR);
3125             } else {
3126                 m_jit.load64(
3127                     MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight),
3128                     valueGPR);
3129                 // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old
3130                 // length and the new length.
3131                 m_jit.store64(
3132                 MacroAssembler::TrustedImm64((int64_t)0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3133                 slowCase = m_jit.branchTest64(MacroAssembler::Zero, valueGPR);
3134             }
3135
3136             addSlowPathGenerator(
3137                 slowPathMove(
3138                     undefinedCase, this,
3139                     MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), valueGPR));
3140             addSlowPathGenerator(
3141                 slowPathCall(
3142                     slowCase, this, operationArrayPopAndRecoverLength, valueGPR, baseGPR));
3143             
3144             // We can't know for sure that the result is an int because of the slow paths. :-/
3145             jsValueResult(valueGPR, node);
3146             break;
3147         }
3148             
3149         case Array::ArrayStorage: {
3150             m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
3151         
3152             JITCompiler::Jump undefinedCase =
3153                 m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
3154         
3155             m_jit.sub32(TrustedImm32(1), storageLengthGPR);
3156         
3157             JITCompiler::JumpList slowCases;
3158             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())));
3159         
3160             m_jit.load64(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), valueGPR);
3161             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, valueGPR));
3162         
3163             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
3164         
3165             m_jit.store64(MacroAssembler::TrustedImm64((int64_t)0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])));
3166             m_jit.sub32(MacroAssembler::TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
3167         
3168             addSlowPathGenerator(
3169                 slowPathMove(
3170                     undefinedCase, this,
3171                     MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), valueGPR));
3172         
3173             addSlowPathGenerator(
3174                 slowPathCall(
3175                     slowCases, this, operationArrayPop, valueGPR, baseGPR));
3176
3177             jsValueResult(valueGPR, node);
3178             break;
3179         }
3180             
3181         default:
3182             CRASH();
3183             break;
3184         }
3185         break;
3186     }
3187
3188     case DFG::Jump: {
3189         jump(node->targetBlock());
3190         noResult(node);
3191         break;
3192     }
3193
3194     case Branch:
3195         emitBranch(node);
3196         break;
3197         
3198     case Switch:
3199         emitSwitch(node);
3200         break;
3201
3202     case Return: {
3203         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);
3204         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
3205         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
3206
3207         // Return the result in returnValueGPR.
3208         JSValueOperand op1(this, node->child1());
3209         m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
3210
3211         m_jit.emitFunctionEpilogue();
3212         m_jit.ret();
3213         
3214         noResult(node);
3215         break;
3216     }
3217         
3218     case Throw:
3219     case ThrowReferenceError: {
3220         // We expect that throw statements are rare and are intended to exit the code block
3221         // anyway, so we just OSR back to the old JIT for now.
3222         terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
3223         break;
3224     }
3225         
3226     case BooleanToNumber: {
3227         switch (node->child1().useKind()) {
3228         case BooleanUse: {
3229             JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
3230             GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
3231             
3232             m_jit.move(value.gpr(), result.gpr());
3233             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
3234             DFG_TYPE_CHECK(
3235                 JSValueRegs(value.gpr()), node->child1(), SpecBoolean, m_jit.branchTest64(
3236                     JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
3237
3238             int32Result(result.gpr(), node);
3239             break;
3240         }
3241             
3242         case UntypedUse: {
3243             JSValueOperand value(this, node->child1());
3244             GPRTemporary result(this);
3245             
3246             if (!m_interpreter.needsTypeCheck(node->child1(), SpecBoolInt32 | SpecBoolean)) {
3247                 m_jit.move(value.gpr(), result.gpr());
3248                 m_jit.and32(TrustedImm32(1), result.gpr());
3249                 int32Result(result.gpr(), node);
3250                 break;
3251             }
3252             
3253             m_jit.move(value.gpr(), result.gpr());
3254             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
3255             JITCompiler::Jump isBoolean = m_jit.branchTest64(
3256                 JITCompiler::Zero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1)));
3257             m_jit.move(value.gpr(), result.gpr());
3258             JITCompiler::Jump done = m_jit.jump();
3259             isBoolean.link(&m_jit);
3260             m_jit.or64(GPRInfo::tagTypeNumberRegister, result.gpr());
3261             done.link(&m_jit);
3262             
3263             jsValueResult(result.gpr(), node);
3264             break;
3265         }
3266             
3267         default:
3268             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
3269             break;
3270         }
3271         break;
3272     }
3273         
3274     case ToPrimitive: {
3275         DFG_ASSERT(m_jit.graph(), node, node->child1().useKind() == UntypedUse);
3276         JSValueOperand op1(this, node->child1());
3277         GPRTemporary result(this, Reuse, op1);
3278         
3279         GPRReg op1GPR = op1.gpr();
3280         GPRReg resultGPR = result.gpr();
3281         
3282         op1.use();
3283         
3284         MacroAssembler::Jump alreadyPrimitive = m_jit.branchIfNotCell(JSValueRegs(op1GPR));
3285         MacroAssembler::Jump notPrimitive = m_jit.branchIfObject(op1GPR);
3286         
3287         alreadyPrimitive.link(&m_jit);
3288         m_jit.move(op1GPR, resultGPR);
3289         
3290         addSlowPathGenerator(
3291             slowPathCall(notPrimitive, this, operationToPrimitive, resultGPR, op1GPR));
3292         
3293         jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
3294         break;
3295     }
3296         
3297     case ToString:
3298     case CallStringConstructor: {
3299         if (node->child1().useKind() == UntypedUse) {
3300             JSValueOperand op1(this, node->child1());
3301             GPRReg op1GPR = op1.gpr();
3302             
3303             GPRFlushedCallResult result(this);
3304             GPRReg resultGPR = result.gpr();
3305             
3306             flushRegisters();
3307             
3308             JITCompiler::Jump done;
3309             if (node->child1()->prediction() & SpecString) {
3310                 JITCompiler::Jump slowPath1 = m_jit.branchIfNotCell(JSValueRegs(op1GPR));
3311                 JITCompiler::Jump slowPath2 = m_jit.branchIfNotString(op1GPR);
3312                 m_jit.move(op1GPR, resultGPR);
3313                 done = m_jit.jump();
3314                 slowPath1.link(&m_jit);
3315                 slowPath2.link(&m_jit);
3316             }
3317             if (op == ToString)
3318                 callOperation(operationToString, resultGPR, op1GPR);
3319             else {
3320                 ASSERT(op == CallStringConstructor);
3321                 callOperation(operationCallStringConstructor, resultGPR, op1GPR);
3322             }
3323             m_jit.exceptionCheck();
3324             if (done.isSet())
3325                 done.link(&m_jit);
3326             cellResult(resultGPR, node);
3327             break;
3328         }
3329         
3330         compileToStringOrCallStringConstructorOnCell(node);
3331         break;
3332     }
3333         
3334     case NewStringObject: {
3335         compileNewStringObject(node);
3336         break;
3337     }
3338         
3339     case NewArray: {
3340         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
3341         if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(node->indexingType())) {
3342             Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
3343             DFG_ASSERT(m_jit.graph(), node, structure->indexingType() == node->indexingType());
3344             ASSERT(
3345                 hasUndecided(structure->indexingType())
3346                 || hasInt32(structure->indexingType())
3347                 || hasDouble(structure->indexingType())
3348                 || hasContiguous(structure->indexingType()));
3349             
3350             unsigned numElements = node->numChildren();
3351             
3352             GPRTemporary result(this);
3353             GPRTemporary storage(this);
3354             
3355             GPRReg resultGPR = result.gpr();
3356             GPRReg storageGPR = storage.gpr();
3357
3358             emitAllocateJSArray(resultGPR, structure, storageGPR, numElements);
3359             
3360             // At this point, one way or another, resultGPR and storageGPR have pointers to
3361             // the JSArray and the Butterfly, respectively.
3362             
3363             ASSERT(!hasUndecided(structure->indexingType()) || !node->numChildren());
3364             
3365             for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
3366                 Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
3367                 switch (node->indexingType()) {
3368                 case ALL_BLANK_INDEXING_TYPES:
3369                 case ALL_UNDECIDED_INDEXING_TYPES:
3370                     CRASH();
3371                     break;
3372                 case ALL_DOUBLE_INDEXING_TYPES: {
3373                     SpeculateDoubleOperand operand(this, use);
3374                     FPRReg opFPR = operand.fpr();
3375                     DFG_TYPE_CHECK(
3376                         JSValueRegs(), use, SpecDoubleReal,
3377                         m_jit.branchDouble(
3378                             MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
3379                     m_jit.storeDouble(opFPR, MacroAssembler::Address(storageGPR, sizeof(double) * operandIdx));
3380                     break;
3381                 }
3382                 case ALL_INT32_INDEXING_TYPES:
3383                 case ALL_CONTIGUOUS_INDEXING_TYPES: {
3384                     JSValueOperand operand(this, use, ManualOperandSpeculation);
3385                     GPRReg opGPR = operand.gpr();
3386                     if (hasInt32(node->indexingType())) {
3387                         DFG_TYPE_CHECK(
3388                             JSValueRegs(opGPR), use, SpecInt32,
3389                             m_jit.branch64(
3390                                 MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
3391                     }
3392                     m_jit.store64(opGPR, MacroAssembler::Address(storageGPR, sizeof(JSValue) * operandIdx));
3393                     break;
3394                 }
3395                 default:
3396                     CRASH();
3397                     break;
3398                 }
3399             }
3400             
3401             // Yuck, we should *really* have a way of also returning the storageGPR. But
3402             // that's the least of what's wrong with this code. We really shouldn't be
3403             // allocating the array after having computed - and probably spilled to the
3404             // stack - all of the things that will go into the array. The solution to that
3405             // bigger problem will also likely fix the redundancy in reloading the storage
3406             // pointer that we currently have.
3407             
3408             cellResult(resultGPR, node);
3409             break;
3410         }
3411         
3412         if (!node->numChildren()) {
3413             flushRegisters();
3414             GPRFlushedCallResult result(this);
3415             callOperation(operationNewEmptyArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
3416             m_jit.exceptionCheck();
3417             cellResult(result.gpr(), node);
3418             break;
3419         }
3420         
3421         size_t scratchSize = sizeof(EncodedJSValue) * node->numChildren();
3422         ScratchBuffer* scratchBuffer = m_jit.vm()->scratchBufferForSize(scratchSize);
3423         EncodedJSValue* buffer = scratchBuffer ? static_cast<EncodedJSValue*>(scratchBuffer->dataBuffer()) : 0;
3424         
3425         for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) {
3426             // Need to perform the speculations that this node promises to perform. If we're
3427             // emitting code here and the indexing type is not array storage then there is
3428             // probably something hilarious going on and we're already failing at all the
3429             // things, but at least we're going to be sound.
3430             Edge use = m_jit.graph().m_varArgChildren[node->firstChild() + operandIdx];
3431             switch (node->indexingType()) {
3432             case ALL_BLANK_INDEXING_TYPES:
3433             case ALL_UNDECIDED_INDEXING_TYPES:
3434                 CRASH();
3435                 break;
3436             case ALL_DOUBLE_INDEXING_TYPES: {
3437                 SpeculateDoubleOperand operand(this, use);
3438                 GPRTemporary scratch(this);
3439                 FPRReg opFPR = operand.fpr();
3440                 GPRReg scratchGPR = scratch.gpr();
3441                 DFG_TYPE_CHECK(
3442                     JSValueRegs(), use, SpecDoubleReal,
3443                     m_jit.branchDouble(
3444                         MacroAssembler::DoubleNotEqualOrUnordered, opFPR, opFPR));
3445                 m_jit.boxDouble(opFPR, scratchGPR);
3446                 m_jit.store64(scratchGPR, buffer + operandIdx);
3447                 break;
3448             }
3449             case ALL_INT32_INDEXING_TYPES: {
3450                 JSValueOperand operand(this, use, ManualOperandSpeculation);
3451                 GPRReg opGPR = operand.gpr();
3452                 if (hasInt32(node->indexingType())) {
3453                     DFG_TYPE_CHECK(
3454                         JSValueRegs(opGPR), use, SpecInt32,
3455                         m_jit.branch64(
3456                             MacroAssembler::Below, opGPR, GPRInfo::tagTypeNumberRegister));
3457                 }
3458                 m_jit.store64(opGPR, buffer + operandIdx);
3459                 break;
3460             }
3461             case ALL_CONTIGUOUS_INDEXING_TYPES:
3462             case ALL_ARRAY_STORAGE_INDEXING_TYPES: {
3463                 JSValueOperand operand(this, use);
3464                 GPRReg opGPR = operand.gpr();
3465                 m_jit.store64(opGPR, buffer + operandIdx);
3466                 operand.use();
3467                 break;
3468             }
3469             default:
3470                 CRASH();
3471                 break;
3472             }
3473         }
3474         
3475         switch (node->indexingType()) {
3476         case ALL_DOUBLE_INDEXING_TYPES:
3477         case ALL_INT32_INDEXING_TYPES:
3478             useChildren(node);
3479             break;
3480         default:
3481             break;
3482         }
3483         
3484         flushRegisters();
3485
3486         if (scratchSize) {
3487             GPRTemporary scratch(this);
3488
3489             // Tell GC mark phase how much of the scratch buffer is active during call.
3490             m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr());
3491             m_jit.storePtr(TrustedImmPtr(scratchSize), scratch.gpr());
3492         }
3493
3494         GPRFlushedCallResult result(this);
3495         
3496         callOperation(
3497             operationNewArray, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
3498             static_cast<void*>(buffer), node->numChildren());
3499         m_jit.exceptionCheck();
3500
3501         if (scratchSize) {
3502             GPRTemporary scratch(this);
3503
3504             m_jit.move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), scratch.gpr());
3505             m_jit.storePtr(TrustedImmPtr(0), scratch.gpr());
3506         }
3507
3508         cellResult(result.gpr(), node, UseChildrenCalledExplicitly);
3509         break;
3510     }
3511         
3512     case NewArrayWithSize: {
3513         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
3514         if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(node->indexingType())) {
3515             SpeculateStrictInt32Operand size(this, node->child1());
3516             GPRTemporary result(this);
3517             GPRTemporary storage(this);
3518             GPRTemporary scratch(this);
3519             GPRTemporary scratch2(this);
3520             
3521             GPRReg sizeGPR = size.gpr();
3522             GPRReg resultGPR = result.gpr();
3523             GPRReg storageGPR = storage.gpr();
3524             GPRReg scratchGPR = scratch.gpr();
3525             GPRReg scratch2GPR = scratch2.gpr();
3526             
3527             MacroAssembler::JumpList slowCases;
3528             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH)));
3529             
3530             ASSERT((1 << 3) == sizeof(JSValue));
3531             m_jit.move(sizeGPR, scratchGPR);
3532             m_jit.lshift32(TrustedImm32(3), scratchGPR);
3533             m_jit.add32(TrustedImm32(sizeof(IndexingHeader)), scratchGPR, resultGPR);
3534             slowCases.append(
3535                 emitAllocateBasicStorage(resultGPR, storageGPR));
3536             m_jit.subPtr(scratchGPR, storageGPR);
3537             Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType());
3538             emitAllocateJSObject<JSArray>(resultGPR, TrustedImmPtr(structure), storageGPR, scratchGPR, scratch2GPR, slowCases);
3539             
3540             m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3541             m_jit.store32(sizeGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfVectorLength()));
3542             
3543             if (hasDouble(node->indexingType())) {
3544                 m_jit.move(TrustedImm64(bitwise_cast<int64_t>(PNaN)), scratchGPR);
3545                 m_jit.move(sizeGPR, scratch2GPR);
3546                 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, scratch2GPR);
3547                 MacroAssembler::Label loop = m_jit.label();
3548                 m_jit.sub32(TrustedImm32(1), scratch2GPR);
3549                 m_jit.store64(scratchGPR, MacroAssembler::BaseIndex(storageGPR, scratch2GPR, MacroAssembler::TimesEight));
3550                 m_jit.branchTest32(MacroAssembler::NonZero, scratch2GPR).linkTo(loop, &m_jit);
3551                 done.link(&m_jit);
3552             }
3553             
3554             addSlowPathGenerator(std::make_unique<CallArrayAllocatorWithVariableSizeSlowPathGenerator>(
3555                     slowCases, this, operationNewArrayWithSize, resultGPR,
3556                     globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()),
3557                     globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage),
3558                     sizeGPR));
3559             
3560             cellResult(resultGPR, node);
3561             break;
3562         }
3563         
3564         SpeculateStrictInt32Operand size(this, node->child1());
3565         GPRReg sizeGPR = size.gpr();
3566         flushRegisters();
3567         GPRFlushedCallResult result(this);
3568         GPRReg resultGPR = result.gpr();
3569         GPRReg structureGPR = selectScratchGPR(sizeGPR);
3570         MacroAssembler::Jump bigLength = m_jit.branch32(MacroAssembler::AboveOrEqual, sizeGPR, TrustedImm32(MIN_ARRAY_STORAGE_CONSTRUCTION_LENGTH));
3571         m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType())), structureGPR);
3572         MacroAssembler::Jump done = m_jit.jump();
3573         bigLength.link(&m_jit);
3574         m_jit.move(TrustedImmPtr(globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithArrayStorage)), structureGPR);
3575         done.link(&m_jit);
3576         callOperation(operationNewArrayWithSize, resultGPR, structureGPR, sizeGPR);
3577         m_jit.exceptionCheck();
3578         cellResult(resultGPR, node);
3579         break;
3580     }
3581         
3582     case NewArrayBuffer: {
3583         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
3584         IndexingType indexingType = node->indexingType();
3585         if (!globalObject->isHavingABadTime() && !hasAnyArrayStorage(indexingType)) {
3586             unsigned numElements = node->numConstants();
3587             
3588             GPRTemporary result(this);
3589             GPRTemporary storage(this);
3590             
3591             GPRReg resultGPR = result.gpr();
3592             GPRReg storageGPR = storage.gpr();
3593
3594             emitAllocateJSArray(resultGPR, globalObject->arrayStructureForIndexingTypeDuringAllocation(indexingType), storageGPR, numElements);
3595             
3596             DFG_ASSERT(m_jit.graph(), node, indexingType & IsArray);
3597             JSValue* data = m_jit.codeBlock()->constantBuffer(node->startConstant());
3598             if (indexingType == ArrayWithDouble) {
3599                 for (unsigned index = 0; index < node->numConstants(); ++index) {
3600                     double value = data[index].asNumber();
3601                     m_jit.store64(
3602                         Imm64(bitwise_cast<int64_t>(value)),
3603                         MacroAssembler::Address(storageGPR, sizeof(double) * index));
3604                 }
3605             } else {
3606                 for (unsigned index = 0; index < node->numConstants(); ++index) {
3607                     m_jit.store64(
3608                         Imm64(JSValue::encode(data[index])),
3609                         MacroAssembler::Address(storageGPR, sizeof(JSValue) * index));
3610                 }
3611             }
3612             
3613             cellResult(resultGPR, node);
3614             break;
3615         }
3616         
3617         flushRegisters();
3618         GPRFlushedCallResult result(this);
3619         
3620         callOperation(operationNewArrayBuffer, result.gpr(), globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()), node->startConstant(), node->numConstants());
3621         m_jit.exceptionCheck();
3622         
3623         cellResult(result.gpr(), node);
3624         break;
3625     }
3626         
3627     case NewTypedArray: {
3628         switch (node->child1().useKind()) {
3629         case Int32Use:
3630             compileNewTypedArray(node);
3631             break;
3632         case UntypedUse: {
3633             JSValueOperand argument(this, node->child1());
3634             GPRReg argumentGPR = argument.gpr();
3635             
3636             flushRegisters();
3637             
3638             GPRFlushedCallResult result(this);
3639             GPRReg resultGPR = result.gpr();
3640             
3641 &nb