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