Templatize CodePtr/Refs/FunctionPtrs with PtrTags.
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSpeculativeJIT64.cpp
1 /*
2  * Copyright (C) 2011-2018 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 "DFGOperations.h"
37 #include "DFGSlowPathGenerator.h"
38 #include "DirectArguments.h"
39 #include "GetterSetter.h"
40 #include "HasOwnPropertyCache.h"
41 #include "JSCInlines.h"
42 #include "JSLexicalEnvironment.h"
43 #include "JSMap.h"
44 #include "JSPropertyNameEnumerator.h"
45 #include "JSSet.h"
46 #include "ObjectPrototype.h"
47 #include "SetupVarargsFrame.h"
48 #include "SpillRegistersMode.h"
49 #include "StringPrototype.h"
50 #include "Watchdog.h"
51
52 namespace JSC { namespace DFG {
53
54 #if USE(JSVALUE64)
55
56 void SpeculativeJIT::boxInt52(GPRReg sourceGPR, GPRReg targetGPR, DataFormat format)
57 {
58     GPRReg tempGPR;
59     if (sourceGPR == targetGPR)
60         tempGPR = allocate();
61     else
62         tempGPR = targetGPR;
63     
64     FPRReg fpr = fprAllocate();
65
66     if (format == DataFormatInt52)
67         m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), sourceGPR);
68     else
69         ASSERT(format == DataFormatStrictInt52);
70     
71     m_jit.boxInt52(sourceGPR, targetGPR, tempGPR, fpr);
72     
73     if (format == DataFormatInt52 && sourceGPR != targetGPR)
74         m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), sourceGPR);
75     
76     if (tempGPR != targetGPR)
77         unlock(tempGPR);
78     
79     unlock(fpr);
80 }
81
82 GPRReg SpeculativeJIT::fillJSValue(Edge edge)
83 {
84     VirtualRegister virtualRegister = edge->virtualRegister();
85     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
86     
87     switch (info.registerFormat()) {
88     case DataFormatNone: {
89         GPRReg gpr = allocate();
90
91         if (edge->hasConstant()) {
92             JSValue jsValue = edge->asJSValue();
93             m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
94             info.fillJSValue(*m_stream, gpr, DataFormatJS);
95             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
96         } else {
97             DataFormat spillFormat = info.spillFormat();
98             m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
99             switch (spillFormat) {
100             case DataFormatInt32: {
101                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
102                 m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr);
103                 spillFormat = DataFormatJSInt32;
104                 break;
105             }
106                 
107             default:
108                 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
109                 DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat & DataFormatJS, spillFormat);
110                 break;
111             }
112             info.fillJSValue(*m_stream, gpr, spillFormat);
113         }
114         return gpr;
115     }
116
117     case DataFormatInt32: {
118         GPRReg gpr = info.gpr();
119         // If the register has already been locked we need to take a copy.
120         // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInt32, not DataFormatJSInt32.
121         if (m_gprs.isLocked(gpr)) {
122             GPRReg result = allocate();
123             m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr, result);
124             return result;
125         }
126         m_gprs.lock(gpr);
127         m_jit.or64(GPRInfo::tagTypeNumberRegister, gpr);
128         info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
129         return gpr;
130     }
131
132     case DataFormatCell:
133         // No retag required on JSVALUE64!
134     case DataFormatJS:
135     case DataFormatJSInt32:
136     case DataFormatJSDouble:
137     case DataFormatJSCell:
138     case DataFormatJSBoolean: {
139         GPRReg gpr = info.gpr();
140         m_gprs.lock(gpr);
141         return gpr;
142     }
143         
144     case DataFormatBoolean:
145     case DataFormatStorage:
146     case DataFormatDouble:
147     case DataFormatInt52:
148         // this type currently never occurs
149         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
150         
151     default:
152         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
153         return InvalidGPRReg;
154     }
155 }
156
157 void SpeculativeJIT::cachedGetById(CodeOrigin origin, JSValueRegs base, JSValueRegs result, unsigned identifierNumber, JITCompiler::Jump slowPathTarget , SpillRegistersMode mode, AccessType type)
158 {
159     cachedGetById(origin, base.gpr(), result.gpr(), identifierNumber, slowPathTarget, mode, type);
160 }
161
162 void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode, AccessType type)
163 {
164     CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
165     RegisterSet usedRegisters = this->usedRegisters();
166     if (spillMode == DontSpill) {
167         // We've already flushed registers to the stack, we don't need to spill these.
168         usedRegisters.set(baseGPR, false);
169         usedRegisters.set(resultGPR, false);
170     }
171     JITGetByIdGenerator gen(
172         m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifierUID(identifierNumber),
173         JSValueRegs(baseGPR), JSValueRegs(resultGPR), type);
174     gen.generateFastPath(m_jit);
175     
176     JITCompiler::JumpList slowCases;
177     if (slowPathTarget.isSet())
178         slowCases.append(slowPathTarget);
179     slowCases.append(gen.slowPathJump());
180
181     auto slowPath = slowPathCall(
182         slowCases, this, appropriateOptimizingGetByIdFunction(type),
183         spillMode, ExceptionCheckRequirement::CheckNeeded,
184         resultGPR, gen.stubInfo(), baseGPR, identifierUID(identifierNumber));
185     
186     m_jit.addGetById(gen, slowPath.get());
187     addSlowPathGenerator(WTFMove(slowPath));
188 }
189
190 void SpeculativeJIT::cachedGetByIdWithThis(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg thisGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::JumpList slowPathTarget)
191 {
192     CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
193     RegisterSet usedRegisters = this->usedRegisters();
194     // We've already flushed registers to the stack, we don't need to spill these.
195     usedRegisters.set(baseGPR, false);
196     usedRegisters.set(thisGPR, false);
197     usedRegisters.set(resultGPR, false);
198     
199     JITGetByIdWithThisGenerator gen(
200         m_jit.codeBlock(), codeOrigin, callSite, usedRegisters, identifierUID(identifierNumber),
201         JSValueRegs(resultGPR), JSValueRegs(baseGPR), JSValueRegs(thisGPR), AccessType::GetWithThis);
202     gen.generateFastPath(m_jit);
203     
204     JITCompiler::JumpList slowCases;
205     if (!slowPathTarget.empty())
206         slowCases.append(slowPathTarget);
207     slowCases.append(gen.slowPathJump());
208     
209     auto 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.branchTest64(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
370         
371         JITCompiler::Jump leftOK = m_jit.branch64(JITCompiler::AboveOrEqual, arg1GPR, GPRInfo::tagTypeNumberRegister);
372         JITCompiler::Jump leftDouble = m_jit.branchTest64(JITCompiler::NonZero, arg1GPR, GPRInfo::tagTypeNumberRegister);
373         leftOK.link(&m_jit);
374         JITCompiler::Jump rightOK = m_jit.branch64(JITCompiler::AboveOrEqual, arg2GPR, GPRInfo::tagTypeNumberRegister);
375         JITCompiler::Jump rightDouble = m_jit.branchTest64(JITCompiler::NonZero, arg2GPR, GPRInfo::tagTypeNumberRegister);
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.branchTest64(JITCompiler::Zero, resultGPR, GPRInfo::tagMaskRegister);
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.branchTest64(JITCompiler::NonZero, 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 #if COMPILER(CLANG) && defined(__has_warning)
881 #pragma clang diagnostic push
882 #if __has_warning("-Wimplicit-fallthrough")
883 #pragma clang diagnostic ignored "-Wimplicit-fallthrough"
884 #endif
885 #endif
886 template<bool strict>
887 GPRReg SpeculativeJIT::fillSpeculateInt32Internal(Edge edge, DataFormat& returnFormat)
888 {
889     AbstractValue& value = m_state.forNode(edge);
890     SpeculatedType type = value.m_type;
891     ASSERT(edge.useKind() != KnownInt32Use || !(value.m_type & ~SpecInt32Only));
892
893     m_interpreter.filter(value, SpecInt32Only);
894     if (value.isClear()) {
895         if (mayHaveTypeCheck(edge.useKind()))
896             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
897         returnFormat = DataFormatInt32;
898         return allocate();
899     }
900
901     VirtualRegister virtualRegister = edge->virtualRegister();
902     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
903
904     switch (info.registerFormat()) {
905     case DataFormatNone: {
906         GPRReg gpr = allocate();
907
908         if (edge->hasConstant()) {
909             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
910             ASSERT(edge->isInt32Constant());
911             m_jit.move(MacroAssembler::Imm32(edge->asInt32()), gpr);
912             info.fillInt32(*m_stream, gpr);
913             returnFormat = DataFormatInt32;
914             return gpr;
915         }
916         
917         DataFormat spillFormat = info.spillFormat();
918         
919         DFG_ASSERT(m_jit.graph(), m_currentNode, (spillFormat & DataFormatJS) || spillFormat == DataFormatInt32, spillFormat);
920         
921         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
922         
923         if (spillFormat == DataFormatJSInt32 || spillFormat == DataFormatInt32) {
924             // If we know this was spilled as an integer we can fill without checking.
925             if (strict) {
926                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
927                 info.fillInt32(*m_stream, gpr);
928                 returnFormat = DataFormatInt32;
929                 return gpr;
930             }
931             if (spillFormat == DataFormatInt32) {
932                 m_jit.load32(JITCompiler::addressFor(virtualRegister), gpr);
933                 info.fillInt32(*m_stream, gpr);
934                 returnFormat = DataFormatInt32;
935             } else {
936                 m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
937                 info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
938                 returnFormat = DataFormatJSInt32;
939             }
940             return gpr;
941         }
942         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
943
944         // Fill as JSValue, and fall through.
945         info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
946         m_gprs.unlock(gpr);
947         FALLTHROUGH;
948     }
949
950     case DataFormatJS: {
951         DFG_ASSERT(m_jit.graph(), m_currentNode, !(type & SpecInt52Only));
952         // Check the value is an integer.
953         GPRReg gpr = info.gpr();
954         m_gprs.lock(gpr);
955         if (type & ~SpecInt32Only)
956             speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branch64(MacroAssembler::Below, gpr, GPRInfo::tagTypeNumberRegister));
957         info.fillJSValue(*m_stream, gpr, DataFormatJSInt32);
958         // If !strict we're done, return.
959         if (!strict) {
960             returnFormat = DataFormatJSInt32;
961             return gpr;
962         }
963         // else fall through & handle as DataFormatJSInt32.
964         m_gprs.unlock(gpr);
965         FALLTHROUGH;
966     }
967
968     case DataFormatJSInt32: {
969         // In a strict fill we need to strip off the value tag.
970         if (strict) {
971             GPRReg gpr = info.gpr();
972             GPRReg result;
973             // If the register has already been locked we need to take a copy.
974             // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInt32, not DataFormatJSInt32.
975             if (m_gprs.isLocked(gpr))
976                 result = allocate();
977             else {
978                 m_gprs.lock(gpr);
979                 info.fillInt32(*m_stream, gpr);
980                 result = gpr;
981             }
982             m_jit.zeroExtend32ToPtr(gpr, result);
983             returnFormat = DataFormatInt32;
984             return result;
985         }
986
987         GPRReg gpr = info.gpr();
988         m_gprs.lock(gpr);
989         returnFormat = DataFormatJSInt32;
990         return gpr;
991     }
992
993     case DataFormatInt32: {
994         GPRReg gpr = info.gpr();
995         m_gprs.lock(gpr);
996         returnFormat = DataFormatInt32;
997         return gpr;
998     }
999         
1000     case DataFormatJSDouble:
1001     case DataFormatCell:
1002     case DataFormatBoolean:
1003     case DataFormatJSCell:
1004     case DataFormatJSBoolean:
1005     case DataFormatDouble:
1006     case DataFormatStorage:
1007     case DataFormatInt52:
1008     case DataFormatStrictInt52:
1009         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
1010         
1011     default:
1012         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
1013         return InvalidGPRReg;
1014     }
1015 }
1016 #if COMPILER(CLANG) && defined(__has_warning)
1017 #pragma clang diagnostic pop
1018 #endif
1019
1020 GPRReg SpeculativeJIT::fillSpeculateInt32(Edge edge, DataFormat& returnFormat)
1021 {
1022     return fillSpeculateInt32Internal<false>(edge, returnFormat);
1023 }
1024
1025 GPRReg SpeculativeJIT::fillSpeculateInt32Strict(Edge edge)
1026 {
1027     DataFormat mustBeDataFormatInt32;
1028     GPRReg result = fillSpeculateInt32Internal<true>(edge, mustBeDataFormatInt32);
1029     DFG_ASSERT(m_jit.graph(), m_currentNode, mustBeDataFormatInt32 == DataFormatInt32, mustBeDataFormatInt32);
1030     return result;
1031 }
1032
1033 GPRReg SpeculativeJIT::fillSpeculateInt52(Edge edge, DataFormat desiredFormat)
1034 {
1035     ASSERT(desiredFormat == DataFormatInt52 || desiredFormat == DataFormatStrictInt52);
1036     AbstractValue& value = m_state.forNode(edge);
1037
1038     m_interpreter.filter(value, SpecAnyInt);
1039     if (value.isClear()) {
1040         if (mayHaveTypeCheck(edge.useKind()))
1041             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1042         return allocate();
1043     }
1044
1045     VirtualRegister virtualRegister = edge->virtualRegister();
1046     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1047
1048     switch (info.registerFormat()) {
1049     case DataFormatNone: {
1050         GPRReg gpr = allocate();
1051
1052         if (edge->hasConstant()) {
1053             JSValue jsValue = edge->asJSValue();
1054             ASSERT(jsValue.isAnyInt());
1055             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1056             int64_t value = jsValue.asAnyInt();
1057             if (desiredFormat == DataFormatInt52)
1058                 value = value << JSValue::int52ShiftAmount;
1059             m_jit.move(MacroAssembler::Imm64(value), gpr);
1060             info.fillGPR(*m_stream, gpr, desiredFormat);
1061             return gpr;
1062         }
1063         
1064         DataFormat spillFormat = info.spillFormat();
1065         
1066         DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatInt52 || spillFormat == DataFormatStrictInt52, spillFormat);
1067         
1068         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1069         
1070         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
1071         if (desiredFormat == DataFormatStrictInt52) {
1072             if (spillFormat == DataFormatInt52)
1073                 m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
1074             info.fillStrictInt52(*m_stream, gpr);
1075             return gpr;
1076         }
1077         if (spillFormat == DataFormatStrictInt52)
1078             m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
1079         info.fillInt52(*m_stream, gpr);
1080         return gpr;
1081     }
1082
1083     case DataFormatStrictInt52: {
1084         GPRReg gpr = info.gpr();
1085         bool wasLocked = m_gprs.isLocked(gpr);
1086         lock(gpr);
1087         if (desiredFormat == DataFormatStrictInt52)
1088             return gpr;
1089         if (wasLocked) {
1090             GPRReg result = allocate();
1091             m_jit.move(gpr, result);
1092             unlock(gpr);
1093             gpr = result;
1094         } else
1095             info.fillInt52(*m_stream, gpr);
1096         m_jit.lshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
1097         return gpr;
1098     }
1099         
1100     case DataFormatInt52: {
1101         GPRReg gpr = info.gpr();
1102         bool wasLocked = m_gprs.isLocked(gpr);
1103         lock(gpr);
1104         if (desiredFormat == DataFormatInt52)
1105             return gpr;
1106         if (wasLocked) {
1107             GPRReg result = allocate();
1108             m_jit.move(gpr, result);
1109             unlock(gpr);
1110             gpr = result;
1111         } else
1112             info.fillStrictInt52(*m_stream, gpr);
1113         m_jit.rshift64(TrustedImm32(JSValue::int52ShiftAmount), gpr);
1114         return gpr;
1115     }
1116
1117     default:
1118         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
1119         return InvalidGPRReg;
1120     }
1121 }
1122
1123 FPRReg SpeculativeJIT::fillSpeculateDouble(Edge edge)
1124 {
1125     ASSERT(edge.useKind() == DoubleRepUse || edge.useKind() == DoubleRepRealUse || edge.useKind() == DoubleRepAnyIntUse);
1126     ASSERT(edge->hasDoubleResult());
1127     VirtualRegister virtualRegister = edge->virtualRegister();
1128     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1129
1130     if (info.registerFormat() == DataFormatNone) {
1131         if (edge->hasConstant()) {
1132             if (edge->isNumberConstant()) {
1133                 FPRReg fpr = fprAllocate();
1134                 int64_t doubleAsInt = reinterpretDoubleToInt64(edge->asNumber());
1135                 if (!doubleAsInt)
1136                     m_jit.moveZeroToDouble(fpr);
1137                 else {
1138                     GPRReg gpr = allocate();
1139                     m_jit.move(MacroAssembler::Imm64(doubleAsInt), gpr);
1140                     m_jit.move64ToDouble(gpr, fpr);
1141                     unlock(gpr);
1142                 }
1143
1144                 m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1145                 info.fillDouble(*m_stream, fpr);
1146                 return fpr;
1147             }
1148             if (mayHaveTypeCheck(edge.useKind()))
1149                 terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1150             return fprAllocate();
1151         }
1152         
1153         DataFormat spillFormat = info.spillFormat();
1154         if (spillFormat != DataFormatDouble) {
1155             DFG_CRASH(
1156                 m_jit.graph(), m_currentNode, toCString(
1157                     "Expected ", edge, " to have double format but instead it is spilled as ",
1158                     dataFormatToString(spillFormat)).data());
1159         }
1160         DFG_ASSERT(m_jit.graph(), m_currentNode, spillFormat == DataFormatDouble, spillFormat);
1161         FPRReg fpr = fprAllocate();
1162         m_jit.loadDouble(JITCompiler::addressFor(virtualRegister), fpr);
1163         m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
1164         info.fillDouble(*m_stream, fpr);
1165         return fpr;
1166     }
1167
1168     DFG_ASSERT(m_jit.graph(), m_currentNode, info.registerFormat() == DataFormatDouble, info.registerFormat());
1169     FPRReg fpr = info.fpr();
1170     m_fprs.lock(fpr);
1171     return fpr;
1172 }
1173
1174 GPRReg SpeculativeJIT::fillSpeculateCell(Edge edge)
1175 {
1176     AbstractValue& value = m_state.forNode(edge);
1177     SpeculatedType type = value.m_type;
1178     ASSERT((edge.useKind() != KnownCellUse && edge.useKind() != KnownStringUse) || !(value.m_type & ~SpecCellCheck));
1179
1180     m_interpreter.filter(value, SpecCellCheck);
1181     if (value.isClear()) {
1182         if (mayHaveTypeCheck(edge.useKind()))
1183             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1184         return allocate();
1185     }
1186
1187     VirtualRegister virtualRegister = edge->virtualRegister();
1188     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1189
1190     switch (info.registerFormat()) {
1191     case DataFormatNone: {
1192         GPRReg gpr = allocate();
1193
1194         if (edge->hasConstant()) {
1195             JSValue jsValue = edge->asJSValue();
1196             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1197             m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
1198             info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
1199             return gpr;
1200         }
1201
1202         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1203         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
1204
1205         info.fillJSValue(*m_stream, gpr, DataFormatJS);
1206         if (type & ~SpecCellCheck)
1207             speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchIfNotCell(JSValueRegs(gpr)));
1208         info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
1209         return gpr;
1210     }
1211
1212     case DataFormatCell:
1213     case DataFormatJSCell: {
1214         GPRReg gpr = info.gpr();
1215         m_gprs.lock(gpr);
1216         if (!ASSERT_DISABLED) {
1217             MacroAssembler::Jump checkCell = m_jit.branchIfCell(JSValueRegs(gpr));
1218             m_jit.abortWithReason(DFGIsNotCell);
1219             checkCell.link(&m_jit);
1220         }
1221         return gpr;
1222     }
1223
1224     case DataFormatJS: {
1225         GPRReg gpr = info.gpr();
1226         m_gprs.lock(gpr);
1227         if (type & ~SpecCellCheck)
1228             speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchIfNotCell(JSValueRegs(gpr)));
1229         info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
1230         return gpr;
1231     }
1232
1233     case DataFormatJSInt32:
1234     case DataFormatInt32:
1235     case DataFormatJSDouble:
1236     case DataFormatJSBoolean:
1237     case DataFormatBoolean:
1238     case DataFormatDouble:
1239     case DataFormatStorage:
1240     case DataFormatInt52:
1241     case DataFormatStrictInt52:
1242         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
1243         
1244     default:
1245         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
1246         return InvalidGPRReg;
1247     }
1248 }
1249
1250 GPRReg SpeculativeJIT::fillSpeculateBoolean(Edge edge)
1251 {
1252     AbstractValue& value = m_state.forNode(edge);
1253     SpeculatedType type = value.m_type;
1254     ASSERT(edge.useKind() != KnownBooleanUse || !(value.m_type & ~SpecBoolean));
1255
1256     m_interpreter.filter(value, SpecBoolean);
1257     if (value.isClear()) {
1258         if (mayHaveTypeCheck(edge.useKind()))
1259             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
1260         return allocate();
1261     }
1262
1263     VirtualRegister virtualRegister = edge->virtualRegister();
1264     GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
1265
1266     switch (info.registerFormat()) {
1267     case DataFormatNone: {
1268         GPRReg gpr = allocate();
1269
1270         if (edge->hasConstant()) {
1271             JSValue jsValue = edge->asJSValue();
1272             m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
1273             m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
1274             info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
1275             return gpr;
1276         }
1277         DFG_ASSERT(m_jit.graph(), m_currentNode, info.spillFormat() & DataFormatJS, info.spillFormat());
1278         m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
1279         m_jit.load64(JITCompiler::addressFor(virtualRegister), gpr);
1280
1281         info.fillJSValue(*m_stream, gpr, DataFormatJS);
1282         if (type & ~SpecBoolean) {
1283             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1284             speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
1285             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1286         }
1287         info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
1288         return gpr;
1289     }
1290
1291     case DataFormatBoolean:
1292     case DataFormatJSBoolean: {
1293         GPRReg gpr = info.gpr();
1294         m_gprs.lock(gpr);
1295         return gpr;
1296     }
1297
1298     case DataFormatJS: {
1299         GPRReg gpr = info.gpr();
1300         m_gprs.lock(gpr);
1301         if (type & ~SpecBoolean) {
1302             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1303             speculationCheck(BadType, JSValueRegs(gpr), edge, m_jit.branchTest64(MacroAssembler::NonZero, gpr, TrustedImm32(static_cast<int32_t>(~1))), SpeculationRecovery(BooleanSpeculationCheck, gpr, InvalidGPRReg));
1304             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), gpr);
1305         }
1306         info.fillJSValue(*m_stream, gpr, DataFormatJSBoolean);
1307         return gpr;
1308     }
1309
1310     case DataFormatJSInt32:
1311     case DataFormatInt32:
1312     case DataFormatJSDouble:
1313     case DataFormatJSCell:
1314     case DataFormatCell:
1315     case DataFormatDouble:
1316     case DataFormatStorage:
1317     case DataFormatInt52:
1318     case DataFormatStrictInt52:
1319         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad data format");
1320         
1321     default:
1322         DFG_CRASH(m_jit.graph(), m_currentNode, "Corrupt data format");
1323         return InvalidGPRReg;
1324     }
1325 }
1326
1327 void SpeculativeJIT::compileObjectEquality(Node* node)
1328 {
1329     SpeculateCellOperand op1(this, node->child1());
1330     SpeculateCellOperand op2(this, node->child2());
1331     GPRTemporary result(this, Reuse, op1);
1332     
1333     GPRReg op1GPR = op1.gpr();
1334     GPRReg op2GPR = op2.gpr();
1335     GPRReg resultGPR = result.gpr();
1336    
1337     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
1338         DFG_TYPE_CHECK(
1339             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
1340         DFG_TYPE_CHECK(
1341             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
1342     } else {
1343         DFG_TYPE_CHECK(
1344             JSValueSource::unboxedCell(op1GPR), node->child1(), SpecObject, m_jit.branchIfNotObject(op1GPR));
1345         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), node->child1(),
1346             m_jit.branchTest8(
1347                 MacroAssembler::NonZero, 
1348                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
1349                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1350
1351         DFG_TYPE_CHECK(
1352             JSValueSource::unboxedCell(op2GPR), node->child2(), SpecObject, m_jit.branchIfNotObject(op2GPR));
1353         speculationCheck(BadType, JSValueSource::unboxedCell(op2GPR), node->child2(),
1354             m_jit.branchTest8(
1355                 MacroAssembler::NonZero, 
1356                 MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()), 
1357                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1358     }
1359
1360     m_jit.compare64(MacroAssembler::Equal, op1GPR, op2GPR, resultGPR);
1361     m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
1362     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
1363 }
1364
1365 void SpeculativeJIT::compileObjectStrictEquality(Edge objectChild, Edge otherChild)
1366 {
1367     SpeculateCellOperand op1(this, objectChild);
1368     JSValueOperand op2(this, otherChild);
1369     GPRTemporary result(this);
1370
1371     GPRReg op1GPR = op1.gpr();
1372     GPRReg op2GPR = op2.gpr();
1373     GPRReg resultGPR = result.gpr();
1374
1375     DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1376
1377     // At this point we know that we can perform a straight-forward equality comparison on pointer
1378     // values because we are doing strict equality.
1379     m_jit.compare64(MacroAssembler::Equal, op1GPR, op2GPR, resultGPR);
1380     m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
1381     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
1382 }
1383     
1384 void SpeculativeJIT::compilePeepHoleObjectStrictEquality(Edge objectChild, Edge otherChild, Node* branchNode)
1385 {
1386     BasicBlock* taken = branchNode->branchData()->taken.block;
1387     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
1388     
1389     SpeculateCellOperand op1(this, objectChild);
1390     JSValueOperand op2(this, otherChild);
1391     
1392     GPRReg op1GPR = op1.gpr();
1393     GPRReg op2GPR = op2.gpr();
1394     
1395     DFG_TYPE_CHECK(JSValueSource::unboxedCell(op1GPR), objectChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1396
1397     if (taken == nextBlock()) {
1398         branchPtr(MacroAssembler::NotEqual, op1GPR, op2GPR, notTaken);
1399         jump(taken);
1400     } else {
1401         branchPtr(MacroAssembler::Equal, op1GPR, op2GPR, taken);
1402         jump(notTaken);
1403     }
1404 }
1405
1406 void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild)
1407 {
1408     SpeculateCellOperand op1(this, leftChild);
1409     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
1410     GPRTemporary result(this);
1411     
1412     GPRReg op1GPR = op1.gpr();
1413     GPRReg op2GPR = op2.gpr();
1414     GPRReg resultGPR = result.gpr();
1415
1416     bool masqueradesAsUndefinedWatchpointValid =
1417         masqueradesAsUndefinedWatchpointIsStillValid();
1418
1419     if (masqueradesAsUndefinedWatchpointValid) {
1420         DFG_TYPE_CHECK(
1421             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1422     } else {
1423         DFG_TYPE_CHECK(
1424             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1425         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild,
1426             m_jit.branchTest8(
1427                 MacroAssembler::NonZero, 
1428                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
1429                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1430     }
1431     
1432     // It seems that most of the time when programs do a == b where b may be either null/undefined
1433     // or an object, b is usually an object. Balance the branches to make that case fast.
1434     MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(JSValueRegs(op2GPR));
1435     
1436     // We know that within this branch, rightChild must be a cell. 
1437     if (masqueradesAsUndefinedWatchpointValid) {
1438         DFG_TYPE_CHECK(
1439             JSValueRegs(op2GPR), rightChild, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(op2GPR));
1440     } else {
1441         DFG_TYPE_CHECK(
1442             JSValueRegs(op2GPR), rightChild, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(op2GPR));
1443         speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
1444             m_jit.branchTest8(
1445                 MacroAssembler::NonZero, 
1446                 MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()), 
1447                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1448     }
1449     
1450     // At this point we know that we can perform a straight-forward equality comparison on pointer
1451     // values because both left and right are pointers to objects that have no special equality
1452     // protocols.
1453     m_jit.compare64(MacroAssembler::Equal, op1GPR, op2GPR, resultGPR);
1454     MacroAssembler::Jump done = m_jit.jump();
1455     
1456     rightNotCell.link(&m_jit);
1457     
1458     // We know that within this branch, rightChild must not be a cell. Check if that is enough to
1459     // prove that it is either null or undefined.
1460     if (needsTypeCheck(rightChild, SpecCellCheck | SpecOther)) {
1461         m_jit.move(op2GPR, resultGPR);
1462         m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
1463         
1464         typeCheck(
1465             JSValueRegs(op2GPR), rightChild, SpecCellCheck | SpecOther,
1466             m_jit.branch64(
1467                 MacroAssembler::NotEqual, resultGPR,
1468                 MacroAssembler::TrustedImm64(ValueNull)));
1469     }
1470     m_jit.move(TrustedImm32(0), result.gpr());
1471
1472     done.link(&m_jit);
1473     m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
1474     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
1475 }
1476
1477 void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild, Edge rightChild, Node* branchNode)
1478 {
1479     BasicBlock* taken = branchNode->branchData()->taken.block;
1480     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
1481     
1482     SpeculateCellOperand op1(this, leftChild);
1483     JSValueOperand op2(this, rightChild, ManualOperandSpeculation);
1484     GPRTemporary result(this);
1485     
1486     GPRReg op1GPR = op1.gpr();
1487     GPRReg op2GPR = op2.gpr();
1488     GPRReg resultGPR = result.gpr();
1489     
1490     bool masqueradesAsUndefinedWatchpointValid = 
1491         masqueradesAsUndefinedWatchpointIsStillValid();
1492
1493     if (masqueradesAsUndefinedWatchpointValid) {
1494         DFG_TYPE_CHECK(
1495             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1496     } else {
1497         DFG_TYPE_CHECK(
1498             JSValueSource::unboxedCell(op1GPR), leftChild, SpecObject, m_jit.branchIfNotObject(op1GPR));
1499         speculationCheck(BadType, JSValueSource::unboxedCell(op1GPR), leftChild, 
1500             m_jit.branchTest8(
1501                 MacroAssembler::NonZero, 
1502                 MacroAssembler::Address(op1GPR, JSCell::typeInfoFlagsOffset()), 
1503                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1504     }
1505
1506     // It seems that most of the time when programs do a == b where b may be either null/undefined
1507     // or an object, b is usually an object. Balance the branches to make that case fast.
1508     MacroAssembler::Jump rightNotCell = m_jit.branchIfNotCell(JSValueRegs(op2GPR));
1509     
1510     // We know that within this branch, rightChild must be a cell. 
1511     if (masqueradesAsUndefinedWatchpointValid) {
1512         DFG_TYPE_CHECK(
1513             JSValueRegs(op2GPR), rightChild, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(op2GPR));
1514     } else {
1515         DFG_TYPE_CHECK(
1516             JSValueRegs(op2GPR), rightChild, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(op2GPR));
1517         speculationCheck(BadType, JSValueRegs(op2GPR), rightChild,
1518             m_jit.branchTest8(
1519                 MacroAssembler::NonZero, 
1520                 MacroAssembler::Address(op2GPR, JSCell::typeInfoFlagsOffset()), 
1521                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined)));
1522     }
1523     
1524     // At this point we know that we can perform a straight-forward equality comparison on pointer
1525     // values because both left and right are pointers to objects that have no special equality
1526     // protocols.
1527     branch64(MacroAssembler::Equal, op1GPR, op2GPR, taken);
1528     
1529     // We know that within this branch, rightChild must not be a cell. Check if that is enough to
1530     // prove that it is either null or undefined.
1531     if (!needsTypeCheck(rightChild, SpecCellCheck | SpecOther))
1532         rightNotCell.link(&m_jit);
1533     else {
1534         jump(notTaken, ForceJump);
1535         
1536         rightNotCell.link(&m_jit);
1537         m_jit.move(op2GPR, resultGPR);
1538         m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
1539         
1540         typeCheck(
1541             JSValueRegs(op2GPR), rightChild, SpecCellCheck | SpecOther, m_jit.branch64(
1542                 MacroAssembler::NotEqual, resultGPR,
1543                 MacroAssembler::TrustedImm64(ValueNull)));
1544     }
1545     
1546     jump(notTaken);
1547 }
1548
1549 void SpeculativeJIT::compileSymbolUntypedEquality(Node* node, Edge symbolEdge, Edge untypedEdge)
1550 {
1551     SpeculateCellOperand symbol(this, symbolEdge);
1552     JSValueOperand untyped(this, untypedEdge);
1553     GPRTemporary result(this, Reuse, symbol, untyped);
1554
1555     GPRReg symbolGPR = symbol.gpr();
1556     GPRReg untypedGPR = untyped.gpr();
1557     GPRReg resultGPR = result.gpr();
1558
1559     speculateSymbol(symbolEdge, symbolGPR);
1560
1561     // At this point we know that we can perform a straight-forward equality comparison on pointer
1562     // values because we are doing strict equality.
1563     m_jit.compare64(MacroAssembler::Equal, symbolGPR, untypedGPR, resultGPR);
1564     unblessedBooleanResult(resultGPR, node);
1565 }
1566
1567 void SpeculativeJIT::compileInt32Compare(Node* node, MacroAssembler::RelationalCondition condition)
1568 {
1569     if (node->child1()->isInt32Constant()) {
1570         SpeculateInt32Operand op2(this, node->child2());
1571         GPRTemporary result(this, Reuse, op2);
1572         int32_t imm = node->child1()->asInt32();
1573         m_jit.compare32(condition, JITCompiler::Imm32(imm), op2.gpr(), result.gpr());
1574
1575         // If we add a DataFormatBool, we should use it here.
1576         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1577         jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1578     } else if (node->child2()->isInt32Constant()) {
1579         SpeculateInt32Operand op1(this, node->child1());
1580         GPRTemporary result(this, Reuse, op1);
1581         int32_t imm = node->child2()->asInt32();
1582         m_jit.compare32(condition, op1.gpr(), JITCompiler::Imm32(imm), result.gpr());
1583
1584         // If we add a DataFormatBool, we should use it here.
1585         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1586         jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1587     } else {
1588         SpeculateInt32Operand op1(this, node->child1());
1589         SpeculateInt32Operand op2(this, node->child2());
1590         GPRTemporary result(this, Reuse, op1, op2);
1591         m_jit.compare32(condition, op1.gpr(), op2.gpr(), result.gpr());
1592
1593         // If we add a DataFormatBool, we should use it here.
1594         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1595         jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1596     }
1597 }
1598
1599 void SpeculativeJIT::compileInt52Compare(Node* node, MacroAssembler::RelationalCondition condition)
1600 {
1601     SpeculateWhicheverInt52Operand op1(this, node->child1());
1602     SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
1603     GPRTemporary result(this, Reuse, op1, op2);
1604     
1605     m_jit.compare64(condition, op1.gpr(), op2.gpr(), result.gpr());
1606     
1607     // If we add a DataFormatBool, we should use it here.
1608     m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1609     jsValueResult(result.gpr(), m_currentNode, DataFormatJSBoolean);
1610 }
1611
1612 void SpeculativeJIT::compilePeepHoleInt52Branch(Node* node, Node* branchNode, JITCompiler::RelationalCondition condition)
1613 {
1614     BasicBlock* taken = branchNode->branchData()->taken.block;
1615     BasicBlock* notTaken = branchNode->branchData()->notTaken.block;
1616
1617     // The branch instruction will branch to the taken block.
1618     // If taken is next, switch taken with notTaken & invert the branch condition so we can fall through.
1619     if (taken == nextBlock()) {
1620         condition = JITCompiler::invert(condition);
1621         BasicBlock* tmp = taken;
1622         taken = notTaken;
1623         notTaken = tmp;
1624     }
1625     
1626     SpeculateWhicheverInt52Operand op1(this, node->child1());
1627     SpeculateWhicheverInt52Operand op2(this, node->child2(), op1);
1628     
1629     branch64(condition, op1.gpr(), op2.gpr(), taken);
1630     jump(notTaken);
1631 }
1632
1633 void SpeculativeJIT::compileDoubleCompare(Node* node, MacroAssembler::DoubleCondition condition)
1634 {
1635     SpeculateDoubleOperand op1(this, node->child1());
1636     SpeculateDoubleOperand op2(this, node->child2());
1637     GPRTemporary result(this);
1638     
1639     m_jit.move(TrustedImm32(ValueTrue), result.gpr());
1640     MacroAssembler::Jump trueCase = m_jit.branchDouble(condition, op1.fpr(), op2.fpr());
1641     m_jit.xor64(TrustedImm32(true), result.gpr());
1642     trueCase.link(&m_jit);
1643     
1644     jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1645 }
1646
1647 void SpeculativeJIT::compileCompareEqPtr(Node* node)
1648 {
1649     JSValueOperand value(this, node->child1());
1650     GPRTemporary result(this);
1651     GPRReg valueGPR = value.gpr();
1652     GPRReg resultGPR = result.gpr();
1653
1654     m_jit.move(TrustedImmPtr::weakPointer(m_jit.graph(), node->cellOperand()->cell()), resultGPR);
1655     m_jit.compare64(MacroAssembler::Equal, valueGPR, resultGPR, resultGPR);
1656     unblessedBooleanResult(resultGPR, node);
1657 }
1658
1659 void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
1660 {
1661     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
1662     GPRTemporary result(this);
1663     GPRReg valueGPR = value.gpr();
1664     GPRReg resultGPR = result.gpr();
1665     GPRTemporary structure;
1666     GPRReg structureGPR = InvalidGPRReg;
1667     GPRTemporary scratch;
1668     GPRReg scratchGPR = InvalidGPRReg;
1669
1670     bool masqueradesAsUndefinedWatchpointValid =
1671         masqueradesAsUndefinedWatchpointIsStillValid();
1672
1673     if (!masqueradesAsUndefinedWatchpointValid) {
1674         // The masquerades as undefined case will use the structure register, so allocate it here.
1675         // Do this at the top of the function to avoid branching around a register allocation.
1676         GPRTemporary realStructure(this);
1677         GPRTemporary realScratch(this);
1678         structure.adopt(realStructure);
1679         scratch.adopt(realScratch);
1680         structureGPR = structure.gpr();
1681         scratchGPR = scratch.gpr();
1682     }
1683
1684     MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
1685     if (masqueradesAsUndefinedWatchpointValid) {
1686         DFG_TYPE_CHECK(
1687             JSValueRegs(valueGPR), nodeUse, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1688     } else {
1689         DFG_TYPE_CHECK(
1690             JSValueRegs(valueGPR), nodeUse, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1691
1692         MacroAssembler::Jump isNotMasqueradesAsUndefined = 
1693             m_jit.branchTest8(
1694                 MacroAssembler::Zero, 
1695                 MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), 
1696                 MacroAssembler::TrustedImm32(MasqueradesAsUndefined));
1697
1698         m_jit.emitLoadStructure(*m_jit.vm(), valueGPR, structureGPR, scratchGPR);
1699         speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse, 
1700             m_jit.branchPtr(
1701                 MacroAssembler::Equal, 
1702                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
1703                 TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic))));
1704
1705         isNotMasqueradesAsUndefined.link(&m_jit);
1706     }
1707     m_jit.move(TrustedImm32(ValueFalse), resultGPR);
1708     MacroAssembler::Jump done = m_jit.jump();
1709     
1710     notCell.link(&m_jit);
1711
1712     if (needsTypeCheck(nodeUse, SpecCellCheck | SpecOther)) {
1713         m_jit.move(valueGPR, resultGPR);
1714         m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), resultGPR);
1715         typeCheck(
1716             JSValueRegs(valueGPR), nodeUse, SpecCellCheck | SpecOther, m_jit.branch64(
1717                 MacroAssembler::NotEqual, 
1718                 resultGPR, 
1719                 MacroAssembler::TrustedImm64(ValueNull)));
1720     }
1721     m_jit.move(TrustedImm32(ValueTrue), resultGPR);
1722     
1723     done.link(&m_jit);
1724     
1725     jsValueResult(resultGPR, m_currentNode, DataFormatJSBoolean);
1726 }
1727
1728 void SpeculativeJIT::compileLogicalNot(Node* node)
1729 {
1730     switch (node->child1().useKind()) {
1731     case ObjectOrOtherUse: {
1732         compileObjectOrOtherLogicalNot(node->child1());
1733         return;
1734     }
1735         
1736     case Int32Use: {
1737         SpeculateInt32Operand value(this, node->child1());
1738         GPRTemporary result(this, Reuse, value);
1739         m_jit.compare32(MacroAssembler::Equal, value.gpr(), MacroAssembler::TrustedImm32(0), result.gpr());
1740         m_jit.or32(TrustedImm32(ValueFalse), result.gpr());
1741         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1742         return;
1743     }
1744         
1745     case DoubleRepUse: {
1746         SpeculateDoubleOperand value(this, node->child1());
1747         FPRTemporary scratch(this);
1748         GPRTemporary result(this);
1749         m_jit.move(TrustedImm32(ValueFalse), result.gpr());
1750         MacroAssembler::Jump nonZero = m_jit.branchDoubleNonZero(value.fpr(), scratch.fpr());
1751         m_jit.xor32(TrustedImm32(true), result.gpr());
1752         nonZero.link(&m_jit);
1753         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1754         return;
1755     }
1756     
1757     case BooleanUse:
1758     case KnownBooleanUse: {
1759         if (!needsTypeCheck(node->child1(), SpecBoolean)) {
1760             SpeculateBooleanOperand value(this, node->child1());
1761             GPRTemporary result(this, Reuse, value);
1762             
1763             m_jit.move(value.gpr(), result.gpr());
1764             m_jit.xor64(TrustedImm32(true), result.gpr());
1765             
1766             jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1767             return;
1768         }
1769         
1770         JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
1771         GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
1772         
1773         m_jit.move(value.gpr(), result.gpr());
1774         m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
1775         typeCheck(
1776             JSValueRegs(value.gpr()), node->child1(), SpecBoolean, m_jit.branchTest64(
1777                 JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
1778         m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueTrue)), result.gpr());
1779         
1780         // If we add a DataFormatBool, we should use it here.
1781         jsValueResult(result.gpr(), node, DataFormatJSBoolean);
1782         return;
1783     }
1784         
1785     case UntypedUse: {
1786         JSValueOperand arg1(this, node->child1());
1787         GPRTemporary result(this);
1788     
1789         GPRReg arg1GPR = arg1.gpr();
1790         GPRReg resultGPR = result.gpr();
1791
1792         FPRTemporary valueFPR(this);
1793         FPRTemporary tempFPR(this);
1794
1795         bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
1796         JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
1797         std::optional<GPRTemporary> scratch;
1798         GPRReg scratchGPR = InvalidGPRReg;
1799         if (shouldCheckMasqueradesAsUndefined) {
1800             scratch.emplace(this);
1801             scratchGPR = scratch->gpr();
1802         }
1803         bool negateResult = true;
1804         m_jit.emitConvertValueToBoolean(*m_jit.vm(), JSValueRegs(arg1GPR), resultGPR, scratchGPR, valueFPR.fpr(), tempFPR.fpr(), shouldCheckMasqueradesAsUndefined, globalObject, negateResult);
1805         m_jit.or32(TrustedImm32(ValueFalse), resultGPR);
1806         jsValueResult(resultGPR, node, DataFormatJSBoolean);
1807         return;
1808     }
1809     case StringUse:
1810         return compileStringZeroLength(node);
1811
1812     case StringOrOtherUse:
1813         return compileLogicalNotStringOrOther(node);
1814
1815     default:
1816         DFG_CRASH(m_jit.graph(), node, "Bad use kind");
1817         break;
1818     }
1819 }
1820
1821 void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
1822 {
1823     JSValueOperand value(this, nodeUse, ManualOperandSpeculation);
1824     GPRTemporary scratch(this);
1825     GPRTemporary structure;
1826     GPRReg valueGPR = value.gpr();
1827     GPRReg scratchGPR = scratch.gpr();
1828     GPRReg structureGPR = InvalidGPRReg;
1829
1830     if (!masqueradesAsUndefinedWatchpointIsStillValid()) {
1831         GPRTemporary realStructure(this);
1832         structure.adopt(realStructure);
1833         structureGPR = structure.gpr();
1834     }
1835
1836     MacroAssembler::Jump notCell = m_jit.branchIfNotCell(JSValueRegs(valueGPR));
1837     if (masqueradesAsUndefinedWatchpointIsStillValid()) {
1838         DFG_TYPE_CHECK(
1839             JSValueRegs(valueGPR), nodeUse, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1840     } else {
1841         DFG_TYPE_CHECK(
1842             JSValueRegs(valueGPR), nodeUse, (~SpecCellCheck) | SpecObject, m_jit.branchIfNotObject(valueGPR));
1843
1844         JITCompiler::Jump isNotMasqueradesAsUndefined = m_jit.branchTest8(
1845             JITCompiler::Zero, 
1846             MacroAssembler::Address(valueGPR, JSCell::typeInfoFlagsOffset()), 
1847             TrustedImm32(MasqueradesAsUndefined));
1848
1849         m_jit.emitLoadStructure(*m_jit.vm(), valueGPR, structureGPR, scratchGPR);
1850         speculationCheck(BadType, JSValueRegs(valueGPR), nodeUse,
1851             m_jit.branchPtr(
1852                 MacroAssembler::Equal, 
1853                 MacroAssembler::Address(structureGPR, Structure::globalObjectOffset()), 
1854                 TrustedImmPtr::weakPointer(m_jit.graph(), m_jit.graph().globalObjectFor(m_currentNode->origin.semantic))));
1855
1856         isNotMasqueradesAsUndefined.link(&m_jit);
1857     }
1858     jump(taken, ForceJump);
1859     
1860     notCell.link(&m_jit);
1861     
1862     if (needsTypeCheck(nodeUse, SpecCellCheck | SpecOther)) {
1863         m_jit.move(valueGPR, scratchGPR);
1864         m_jit.and64(MacroAssembler::TrustedImm32(~TagBitUndefined), scratchGPR);
1865         typeCheck(
1866             JSValueRegs(valueGPR), nodeUse, SpecCellCheck | SpecOther, m_jit.branch64(
1867                 MacroAssembler::NotEqual, scratchGPR, MacroAssembler::TrustedImm64(ValueNull)));
1868     }
1869     jump(notTaken);
1870     
1871     noResult(m_currentNode);
1872 }
1873
1874 void SpeculativeJIT::emitBranch(Node* node)
1875 {
1876     BasicBlock* taken = node->branchData()->taken.block;
1877     BasicBlock* notTaken = node->branchData()->notTaken.block;
1878     
1879     switch (node->child1().useKind()) {
1880     case ObjectOrOtherUse: {
1881         emitObjectOrOtherBranch(node->child1(), taken, notTaken);
1882         return;
1883     }
1884         
1885     case Int32Use:
1886     case DoubleRepUse: {
1887         if (node->child1().useKind() == Int32Use) {
1888             bool invert = false;
1889             
1890             if (taken == nextBlock()) {
1891                 invert = true;
1892                 BasicBlock* tmp = taken;
1893                 taken = notTaken;
1894                 notTaken = tmp;
1895             }
1896
1897             SpeculateInt32Operand value(this, node->child1());
1898             branchTest32(invert ? MacroAssembler::Zero : MacroAssembler::NonZero, value.gpr(), taken);
1899         } else {
1900             SpeculateDoubleOperand value(this, node->child1());
1901             FPRTemporary scratch(this);
1902             branchDoubleNonZero(value.fpr(), scratch.fpr(), taken);
1903         }
1904         
1905         jump(notTaken);
1906         
1907         noResult(node);
1908         return;
1909     }
1910
1911     case StringUse: {
1912         emitStringBranch(node->child1(), taken, notTaken);
1913         return;
1914     }
1915
1916     case StringOrOtherUse: {
1917         emitStringOrOtherBranch(node->child1(), taken, notTaken);
1918         return;
1919     }
1920
1921     case UntypedUse:
1922     case BooleanUse:
1923     case KnownBooleanUse: {
1924         JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
1925         GPRReg valueGPR = value.gpr();
1926         
1927         if (node->child1().useKind() == BooleanUse || node->child1().useKind() == KnownBooleanUse) {
1928             if (!needsTypeCheck(node->child1(), SpecBoolean)) {
1929                 MacroAssembler::ResultCondition condition = MacroAssembler::NonZero;
1930                 
1931                 if (taken == nextBlock()) {
1932                     condition = MacroAssembler::Zero;
1933                     BasicBlock* tmp = taken;
1934                     taken = notTaken;
1935                     notTaken = tmp;
1936                 }
1937                 
1938                 branchTest32(condition, valueGPR, TrustedImm32(true), taken);
1939                 jump(notTaken);
1940             } else {
1941                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
1942                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
1943                 
1944                 typeCheck(JSValueRegs(valueGPR), node->child1(), SpecBoolean, m_jit.jump());
1945             }
1946             value.use();
1947         } else {
1948             GPRTemporary result(this);
1949             FPRTemporary fprValue(this);
1950             FPRTemporary fprTemp(this);
1951             std::optional<GPRTemporary> scratch;
1952
1953             GPRReg scratchGPR = InvalidGPRReg;
1954             bool shouldCheckMasqueradesAsUndefined = !masqueradesAsUndefinedWatchpointIsStillValid();
1955             if (shouldCheckMasqueradesAsUndefined) {
1956                 scratch.emplace(this);
1957                 scratchGPR = scratch->gpr();
1958             }
1959
1960             GPRReg resultGPR = result.gpr();
1961             FPRReg valueFPR = fprValue.fpr();
1962             FPRReg tempFPR = fprTemp.fpr();
1963             
1964             if (node->child1()->prediction() & SpecInt32Only) {
1965                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), notTaken);
1966                 branch64(MacroAssembler::AboveOrEqual, valueGPR, GPRInfo::tagTypeNumberRegister, taken);
1967             }
1968     
1969             if (node->child1()->prediction() & SpecBoolean) {
1970                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(false))), notTaken);
1971                 branch64(MacroAssembler::Equal, valueGPR, MacroAssembler::TrustedImm64(JSValue::encode(jsBoolean(true))), taken);
1972             }
1973     
1974             value.use();
1975
1976             JSGlobalObject* globalObject = m_jit.graph().globalObjectFor(node->origin.semantic);
1977             m_jit.emitConvertValueToBoolean(*m_jit.vm(), JSValueRegs(valueGPR), resultGPR, scratchGPR, valueFPR, tempFPR, shouldCheckMasqueradesAsUndefined, globalObject);
1978     
1979             branchTest32(MacroAssembler::NonZero, resultGPR, taken);
1980             jump(notTaken);
1981         }
1982         
1983         noResult(node, UseChildrenCalledExplicitly);
1984         return;
1985     }
1986         
1987     default:
1988         DFG_CRASH(m_jit.graph(), m_currentNode, "Bad use kind");
1989     }
1990 }
1991
1992 void SpeculativeJIT::compile(Node* node)
1993 {
1994     NodeType op = node->op();
1995     
1996 #if ENABLE(DFG_REGISTER_ALLOCATION_VALIDATION)
1997     m_jit.clearRegisterAllocationOffsets();
1998 #endif
1999
2000     switch (op) {
2001     case JSConstant:
2002     case DoubleConstant:
2003     case Int52Constant:
2004     case PhantomDirectArguments:
2005     case PhantomClonedArguments:
2006         initConstantInfo(node);
2007         break;
2008
2009     case LazyJSConstant:
2010         compileLazyJSConstant(node);
2011         break;
2012
2013     case Identity: {
2014         compileIdentity(node);
2015         break;
2016     }
2017
2018     case GetLocal: {
2019         AbstractValue& value = m_state.variables().operand(node->local());
2020
2021         // If the CFA is tracking this variable and it found that the variable
2022         // cannot have been assigned, then don't attempt to proceed.
2023         if (value.isClear()) {
2024             m_compileOkay = false;
2025             break;
2026         }
2027         
2028         switch (node->variableAccessData()->flushFormat()) {
2029         case FlushedDouble: {
2030             FPRTemporary result(this);
2031             m_jit.loadDouble(JITCompiler::addressFor(node->machineLocal()), result.fpr());
2032             VirtualRegister virtualRegister = node->virtualRegister();
2033             m_fprs.retain(result.fpr(), virtualRegister, SpillOrderDouble);
2034             generationInfoFromVirtualRegister(virtualRegister).initDouble(node, node->refCount(), result.fpr());
2035             break;
2036         }
2037         
2038         case FlushedInt32: {
2039             GPRTemporary result(this);
2040             m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
2041             
2042             // Like int32Result, but don't useChildren - our children are phi nodes,
2043             // and don't represent values within this dataflow with virtual registers.
2044             VirtualRegister virtualRegister = node->virtualRegister();
2045             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderInteger);
2046             generationInfoFromVirtualRegister(virtualRegister).initInt32(node, node->refCount(), result.gpr());
2047             break;
2048         }
2049             
2050         case FlushedInt52: {
2051             GPRTemporary result(this);
2052             m_jit.load64(JITCompiler::addressFor(node->machineLocal()), result.gpr());
2053             
2054             VirtualRegister virtualRegister = node->virtualRegister();
2055             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
2056             generationInfoFromVirtualRegister(virtualRegister).initInt52(node, node->refCount(), result.gpr());
2057             break;
2058         }
2059             
2060         default:
2061             GPRTemporary result(this);
2062             m_jit.load64(JITCompiler::addressFor(node->machineLocal()), result.gpr());
2063             
2064             // Like jsValueResult, but don't useChildren - our children are phi nodes,
2065             // and don't represent values within this dataflow with virtual registers.
2066             VirtualRegister virtualRegister = node->virtualRegister();
2067             m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
2068             
2069             DataFormat format;
2070             if (isCellSpeculation(value.m_type))
2071                 format = DataFormatJSCell;
2072             else if (isBooleanSpeculation(value.m_type))
2073                 format = DataFormatJSBoolean;
2074             else
2075                 format = DataFormatJS;
2076             
2077             generationInfoFromVirtualRegister(virtualRegister).initJSValue(node, node->refCount(), result.gpr(), format);
2078             break;
2079         }
2080         break;
2081     }
2082
2083     case MovHint: {
2084         compileMovHint(m_currentNode);
2085         noResult(node);
2086         break;
2087     }
2088         
2089     case ZombieHint: {
2090         recordSetLocal(m_currentNode->unlinkedLocal(), VirtualRegister(), DataFormatDead);
2091         noResult(node);
2092         break;
2093     }
2094         
2095     case ExitOK: {
2096         noResult(node);
2097         break;
2098     }
2099         
2100     case SetLocal: {
2101         switch (node->variableAccessData()->flushFormat()) {
2102         case FlushedDouble: {
2103             SpeculateDoubleOperand value(this, node->child1());
2104             m_jit.storeDouble(value.fpr(), JITCompiler::addressFor(node->machineLocal()));
2105             noResult(node);
2106             // Indicate that it's no longer necessary to retrieve the value of
2107             // this bytecode variable from registers or other locations in the stack,
2108             // but that it is stored as a double.
2109             recordSetLocal(DataFormatDouble);
2110             break;
2111         }
2112             
2113         case FlushedInt32: {
2114             SpeculateInt32Operand value(this, node->child1());
2115             m_jit.store32(value.gpr(), JITCompiler::payloadFor(node->machineLocal()));
2116             noResult(node);
2117             recordSetLocal(DataFormatInt32);
2118             break;
2119         }
2120             
2121         case FlushedInt52: {
2122             SpeculateInt52Operand value(this, node->child1());
2123             m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
2124             noResult(node);
2125             recordSetLocal(DataFormatInt52);
2126             break;
2127         }
2128             
2129         case FlushedCell: {
2130             SpeculateCellOperand cell(this, node->child1());
2131             GPRReg cellGPR = cell.gpr();
2132             m_jit.store64(cellGPR, JITCompiler::addressFor(node->machineLocal()));
2133             noResult(node);
2134             recordSetLocal(DataFormatCell);
2135             break;
2136         }
2137             
2138         case FlushedBoolean: {
2139             SpeculateBooleanOperand boolean(this, node->child1());
2140             m_jit.store64(boolean.gpr(), JITCompiler::addressFor(node->machineLocal()));
2141             noResult(node);
2142             recordSetLocal(DataFormatBoolean);
2143             break;
2144         }
2145             
2146         case FlushedJSValue: {
2147             JSValueOperand value(this, node->child1());
2148             m_jit.store64(value.gpr(), JITCompiler::addressFor(node->machineLocal()));
2149             noResult(node);
2150             recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
2151             break;
2152         }
2153             
2154         default:
2155             DFG_CRASH(m_jit.graph(), node, "Bad flush format");
2156             break;
2157         }
2158
2159         break;
2160     }
2161
2162     case SetArgument:
2163         // This is a no-op; it just marks the fact that the argument is being used.
2164         // But it may be profitable to use this as a hook to run speculation checks
2165         // on arguments, thereby allowing us to trivially eliminate such checks if
2166         // the argument is not used.
2167         recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
2168         break;
2169
2170     case BitAnd:
2171     case BitOr:
2172     case BitXor:
2173         compileBitwiseOp(node);
2174         break;
2175
2176     case BitRShift:
2177     case BitLShift:
2178     case BitURShift:
2179         compileShiftOp(node);
2180         break;
2181
2182     case UInt32ToNumber: {
2183         compileUInt32ToNumber(node);
2184         break;
2185     }
2186
2187     case DoubleAsInt32: {
2188         compileDoubleAsInt32(node);
2189         break;
2190     }
2191
2192     case ValueToInt32: {
2193         compileValueToInt32(node);
2194         break;
2195     }
2196         
2197     case DoubleRep: {
2198         compileDoubleRep(node);
2199         break;
2200     }
2201         
2202     case ValueRep: {
2203         compileValueRep(node);
2204         break;
2205     }
2206         
2207     case Int52Rep: {
2208         switch (node->child1().useKind()) {
2209         case Int32Use: {
2210             SpeculateInt32Operand operand(this, node->child1());
2211             GPRTemporary result(this, Reuse, operand);
2212             
2213             m_jit.signExtend32ToPtr(operand.gpr(), result.gpr());
2214             
2215             strictInt52Result(result.gpr(), node);
2216             break;
2217         }
2218             
2219         case AnyIntUse: {
2220             GPRTemporary result(this);
2221             GPRReg resultGPR = result.gpr();
2222             
2223             convertAnyInt(node->child1(), resultGPR);
2224             
2225             strictInt52Result(resultGPR, node);
2226             break;
2227         }
2228             
2229         case DoubleRepAnyIntUse: {
2230             SpeculateDoubleOperand value(this, node->child1());
2231             FPRReg valueFPR = value.fpr();
2232             
2233             flushRegisters();
2234             GPRFlushedCallResult result(this);
2235             GPRReg resultGPR = result.gpr();
2236             callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
2237             
2238             DFG_TYPE_CHECK_WITH_EXIT_KIND(Int52Overflow,
2239                 JSValueRegs(), node->child1(), SpecAnyIntAsDouble,
2240                 m_jit.branch64(
2241                     JITCompiler::Equal, resultGPR,
2242                     JITCompiler::TrustedImm64(JSValue::notInt52)));
2243             
2244             strictInt52Result(resultGPR, node);
2245             break;
2246         }
2247             
2248         default:
2249             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
2250         }
2251         break;
2252     }
2253
2254     case ValueAdd:
2255         compileValueAdd(node);
2256         break;
2257
2258     case StrCat: {
2259         compileStrCat(node);
2260         break;
2261     }
2262
2263     case ArithAdd:
2264         compileArithAdd(node);
2265         break;
2266
2267     case ArithClz32:
2268         compileArithClz32(node);
2269         break;
2270         
2271     case MakeRope:
2272         compileMakeRope(node);
2273         break;
2274
2275     case ArithSub:
2276         compileArithSub(node);
2277         break;
2278
2279     case ArithNegate:
2280         compileArithNegate(node);
2281         break;
2282
2283     case ArithMul:
2284         compileArithMul(node);
2285         break;
2286
2287     case ArithDiv: {
2288         compileArithDiv(node);
2289         break;
2290     }
2291
2292     case ArithMod: {
2293         compileArithMod(node);
2294         break;
2295     }
2296
2297     case ArithAbs:
2298         compileArithAbs(node);
2299         break;
2300         
2301     case ArithMin:
2302     case ArithMax: {
2303         compileArithMinMax(node);
2304         break;
2305     }
2306
2307     case ArithPow:
2308         compileArithPow(node);
2309         break;
2310
2311     case ArithSqrt:
2312         compileArithSqrt(node);
2313         break;
2314
2315     case ArithFRound:
2316         compileArithFRound(node);
2317         break;
2318
2319     case ArithRandom:
2320         compileArithRandom(node);
2321         break;
2322
2323     case ArithRound:
2324     case ArithFloor:
2325     case ArithCeil:
2326     case ArithTrunc:
2327         compileArithRounding(node);
2328         break;
2329
2330     case ArithUnary:
2331         compileArithUnary(node);
2332         break;
2333
2334     case LogicalNot:
2335         compileLogicalNot(node);
2336         break;
2337
2338     case CompareLess:
2339         if (compare(node, JITCompiler::LessThan, JITCompiler::DoubleLessThan, operationCompareLess))
2340             return;
2341         break;
2342
2343     case CompareLessEq:
2344         if (compare(node, JITCompiler::LessThanOrEqual, JITCompiler::DoubleLessThanOrEqual, operationCompareLessEq))
2345             return;
2346         break;
2347
2348     case CompareGreater:
2349         if (compare(node, JITCompiler::GreaterThan, JITCompiler::DoubleGreaterThan, operationCompareGreater))
2350             return;
2351         break;
2352
2353     case CompareGreaterEq:
2354         if (compare(node, JITCompiler::GreaterThanOrEqual, JITCompiler::DoubleGreaterThanOrEqual, operationCompareGreaterEq))
2355             return;
2356         break;
2357
2358     case CompareBelow:
2359         compileCompareUnsigned(node, JITCompiler::Below);
2360         break;
2361
2362     case CompareBelowEq:
2363         compileCompareUnsigned(node, JITCompiler::BelowOrEqual);
2364         break;
2365
2366     case CompareEq:
2367         if (compare(node, JITCompiler::Equal, JITCompiler::DoubleEqual, operationCompareEq))
2368             return;
2369         break;
2370
2371     case CompareStrictEq:
2372         if (compileStrictEq(node))
2373             return;
2374         break;
2375         
2376     case CompareEqPtr:
2377         compileCompareEqPtr(node);
2378         break;
2379
2380     case StringCharCodeAt: {
2381         compileGetCharCodeAt(node);
2382         break;
2383     }
2384
2385     case StringCharAt: {
2386         // Relies on StringCharAt node having same basic layout as GetByVal
2387         compileGetByValOnString(node);
2388         break;
2389     }
2390
2391     case StringFromCharCode: {
2392         compileFromCharCode(node);
2393         break;
2394     }
2395         
2396     case CheckArray: {
2397         checkArray(node);
2398         break;
2399     }
2400         
2401     case Arrayify:
2402     case ArrayifyToStructure: {
2403         arrayify(node);
2404         break;
2405     }
2406
2407     case GetByVal: {
2408         switch (node->arrayMode().type()) {
2409         case Array::SelectUsingPredictions:
2410         case Array::ForceExit:
2411             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
2412             break;
2413         case Array::Undecided: {
2414             SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 1));
2415             GPRTemporary result(this, Reuse, index);
2416             GPRReg indexGPR = index.gpr();
2417             GPRReg resultGPR = result.gpr();
2418
2419             speculationCheck(OutOfBounds, JSValueRegs(), node,
2420                 m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
2421
2422             use(m_graph.varArgChild(node, 0));
2423             index.use();
2424
2425             m_jit.move(MacroAssembler::TrustedImm64(ValueUndefined), resultGPR);
2426             jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
2427             break;
2428         }
2429         case Array::Generic: {
2430             if (m_graph.varArgChild(node, 0).useKind() == ObjectUse) {
2431                 if (m_graph.varArgChild(node, 1).useKind() == StringUse) {
2432                     compileGetByValForObjectWithString(node);
2433                     break;
2434                 }
2435
2436                 if (m_graph.varArgChild(node, 1).useKind() == SymbolUse) {
2437                     compileGetByValForObjectWithSymbol(node);
2438                     break;
2439                 }
2440             }
2441             JSValueOperand base(this, m_graph.varArgChild(node, 0));
2442             JSValueOperand property(this, m_graph.varArgChild(node, 1));
2443             GPRReg baseGPR = base.gpr();
2444             GPRReg propertyGPR = property.gpr();
2445             
2446             flushRegisters();
2447             GPRFlushedCallResult result(this);
2448             callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR);
2449             m_jit.exceptionCheck();
2450             
2451             jsValueResult(result.gpr(), node);
2452             break;
2453         }
2454         case Array::Int32:
2455         case Array::Contiguous: {
2456             if (node->arrayMode().isInBounds()) {
2457                 SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2458                 StorageOperand storage(this, m_graph.varArgChild(node, 2));
2459
2460                 GPRReg propertyReg = property.gpr();
2461                 GPRReg storageReg = storage.gpr();
2462
2463                 if (!m_compileOkay)
2464                     return;
2465                 
2466                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2467                 
2468                 GPRTemporary result(this);
2469
2470                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.gpr());
2471                 if (node->arrayMode().isSaneChain()) {
2472                     ASSERT(node->arrayMode().type() == Array::Contiguous);
2473                     JITCompiler::Jump notHole = m_jit.branchTest64(
2474                         MacroAssembler::NonZero, result.gpr());
2475                     m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), result.gpr());
2476                     notHole.link(&m_jit);
2477                 } else {
2478                     speculationCheck(
2479                         LoadFromHole, JSValueRegs(), 0,
2480                         m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
2481                 }
2482                 jsValueResult(result.gpr(), node, node->arrayMode().type() == Array::Int32 ? DataFormatJSInt32 : DataFormatJS);
2483                 break;
2484             }
2485             
2486             SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
2487             SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2488             StorageOperand storage(this, m_graph.varArgChild(node, 2));
2489             
2490             GPRReg baseReg = base.gpr();
2491             GPRReg propertyReg = property.gpr();
2492             GPRReg storageReg = storage.gpr();
2493             
2494             if (!m_compileOkay)
2495                 return;
2496             
2497             GPRTemporary result(this);
2498             GPRReg resultReg = result.gpr();
2499             
2500             MacroAssembler::JumpList slowCases;
2501             
2502             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2503
2504             m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2505             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
2506             
2507             addSlowPathGenerator(
2508                 slowPathCall(
2509                     slowCases, this, operationGetByValObjectInt,
2510                     result.gpr(), baseReg, propertyReg));
2511             
2512             jsValueResult(resultReg, node);
2513             break;
2514         }
2515
2516         case Array::Double: {
2517             if (node->arrayMode().isInBounds()) {
2518                 SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2519                 StorageOperand storage(this, m_graph.varArgChild(node, 2));
2520
2521                 GPRReg propertyReg = property.gpr();
2522                 GPRReg storageReg = storage.gpr();
2523
2524                 if (!m_compileOkay)
2525                     return;
2526
2527                 FPRTemporary result(this);
2528                 FPRReg resultReg = result.fpr();
2529
2530                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2531
2532                 m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2533                 if (!node->arrayMode().isSaneChain())
2534                     speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, resultReg, resultReg));
2535                 doubleResult(resultReg, node);
2536                 break;
2537             }
2538
2539             SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
2540             SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2541             StorageOperand storage(this, m_graph.varArgChild(node, 2));
2542             
2543             GPRReg baseReg = base.gpr();
2544             GPRReg propertyReg = property.gpr();
2545             GPRReg storageReg = storage.gpr();
2546             
2547             if (!m_compileOkay)
2548                 return;
2549             
2550             GPRTemporary result(this);
2551             FPRTemporary temp(this);
2552             GPRReg resultReg = result.gpr();
2553             FPRReg tempReg = temp.fpr();
2554             
2555             MacroAssembler::JumpList slowCases;
2556             
2557             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2558
2559             m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), tempReg);
2560             slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempReg, tempReg));
2561             boxDouble(tempReg, resultReg);
2562             
2563             addSlowPathGenerator(
2564                 slowPathCall(
2565                     slowCases, this, operationGetByValObjectInt,
2566                     result.gpr(), baseReg, propertyReg));
2567             
2568             jsValueResult(resultReg, node);
2569             break;
2570         }
2571
2572         case Array::ArrayStorage:
2573         case Array::SlowPutArrayStorage: {
2574             if (node->arrayMode().isInBounds()) {
2575                 SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2576                 StorageOperand storage(this, m_graph.varArgChild(node, 2));
2577             
2578                 GPRReg propertyReg = property.gpr();
2579                 GPRReg storageReg = storage.gpr();
2580             
2581                 if (!m_compileOkay)
2582                     return;
2583             
2584                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2585             
2586                 GPRTemporary result(this);
2587                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), result.gpr());
2588                 speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
2589             
2590                 jsValueResult(result.gpr(), node);
2591                 break;
2592             }
2593
2594             SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
2595             SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2596             StorageOperand storage(this, m_graph.varArgChild(node, 2));
2597             
2598             GPRReg baseReg = base.gpr();
2599             GPRReg propertyReg = property.gpr();
2600             GPRReg storageReg = storage.gpr();
2601             
2602             if (!m_compileOkay)
2603                 return;
2604             
2605             GPRTemporary result(this);
2606             GPRReg resultReg = result.gpr();
2607             
2608             MacroAssembler::JumpList slowCases;
2609             
2610             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2611     
2612             m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), resultReg);
2613             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
2614     
2615             addSlowPathGenerator(
2616                 slowPathCall(
2617                     slowCases, this, operationGetByValObjectInt,
2618                     result.gpr(), baseReg, propertyReg));
2619             
2620             jsValueResult(resultReg, node);
2621             break;
2622         }
2623         case Array::String:
2624             compileGetByValOnString(node);
2625             break;
2626         case Array::DirectArguments:
2627             compileGetByValOnDirectArguments(node);
2628             break;
2629         case Array::ScopedArguments:
2630             compileGetByValOnScopedArguments(node);
2631             break;
2632         default: {
2633             TypedArrayType type = node->arrayMode().typedArrayType();
2634             if (isInt(type))
2635                 compileGetByValOnIntTypedArray(node, type);
2636             else
2637                 compileGetByValOnFloatTypedArray(node, type);
2638         } }
2639         break;
2640     }
2641
2642     case GetByValWithThis: {
2643         compileGetByValWithThis(node);
2644         break;
2645     }
2646
2647     case PutByValDirect:
2648     case PutByVal:
2649     case PutByValAlias: {
2650         Edge child1 = m_jit.graph().varArgChild(node, 0);
2651         Edge child2 = m_jit.graph().varArgChild(node, 1);
2652         Edge child3 = m_jit.graph().varArgChild(node, 2);
2653         Edge child4 = m_jit.graph().varArgChild(node, 3);
2654         
2655         ArrayMode arrayMode = node->arrayMode().modeForPut();
2656         bool alreadyHandled = false;
2657         
2658         switch (arrayMode.type()) {
2659         case Array::SelectUsingPredictions:
2660         case Array::ForceExit:
2661             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
2662             break;
2663         case Array::Generic: {
2664             DFG_ASSERT(m_jit.graph(), node, node->op() == PutByVal || node->op() == PutByValDirect, node->op());
2665
2666             if (child1.useKind() == CellUse) {
2667                 if (child2.useKind() == StringUse) {
2668                     compilePutByValForCellWithString(node, child1, child2, child3);
2669                     alreadyHandled = true;
2670                     break;
2671                 }
2672
2673                 if (child2.useKind() == SymbolUse) {
2674                     compilePutByValForCellWithSymbol(node, child1, child2, child3);
2675                     alreadyHandled = true;
2676                     break;
2677                 }
2678             }
2679             
2680             JSValueOperand arg1(this, child1);
2681             JSValueOperand arg2(this, child2);
2682             JSValueOperand arg3(this, child3);
2683             GPRReg arg1GPR = arg1.gpr();
2684             GPRReg arg2GPR = arg2.gpr();
2685             GPRReg arg3GPR = arg3.gpr();
2686             flushRegisters();
2687             if (node->op() == PutByValDirect)
2688                 callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValDirectStrict : operationPutByValDirectNonStrict, arg1GPR, arg2GPR, arg3GPR);
2689             else
2690                 callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
2691             m_jit.exceptionCheck();
2692             
2693             noResult(node);
2694             alreadyHandled = true;
2695             break;
2696         }
2697         default:
2698             break;
2699         }
2700         
2701         if (alreadyHandled)
2702             break;
2703
2704         SpeculateCellOperand base(this, child1);
2705         SpeculateStrictInt32Operand property(this, child2);
2706         
2707         GPRReg baseReg = base.gpr();
2708         GPRReg propertyReg = property.gpr();
2709
2710         switch (arrayMode.type()) {
2711         case Array::Int32:
2712         case Array::Contiguous: {
2713             JSValueOperand value(this, child3, ManualOperandSpeculation);
2714
2715             GPRReg valueReg = value.gpr();
2716         
2717             if (!m_compileOkay)
2718                 return;
2719             
2720             if (arrayMode.type() == Array::Int32) {
2721                 DFG_TYPE_CHECK(
2722                     JSValueRegs(valueReg), child3, SpecInt32Only,
2723                     m_jit.branch64(
2724                         MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
2725             }
2726
2727             StorageOperand storage(this, child4);
2728             GPRReg storageReg = storage.gpr();
2729
2730             if (node->op() == PutByValAlias) {
2731                 // Store the value to the array.
2732                 GPRReg propertyReg = property.gpr();
2733                 GPRReg valueReg = value.gpr();
2734                 m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
2735                 
2736                 noResult(node);
2737                 break;
2738             }
2739             
2740             GPRTemporary temporary;
2741             GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
2742
2743             MacroAssembler::Jump slowCase;
2744             
2745             if (arrayMode.isInBounds()) {
2746                 speculationCheck(
2747                     OutOfBounds, JSValueRegs(), 0,
2748                     m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2749             } else {
2750                 MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2751                 
2752                 slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
2753                 
2754                 if (!arrayMode.isOutOfBounds())
2755                     speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
2756                 
2757                 m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
2758                 m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2759
2760                 inBounds.link(&m_jit);
2761             }
2762
2763             m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
2764
2765             base.use();
2766             property.use();
2767             value.use();
2768             storage.use();
2769             
2770             if (arrayMode.isOutOfBounds()) {
2771                 addSlowPathGenerator(slowPathCall(
2772                     slowCase, this,
2773                     m_jit.codeBlock()->isStrictMode()
2774                         ? (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsStrict)
2775                         : (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsNonStrict : operationPutByValBeyondArrayBoundsNonStrict),
2776                     NoResult, baseReg, propertyReg, valueReg));
2777             }
2778
2779             noResult(node, UseChildrenCalledExplicitly);
2780             break;
2781         }
2782             
2783         case Array::Double: {
2784             compileDoublePutByVal(node, base, property);
2785             break;
2786         }
2787             
2788         case Array::ArrayStorage:
2789         case Array::SlowPutArrayStorage: {
2790             JSValueOperand value(this, child3);
2791
2792             GPRReg valueReg = value.gpr();
2793         
2794             if (!m_compileOkay)
2795                 return;
2796
2797             StorageOperand storage(this, child4);
2798             GPRReg storageReg = storage.gpr();
2799
2800             if (node->op() == PutByValAlias) {
2801                 // Store the value to the array.
2802                 GPRReg propertyReg = property.gpr();
2803                 GPRReg valueReg = value.gpr();
2804                 m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
2805                 
2806                 noResult(node);
2807                 break;
2808             }
2809             
2810             GPRTemporary temporary;
2811             GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
2812
2813             MacroAssembler::JumpList slowCases;
2814
2815             MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
2816             if (!arrayMode.isOutOfBounds())
2817                 speculationCheck(OutOfBounds, JSValueRegs(), 0, beyondArrayBounds);
2818             else
2819                 slowCases.append(beyondArrayBounds);
2820
2821             // Check if we're writing to a hole; if so increment m_numValuesInVector.
2822             if (arrayMode.isInBounds()) {
2823                 speculationCheck(
2824                     StoreToHole, JSValueRegs(), 0,
2825                     m_jit.branchTest64(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset())));
2826             } else {
2827                 MacroAssembler::Jump notHoleValue = m_jit.branchTest64(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
2828                 if (arrayMode.isSlowPut()) {
2829                     // This is sort of strange. If we wanted to optimize this code path, we would invert
2830                     // the above branch. But it's simply not worth it since this only happens if we're
2831                     // already having a bad time.
2832                     slowCases.append(m_jit.jump());
2833                 } else {
2834                     m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
2835                 
2836                     // If we're writing to a hole we might be growing the array; 
2837                     MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2838                     m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
2839                     m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2840                 
2841                     lengthDoesNotNeedUpdate.link(&m_jit);
2842                 }
2843                 notHoleValue.link(&m_jit);
2844             }
2845     
2846             // Store the value to the array.
2847             m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
2848
2849             base.use();
2850             property.use();
2851             value.use();
2852             storage.use();
2853             
2854             if (!slowCases.empty()) {
2855                 addSlowPathGenerator(slowPathCall(
2856                     slowCases, this,
2857                     m_jit.codeBlock()->isStrictMode()
2858                         ? (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsStrict)
2859                         : (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsNonStrict : operationPutByValBeyondArrayBoundsNonStrict),
2860                     NoResult, baseReg, propertyReg, valueReg));
2861             }
2862
2863             noResult(node, UseChildrenCalledExplicitly);
2864             break;
2865         }
2866             
2867         default: {
2868             TypedArrayType type = arrayMode.typedArrayType();
2869             if (isInt(type))
2870                 compilePutByValForIntTypedArray(base.gpr(), property.gpr(), node, type);
2871             else
2872                 compilePutByValForFloatTypedArray(base.gpr(), property.gpr(), node, type);
2873         } }
2874
2875         break;
2876     }
2877         
2878     case AtomicsAdd:
2879     case AtomicsAnd:
2880     case AtomicsCompareExchange:
2881     case AtomicsExchange:
2882     case AtomicsLoad:
2883     case AtomicsOr:
2884     case AtomicsStore:
2885     case AtomicsSub:
2886     case AtomicsXor: {
2887         unsigned numExtraArgs = numExtraAtomicsArgs(node->op());
2888         Edge baseEdge = m_jit.graph().child(node, 0);
2889         Edge indexEdge = m_jit.graph().child(node, 1);
2890         Edge argEdges[maxNumExtraAtomicsArgs];
2891         for (unsigned i = numExtraArgs; i--;)
2892             argEdges[i] = m_jit.graph().child(node, 2 + i);
2893         Edge storageEdge = m_jit.graph().child(node, 2 + numExtraArgs);
2894
2895         GPRReg baseGPR;
2896         GPRReg indexGPR;
2897         GPRReg argGPRs[2];
2898         GPRReg resultGPR;
2899
2900         auto callSlowPath = [&] () {
2901             switch (node->op()) {
2902             case AtomicsAdd:
2903                 callOperation(operationAtomicsAdd, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2904                 break;
2905             case AtomicsAnd:
2906                 callOperation(operationAtomicsAnd, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2907                 break;
2908             case AtomicsCompareExchange:
2909                 callOperation(operationAtomicsCompareExchange, resultGPR, baseGPR, indexGPR, argGPRs[0], argGPRs[1]);
2910                 break;
2911             case AtomicsExchange:
2912                 callOperation(operationAtomicsExchange, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2913                 break;
2914             case AtomicsLoad:
2915                 callOperation(operationAtomicsLoad, resultGPR, baseGPR, indexGPR);
2916                 break;
2917             case AtomicsOr:
2918                 callOperation(operationAtomicsOr, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2919                 break;
2920             case AtomicsStore:
2921                 callOperation(operationAtomicsStore, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2922                 break;
2923             case AtomicsSub:
2924                 callOperation(operationAtomicsSub, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2925                 break;
2926             case AtomicsXor:
2927                 callOperation(operationAtomicsXor, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2928                 break;
2929             default:
2930                 RELEASE_ASSERT_NOT_REACHED();
2931                 break;
2932             }
2933         };
2934         
2935         if (!storageEdge) {
2936             // We are in generic mode!
2937             JSValueOperand base(this, baseEdge);
2938             JSValueOperand index(this, indexEdge);
2939             std::optional<JSValueOperand> args[2];
2940             baseGPR = base.gpr();
2941             indexGPR = index.gpr();
2942             for (unsigned i = numExtraArgs; i--;) {
2943                 args[i].emplace(this, argEdges[i]);
2944                 argGPRs[i] = args[i]->gpr();
2945             }
2946             
2947             flushRegisters();
2948             GPRFlushedCallResult result(this);
2949             resultGPR = result.gpr();
2950             callSlowPath();
2951             m_jit.exceptionCheck();
2952             
2953             jsValueResult(resultGPR, node);
2954             break;
2955         }
2956         
2957         TypedArrayType type = node->arrayMode().typedArrayType();
2958         
2959         SpeculateCellOperand base(this, baseEdge);
2960         SpeculateStrictInt32Operand index(this, indexEdge);
2961
2962         baseGPR = base.gpr();
2963         indexGPR = index.gpr();
2964         
2965         emitTypedArrayBoundsCheck(node, baseGPR, indexGPR);
2966         
2967         GPRTemporary args[2];
2968         
2969         JITCompiler::JumpList slowPathCases;
2970         
2971         bool ok = true;
2972         for (unsigned i = numExtraArgs; i--;) {
2973             if (!getIntTypedArrayStoreOperand(args[i], indexGPR, argEdges[i], slowPathCases)) {
2974                 noResult(node);
2975                 ok = false;
2976             }
2977             argGPRs[i] = args[i].gpr();
2978         }
2979         if (!ok)
2980             break;
2981         
2982         StorageOperand storage(this, storageEdge);
2983         GPRTemporary oldValue(this);
2984         GPRTemporary result(this);
2985         GPRTemporary newValue(this);
2986         GPRReg storageGPR = storage.gpr();
2987         GPRReg oldValueGPR = oldValue.gpr();
2988         resultGPR = result.gpr();
2989         GPRReg newValueGPR = newValue.gpr();
2990         
2991         // FIXME: It shouldn't be necessary to nop-pad between register allocation and a jump label.
2992         // https://bugs.webkit.org/show_bug.cgi?id=170974
2993         m_jit.nop();
2994         
2995         JITCompiler::Label loop = m_jit.label();
2996         
2997         loadFromIntTypedArray(storageGPR, indexGPR, oldValueGPR, type);
2998         m_jit.move(oldValueGPR, newValueGPR);
2999         m_jit.move(oldValueGPR, resultGPR);
3000         
3001         switch (node->op()) {
3002         case AtomicsAdd:
3003             m_jit.add32(argGPRs[0], newValueGPR);
3004             break;
3005         case AtomicsAnd:
3006             m_jit.and32(argGPRs[0], newValueGPR);
3007             break;
3008         case AtomicsCompareExchange: {
3009             switch (elementSize(type)) {
3010             case 1:
3011                 if (isSigned(type))
3012                     m_jit.signExtend8To32(argGPRs[0], argGPRs[0]);
3013                 else
3014                     m_jit.and32(TrustedImm32(0xff), argGPRs[0]);
3015                 break;
3016             case 2:
3017                 if (isSigned(type))
3018                     m_jit.signExtend16To32(argGPRs[0], argGPRs[0]);
3019                 else
3020                     m_jit.and32(TrustedImm32(0xffff), argGPRs[0]);
3021                 break;
3022             case 4:
3023                 break;
3024             default:
3025                 RELEASE_ASSERT_NOT_REACHED();
3026                 break;
3027             }
3028             JITCompiler::Jump fail = m_jit.branch32(JITCompiler::NotEqual, oldValueGPR, argGPRs[0]);
3029             m_jit.move(argGPRs[1], newValueGPR);
3030             fail.link(&m_jit);
3031             break;
3032         }
3033         case AtomicsExchange:
3034             m_jit.move(argGPRs[0], newValueGPR);
3035             break;
3036         case AtomicsLoad:
3037             break;
3038         case AtomicsOr:
3039             m_jit.or32(argGPRs[0], newValueGPR);
3040             break;
3041         case AtomicsStore:
3042             m_jit.move(argGPRs[0], newValueGPR);
3043             m_jit.move(argGPRs[0], resultGPR);
3044             break;
3045         case AtomicsSub:
3046             m_jit.sub32(argGPRs[0], newValueGPR);
3047             break;
3048         case AtomicsXor:
3049             m_jit.xor32(argGPRs[0], newValueGPR);
3050             break;
3051         default:
3052             RELEASE_ASSERT_NOT_REACHED();
3053             break;
3054         }
3055         
3056         JITCompiler::JumpList success;
3057         switch (elementSize(type)) {
3058         case 1:
3059             success = m_jit.branchAtomicWeakCAS8(JITCompiler::Success, oldValueGPR, newValueGPR, JITCompiler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesOne));
3060             break;
3061         case 2:
3062             success = m_jit.branchAtomicWeakCAS16(JITCompiler::Success, oldValueGPR, newValueGPR, JITCompiler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesTwo));
3063             break;
3064         case 4:
3065             success = m_jit.branchAtomicWeakCAS32(JITCompiler::Success, oldValueGPR, newValueGPR, JITCompiler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesFour));
3066             break;
3067         default:
3068             RELEASE_ASSERT_NOT_REACHED();
3069             break;
3070         }
3071         m_jit.jump().linkTo(loop, &m_jit);
3072         
3073         if (!slowPathCases.empty()) {
3074             slowPathCases.link(&m_jit);
3075             silentSpillAllRegisters(resultGPR);
3076             // Since we spilled, we can do things to registers.
3077             m_jit.boxCell(baseGPR, JSValueRegs(baseGPR));
3078             m_jit.boxInt32(indexGPR, JSValueRegs(indexGPR));
3079             for (unsigned i = numExtraArgs; i--;)
3080                 m_jit.boxInt32(argGPRs[i], JSValueRegs(argGPRs[i]));
3081             callSlowPath();
3082             silentFillAllRegisters();
3083             m_jit.exceptionCheck();
3084         }
3085         
3086         success.link(&m_jit);
3087         setIntTypedArrayLoadResult(node, resultGPR, type);
3088         break;
3089     }
3090         
3091     case AtomicsIsLockFree: {
3092         if (node->child1().useKind() != Int32Use) {
3093             JSValueOperand operand(this, node->child1());
3094             GPRReg operandGPR = operand.gpr();
3095             flushRegisters();
3096             GPRFlushedCallResult result(this);
3097             GPRReg resultGPR = result.gpr();
3098             callOperation(operationAtomicsIsLockFree, resultGPR, operandGPR);
3099             m_jit.exceptionCheck();
3100             jsValueResult(resultGPR, node);
3101             break;
3102         }
3103
3104         SpeculateInt32Operand operand(this, node->child1());
3105         GPRTemporary result(this);
3106         GPRReg operandGPR = operand.gpr();
3107         GPRReg resultGPR = result.gpr();
3108         m_jit.move(TrustedImm32(ValueTrue), resultGPR);
3109         JITCompiler::JumpList done;
3110         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(4)));
3111         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(1)));
3112         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(2)));
3113         m_jit.move(TrustedImm32(ValueFalse), resultGPR);
3114         done.link(&m_jit);
3115         jsValueResult(resultGPR, node);
3116         break;
3117     }
3118
3119     case RegExpExec: {
3120         compileRegExpExec(node);
3121         break;
3122     }
3123
3124     case RegExpExecNonGlobalOrSticky: {
3125         compileRegExpExecNonGlobalOrSticky(node);
3126         break;
3127     }
3128
3129     case RegExpMatchFastGlobal: {
3130         compileRegExpMatchFastGlobal(node);
3131         break;
3132     }
3133
3134     case RegExpTest: {
3135         compileRegExpTest(node);
3136         break;
3137     }
3138
3139     case RegExpMatchFast: {
3140         compileRegExpMatchFast(node);
3141         break;
3142     }
3143
3144     case StringReplace:
3145     case StringReplaceRegExp: {
3146         compileStringReplace(node);
3147         break;
3148     }
3149         
3150     case GetRegExpObjectLastIndex: {
3151         compileGetRegExpObjectLastIndex(node);
3152         break;
3153     }
3154         
3155     case SetRegExpObjectLastIndex: {
3156         compileSetRegExpObjectLastIndex(node);
3157         break;
3158     }
3159
3160     case RecordRegExpCachedResult: {
3161         compileRecordRegExpCachedResult(node);
3162         break;
3163     }
3164         
3165     case ArrayPush: {
3166         compileArrayPush(node);
3167         break;
3168     }
3169
3170     case ArraySlice: {
3171         compileArraySlice(node);
3172         break;
3173     }
3174
3175     case ArrayIndexOf: {
3176         compileArrayIndexOf(node);
3177         break;
3178     }
3179         
3180     case ArrayPop: {
3181         ASSERT(node->arrayMode().isJSArray());
3182
3183         SpeculateCellOperand base(this, node->child1());
3184         StorageOperand storage(this, node->child2());
3185         GPRTemporary value(this);
3186         GPRTemporary storageLength(this);
3187         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().
3188         
3189         GPRReg baseGPR = base.gpr();
3190         GPRReg storageGPR = storage.gpr();
3191         GPRReg valueGPR = value.gpr();
3192         GPRReg storageLengthGPR = storageLength.gpr();
3193         FPRReg tempFPR = temp.fpr();
3194         
3195         switch (node->arrayMode().type()) {
3196         case Array::Int32:
3197         case Array::Double:
3198         case Array::Contiguous: {
3199             m_jit.load32(
3200                 MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()), storageLengthGPR);
3201             MacroAssembler::Jump undefinedCase =
3202                 m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
3203             m_jit.sub32(TrustedImm32(1), storageLengthGPR);
3204             m_jit.store32(
3205                 storageLengthGPR, MacroAssembler::Address(storageGPR, Butterfly::offsetOfPublicLength()));
3206             MacroAssembler::Jump slowCase;
3207             if (node->arrayMode().type() == Array::Double) {
3208                 m_jit.loadDouble(
3209                     MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight),
3210                     tempFPR);
3211                 // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old
3212                 // length and the new length.
3213                 m_jit.store64(
3214                     MacroAssembler::TrustedImm64(bitwise_cast<int64_t>(PNaN)), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3215                 slowCase = m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempFPR, tempFPR);
3216                 boxDouble(tempFPR, valueGPR);
3217             } else {
3218                 m_jit.load64(
3219                     MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight),
3220                     valueGPR);
3221                 // FIXME: This would not have to be here if changing the publicLength also zeroed the values between the old
3222                 // length and the new length.
3223                 m_jit.store64(
3224                 MacroAssembler::TrustedImm64((int64_t)0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight));
3225                 slowCase = m_jit.branchTest64(MacroAssembler::Zero, valueGPR);
3226             }
3227
3228             addSlowPathGenerator(
3229                 slowPathMove(
3230                     undefinedCase, this,
3231                     MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), valueGPR));
3232             addSlowPathGenerator(
3233                 slowPathCall(
3234                     slowCase, this, operationArrayPopAndRecoverLength, valueGPR, baseGPR));
3235             
3236             // We can't know for sure that the result is an int because of the slow paths. :-/
3237             jsValueResult(valueGPR, node);
3238             break;
3239         }
3240             
3241         case Array::ArrayStorage: {
3242             m_jit.load32(MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()), storageLengthGPR);
3243         
3244             JITCompiler::Jump undefinedCase =
3245                 m_jit.branchTest32(MacroAssembler::Zero, storageLengthGPR);
3246         
3247             m_jit.sub32(TrustedImm32(1), storageLengthGPR);
3248         
3249             JITCompiler::JumpList slowCases;
3250             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset())));
3251         
3252             m_jit.load64(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), valueGPR);
3253             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, valueGPR));
3254         
3255             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
3256         
3257             m_jit.store64(MacroAssembler::TrustedImm64((int64_t)0), MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight,  ArrayStorage::vectorOffset()));
3258             m_jit.sub32(MacroAssembler::TrustedImm32(1), MacroAssembler::Address(storageGPR, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
3259         
3260             addSlowPathGenerator(
3261                 slowPathMove(
3262                     undefinedCase, this,
3263                     MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), valueGPR));
3264         
3265             addSlowPathGenerator(
3266                 slowPathCall(
3267                     slowCases, this, operationArrayPop, valueGPR, baseGPR));
3268
3269             jsValueResult(valueGPR, node);
3270             break;
3271         }
3272             
3273         default:
3274             CRASH();
3275             break;
3276         }
3277         break;
3278     }
3279
3280     case DFG::Jump: {
3281         jump(node->targetBlock());
3282         noResult(node);
3283         break;
3284     }
3285
3286     case Branch:
3287         emitBranch(node);
3288         break;
3289         
3290     case Switch:
3291         emitSwitch(node);
3292         break;
3293
3294     case Return: {
3295         ASSERT(GPRInfo::callFrameRegister != GPRInfo::regT1);
3296         ASSERT(GPRInfo::regT1 != GPRInfo::returnValueGPR);
3297         ASSERT(GPRInfo::returnValueGPR != GPRInfo::callFrameRegister);
3298
3299         // Return the result in returnValueGPR.
3300         JSValueOperand op1(this, node->child1());
3301         m_jit.move(op1.gpr(), GPRInfo::returnValueGPR);
3302
3303         m_jit.emitRestoreCalleeSaves();
3304         m_jit.emitFunctionEpilogue();
3305         m_jit.ret();
3306         
3307         noResult(node);
3308         break;
3309     }
3310         
3311     case Throw: {
3312         compileThrow(node);
3313         break;
3314     }
3315
3316     case ThrowStaticError: {
3317         compileThrowStaticError(node);
3318         break;
3319     }
3320         
3321     case BooleanToNumber: {
3322         switch (node->child1().useKind()) {
3323         case BooleanUse: {
3324             JSValueOperand value(this, node->child1(), ManualOperandSpeculation);
3325             GPRTemporary result(this); // FIXME: We could reuse, but on speculation fail would need recovery to restore tag (akin to add).
3326             
3327             m_jit.move(value.gpr(), result.gpr());
3328             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
3329             DFG_TYPE_CHECK(
3330                 JSValueRegs(value.gpr()), node->child1(), SpecBoolean, m_jit.branchTest64(
3331                     JITCompiler::NonZero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1))));
3332
3333             int32Result(result.gpr(), node);
3334             break;
3335         }
3336             
3337         case UntypedUse: {
3338             JSValueOperand value(this, node->child1());
3339             GPRTemporary result(this);
3340             
3341             if (!m_interpreter.needsTypeCheck(node->child1(), SpecBoolInt32 | SpecBoolean)) {
3342                 m_jit.move(value.gpr(), result.gpr());
3343                 m_jit.and32(TrustedImm32(1), result.gpr());
3344                 int32Result(result.gpr(), node);
3345                 break;
3346             }
3347             
3348             m_jit.move(value.gpr(), result.gpr());
3349             m_jit.xor64(TrustedImm32(static_cast<int32_t>(ValueFalse)), result.gpr());
3350             JITCompiler::Jump isBoolean = m_jit.branchTest64(
3351                 JITCompiler::Zero, result.gpr(), TrustedImm32(static_cast<int32_t>(~1)));
3352             m_jit.move(value.gpr(), result.gpr());
3353             JITCompiler::Jump done = m_jit.jump();
3354             isBoolean.link(&m_jit);
3355             m_jit.or64(GPRInfo::tagTypeNumberRegister, result.gpr());
3356             done.link(&m_jit);
3357             
3358             jsValueResult(result.gpr(), node);
3359             break;
3360         }
3361             
3362         default:
3363             DFG_CRASH(m_jit.graph(), node, "Bad use kind");
3364             break;
3365         }
3366         break;
3367     }
3368         
3369     case ToPrimitive: {
3370         compileToPrimitive(node);
3371         break;
3372     }
3373
3374     case ToNumber: {
3375         JSValueOperand argument(this, node->child1());
3376         GPRTemporary result(this, Reuse, argument);
3377
3378         GPRReg argumentGPR = argument.gpr();
3379         GPRReg resultGPR = result.gpr();
3380
3381         argument.use();
3382
3383         // We have several attempts to remove ToNumber. But ToNumber still exists.
3384         // It means that converting non-numbers to numbers by this ToNumber is not rare.
3385         // Instead of the slow path generator, we emit callOperation here.
3386         if (!(m_state.forNode(node->child1()).m_type & SpecBytecodeNumber)) {
3387             flushRegisters();
3388             callOperation(operationToNumber, resultGPR, argumentGPR);
3389             m_jit.exceptionCheck();
3390         } else {
3391             MacroAssembler::Jump notNumber = m_jit.branchIfNotNumber(argumentGPR);
3392             m_jit.move(argumentGPR, resultGPR);
3393             MacroAssembler::Jump done = m_jit.jump();
3394
3395             notNumber.link(&m_jit);
3396             silentSpillAllRegisters(resultGPR);
3397             callOperation(operationToNumber, resultGPR, argumentGPR);
3398             silentFillAllRegisters();
3399             m_jit.exceptionCheck();
3400
3401             done.link(&m_jit);
3402         }
3403
3404         jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
3405         break;
3406     }
3407         
3408     case ToString:
3409     case CallStringConstructor: {
3410         compileToStringOrCallStringConstructor(node);
3411         break;
3412     }
3413         
3414     case NewStringObject: {
3415         compileNewStringObject(node);
3416         break;
3417     }
3418         
3419     case NewArray: {
3420         compileNewArray(node);
3421         break;
3422     }
3423
3424     case NewArrayWithSpread: {
3425         compileNewArrayWithSpread(node);
3426         break;
3427     }
3428
3429     case Spread: {
3430         compileSpread(node);
3431         break;
3432     }
3433         
3434     case NewArrayWithSize: {
3435         compileNewArrayWithSize(node);
3436         break;
3437     }
3438         
3439     case NewArrayBuffer: {
3440         compileNewArrayBuffer(node);
3441         break;
3442     }
3443         
3444     case NewTypedArray: {
3445         compileNewTypedArray(node);
3446         break;
3447     }
3448         
3449     case NewRegexp: {
3450         compileNewRegexp(node);
3451         break;
3452     }
3453
3454     case ToObject:
3455     case CallObjectConstructor: {
3456         compileToObjectOrCallObjectConstructor(node);
3457         break;
3458     }
3459
3460     case ToThis: {
3461         compileToThis(node);
3462         break;
3463     }
3464
3465     case CreateThis: {
3466         compileCreateThis(node);
3467         break;
3468     }
3469         
3470     case NewObject: {
3471         compileNewObject(node);
3472         break;
3473     }
3474
3475     case GetCallee: {
3476         compileGetCallee(node);
3477         break;
3478     }
3479         
3480     case GetArgumentCountIncludingThis: {
3481         compileGetArgumentCountIncludingThis(node);
3482         break;
3483     }
3484
3485     case SetArgumentCountIncludingThis:
3486         compileSetArgumentCountIncludingThis(node);
3487         break;
3488
3489     case GetRestLength: {
3490         compileGetRestLength(node);
3491         break;
3492     }
3493         
3494     case GetScope:
3495         compileGetScope(node);
3496         break;
3497             
3498     case SkipScope:
3499         compileSkipScope(node);
3500         break;
3501
3502     case GetGlobalObject:
3503         compileGetGlobalObject(node);
3504         break;
3505
3506     case GetGlobalThis:
3507         compileGetGlobalThis(node);
3508         break;
3509         
3510     case GetClosureVar: {
3511         compileGetClosureVar(node);
3512         break;
3513     }
3514     case PutClosureVar: {
3515         compilePutClosureVar(node);
3516         break;
3517     }
3518
3519     case TryGetById: {
3520         compileGetById(node, AccessType::TryGet);
3521         break;
3522     }
3523
3524     case GetByIdDirect: {
3525         compileGetById(node, AccessType::GetDirect);
3526         break;
3527     }
3528
3529     case GetByIdDirectFlush: {
3530         compileGetByIdFlush(node, AccessType::GetDirect);
3531         break;
3532     }
3533
3534     case GetById: {
3535         compileGetById(node, AccessType::Get);
3536         break;
3537     }
3538
3539     case GetByIdFlush: {
3540         compileGetByIdFlush(node, AccessType::Get);
3541         break;
3542     }
3543
3544     case GetByIdWithThis: {
3545         if (node->child1().useKind() == CellUse && node->child2().useKind() == CellUse) {
3546             SpeculateCellOperand base(this, node->child1());
3547             GPRReg baseGPR = base.gpr();
3548             SpeculateCellOperand thisValue(this, node->child2());
3549             GPRReg thisValueGPR = thisValue.gpr();
3550             
3551             GPRFlushedCallResult result(this);
3552             GPRReg resultGPR = result.gpr();
3553             
3554             flushRegisters();
3555             
3556             cachedGetByIdWithThis(node->origin.semantic, baseGPR, thisValueGPR, resultGPR, node->identifierNumber(), JITCompiler::JumpList());
3557             
3558             jsValueResult(resultGPR, node);
3559             
3560         } else {
3561             JSValueOperand base(this, node->child1());
3562             GPRReg baseGPR = base.gpr();
3563             JSValueOperand thisValue(this, node->child2());
3564             GPRReg thisValueGPR = thisValue.gpr();
3565             
3566             GPRFlushedCallResult result(this);
3567             GPRReg resultGPR = result.gpr();
3568             
3569             flushRegisters();
3570             
3571             JITCompiler::JumpList notCellList;
3572             notCellList.append(m_jit.branchIfNotCell(JSValueRegs(baseGPR)));
3573             notCellList.append(m_jit.branchIfNotCell(JSValueRegs(thisValueGPR)));
3574             
3575             cachedGetByIdWithThis(node->origin.semantic, baseGPR, thisValueGPR, resultGPR, node->identifierNumber(), notCellList);
3576             
3577             jsValueResult(resultGPR, node);
3578         }
3579         
3580         break;
3581     }
3582
3583     case GetArrayLength:
3584         compileGetArrayLength(node);
3585         break;
3586
3587     case DeleteById: {
3588         compileDeleteById(node);
3589         break;
3590     }
3591
3592     case DeleteByVal: {
3593         compileDeleteByVal(node);
3594         break;
3595     }
3596         
3597     case CheckCell: {
3598         compileCheckCell(node);
3599         break;
3600     }
3601
3602     case CheckNotEmpty: {
3603         compileCheckNotEmpty(node);
3604         break;
3605     }
3606
3607     case AssertNotEmpty: {
3608         if (validationEnabled()) {
3609             JSValueOperand operand(this, node->child1());
3610             GPRReg input = operand.gpr();
3611             auto done = m_jit.branchTest64(MacroAssembler::NonZero, input);
3612             m_jit.breakpoint();
3613             done.link(&m_jit);
3614         }
3615         noResult(node);
3616         break;
3617     }
3618
3619     case CheckStringIdent:
3620         compileCheckStringIdent(node);
3621         break;
3622
3623     case GetExecutable: {
3624         compileGetExecutable(node);
3625         break;
3626     }
3627         
3628     case CheckStructureOrEmpty: {
3629         SpeculateCellOperand cell(this, node->child1());
3630         GPRReg cellGPR = cell.gpr();
3631         MacroAssembler::Jump isEmpty;
3632         if (m_interpreter.forNode(node->child1()).m_type & SpecEmpty)
3633             isEmpty = m_jit.branchTest64(MacroAssembler::Zero, cellGPR);
3634
3635         emitStructureCheck(node, cellGPR, InvalidGPRReg);
3636
3637         if (isEmpty.isSet())
3638             isEmpty.link(&m_jit);
3639
3640         noResult(node);
3641         break;
3642     }
3643
3644     case CheckStructure: {
3645         compileCheckStructure(node);
3646         break;
3647     }
3648         
3649     case PutStructure: {
3650         RegisteredStructure oldStructure = node->transition()->previous;
3651         RegisteredStructure newStructure = node->transition()->next;
3652
3653         m_jit.jitCode()->common.notifyCompilingStructureTransition(m_jit.graph().m_plan, m_jit.codeBlock(), node);
3654
3655         SpeculateCellOperand base(this, node->child1());
3656         GPRReg baseGPR = base.gpr();
3657         
3658         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
3659         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
3660         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
3661         m_jit.store32(MacroAssembler::TrustedImm32(newStructure->id()), MacroAssembler::Address(baseGPR, JSCell::structureIDOffset()));
3662         
3663         noResult(node);
3664         break;
3665     }
3666         
3667     case AllocatePropertyStorage:
3668         compileAllocatePropertyStorage(node);
3669         break;
3670         
3671     case ReallocatePropertyStorage:
3672         compileReallocatePropertyStorage(node);
3673         break;
3674         
3675     case NukeStructureAndSetButterfly:
3676         compileNukeStructureAndSetButterfly(node);
3677         break;
3678         
3679     case GetButterfly:
3680         compileGetButterfly(node);
3681         break;
3682
3683     case GetIndexedPropertyStorage: {
3684         compileGetIndexedPropertyStorage(node);
3685         break;
3686     }
3687         
3688     case ConstantStoragePointer: {
3689         compileConstantStoragePointer(node);