[JSC] Add SameValue DFG node
[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 SameValue:
2381         compileSameValue(node);
2382         break;
2383
2384     case StringCharCodeAt: {
2385         compileGetCharCodeAt(node);
2386         break;
2387     }
2388
2389     case StringCharAt: {
2390         // Relies on StringCharAt node having same basic layout as GetByVal
2391         compileGetByValOnString(node);
2392         break;
2393     }
2394
2395     case StringFromCharCode: {
2396         compileFromCharCode(node);
2397         break;
2398     }
2399         
2400     case CheckArray: {
2401         checkArray(node);
2402         break;
2403     }
2404         
2405     case Arrayify:
2406     case ArrayifyToStructure: {
2407         arrayify(node);
2408         break;
2409     }
2410
2411     case GetByVal: {
2412         switch (node->arrayMode().type()) {
2413         case Array::SelectUsingPredictions:
2414         case Array::ForceExit:
2415             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
2416             break;
2417         case Array::Undecided: {
2418             SpeculateStrictInt32Operand index(this, m_graph.varArgChild(node, 1));
2419             GPRTemporary result(this, Reuse, index);
2420             GPRReg indexGPR = index.gpr();
2421             GPRReg resultGPR = result.gpr();
2422
2423             speculationCheck(OutOfBounds, JSValueRegs(), node,
2424                 m_jit.branch32(MacroAssembler::LessThan, indexGPR, MacroAssembler::TrustedImm32(0)));
2425
2426             use(m_graph.varArgChild(node, 0));
2427             index.use();
2428
2429             m_jit.move(MacroAssembler::TrustedImm64(ValueUndefined), resultGPR);
2430             jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
2431             break;
2432         }
2433         case Array::Generic: {
2434             if (m_graph.varArgChild(node, 0).useKind() == ObjectUse) {
2435                 if (m_graph.varArgChild(node, 1).useKind() == StringUse) {
2436                     compileGetByValForObjectWithString(node);
2437                     break;
2438                 }
2439
2440                 if (m_graph.varArgChild(node, 1).useKind() == SymbolUse) {
2441                     compileGetByValForObjectWithSymbol(node);
2442                     break;
2443                 }
2444             }
2445             JSValueOperand base(this, m_graph.varArgChild(node, 0));
2446             JSValueOperand property(this, m_graph.varArgChild(node, 1));
2447             GPRReg baseGPR = base.gpr();
2448             GPRReg propertyGPR = property.gpr();
2449             
2450             flushRegisters();
2451             GPRFlushedCallResult result(this);
2452             callOperation(operationGetByVal, result.gpr(), baseGPR, propertyGPR);
2453             m_jit.exceptionCheck();
2454             
2455             jsValueResult(result.gpr(), node);
2456             break;
2457         }
2458         case Array::Int32:
2459         case Array::Contiguous: {
2460             if (node->arrayMode().isInBounds()) {
2461                 SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2462                 StorageOperand storage(this, m_graph.varArgChild(node, 2));
2463
2464                 GPRReg propertyReg = property.gpr();
2465                 GPRReg storageReg = storage.gpr();
2466
2467                 if (!m_compileOkay)
2468                     return;
2469                 
2470                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2471                 
2472                 GPRTemporary result(this);
2473
2474                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), result.gpr());
2475                 if (node->arrayMode().isSaneChain()) {
2476                     ASSERT(node->arrayMode().type() == Array::Contiguous);
2477                     JITCompiler::Jump notHole = m_jit.branchTest64(
2478                         MacroAssembler::NonZero, result.gpr());
2479                     m_jit.move(TrustedImm64(JSValue::encode(jsUndefined())), result.gpr());
2480                     notHole.link(&m_jit);
2481                 } else {
2482                     speculationCheck(
2483                         LoadFromHole, JSValueRegs(), 0,
2484                         m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
2485                 }
2486                 jsValueResult(result.gpr(), node, node->arrayMode().type() == Array::Int32 ? DataFormatJSInt32 : DataFormatJS);
2487                 break;
2488             }
2489             
2490             SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
2491             SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2492             StorageOperand storage(this, m_graph.varArgChild(node, 2));
2493             
2494             GPRReg baseReg = base.gpr();
2495             GPRReg propertyReg = property.gpr();
2496             GPRReg storageReg = storage.gpr();
2497             
2498             if (!m_compileOkay)
2499                 return;
2500             
2501             GPRTemporary result(this);
2502             GPRReg resultReg = result.gpr();
2503             
2504             MacroAssembler::JumpList slowCases;
2505             
2506             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2507
2508             m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2509             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
2510             
2511             addSlowPathGenerator(
2512                 slowPathCall(
2513                     slowCases, this, operationGetByValObjectInt,
2514                     result.gpr(), baseReg, propertyReg));
2515             
2516             jsValueResult(resultReg, node);
2517             break;
2518         }
2519
2520         case Array::Double: {
2521             if (node->arrayMode().isInBounds()) {
2522                 SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2523                 StorageOperand storage(this, m_graph.varArgChild(node, 2));
2524
2525                 GPRReg propertyReg = property.gpr();
2526                 GPRReg storageReg = storage.gpr();
2527
2528                 if (!m_compileOkay)
2529                     return;
2530
2531                 FPRTemporary result(this);
2532                 FPRReg resultReg = result.fpr();
2533
2534                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2535
2536                 m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), resultReg);
2537                 if (!node->arrayMode().isSaneChain())
2538                     speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, resultReg, resultReg));
2539                 doubleResult(resultReg, node);
2540                 break;
2541             }
2542
2543             SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
2544             SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2545             StorageOperand storage(this, m_graph.varArgChild(node, 2));
2546             
2547             GPRReg baseReg = base.gpr();
2548             GPRReg propertyReg = property.gpr();
2549             GPRReg storageReg = storage.gpr();
2550             
2551             if (!m_compileOkay)
2552                 return;
2553             
2554             GPRTemporary result(this);
2555             FPRTemporary temp(this);
2556             GPRReg resultReg = result.gpr();
2557             FPRReg tempReg = temp.fpr();
2558             
2559             MacroAssembler::JumpList slowCases;
2560             
2561             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2562
2563             m_jit.loadDouble(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight), tempReg);
2564             slowCases.append(m_jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, tempReg, tempReg));
2565             boxDouble(tempReg, resultReg);
2566             
2567             addSlowPathGenerator(
2568                 slowPathCall(
2569                     slowCases, this, operationGetByValObjectInt,
2570                     result.gpr(), baseReg, propertyReg));
2571             
2572             jsValueResult(resultReg, node);
2573             break;
2574         }
2575
2576         case Array::ArrayStorage:
2577         case Array::SlowPutArrayStorage: {
2578             if (node->arrayMode().isInBounds()) {
2579                 SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2580                 StorageOperand storage(this, m_graph.varArgChild(node, 2));
2581             
2582                 GPRReg propertyReg = property.gpr();
2583                 GPRReg storageReg = storage.gpr();
2584             
2585                 if (!m_compileOkay)
2586                     return;
2587             
2588                 speculationCheck(OutOfBounds, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2589             
2590                 GPRTemporary result(this);
2591                 m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), result.gpr());
2592                 speculationCheck(LoadFromHole, JSValueRegs(), 0, m_jit.branchTest64(MacroAssembler::Zero, result.gpr()));
2593             
2594                 jsValueResult(result.gpr(), node);
2595                 break;
2596             }
2597
2598             SpeculateCellOperand base(this, m_graph.varArgChild(node, 0));
2599             SpeculateStrictInt32Operand property(this, m_graph.varArgChild(node, 1));
2600             StorageOperand storage(this, m_graph.varArgChild(node, 2));
2601             
2602             GPRReg baseReg = base.gpr();
2603             GPRReg propertyReg = property.gpr();
2604             GPRReg storageReg = storage.gpr();
2605             
2606             if (!m_compileOkay)
2607                 return;
2608             
2609             GPRTemporary result(this);
2610             GPRReg resultReg = result.gpr();
2611             
2612             MacroAssembler::JumpList slowCases;
2613             
2614             slowCases.append(m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset())));
2615     
2616             m_jit.load64(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), resultReg);
2617             slowCases.append(m_jit.branchTest64(MacroAssembler::Zero, resultReg));
2618     
2619             addSlowPathGenerator(
2620                 slowPathCall(
2621                     slowCases, this, operationGetByValObjectInt,
2622                     result.gpr(), baseReg, propertyReg));
2623             
2624             jsValueResult(resultReg, node);
2625             break;
2626         }
2627         case Array::String:
2628             compileGetByValOnString(node);
2629             break;
2630         case Array::DirectArguments:
2631             compileGetByValOnDirectArguments(node);
2632             break;
2633         case Array::ScopedArguments:
2634             compileGetByValOnScopedArguments(node);
2635             break;
2636         default: {
2637             TypedArrayType type = node->arrayMode().typedArrayType();
2638             if (isInt(type))
2639                 compileGetByValOnIntTypedArray(node, type);
2640             else
2641                 compileGetByValOnFloatTypedArray(node, type);
2642         } }
2643         break;
2644     }
2645
2646     case GetByValWithThis: {
2647         compileGetByValWithThis(node);
2648         break;
2649     }
2650
2651     case PutByValDirect:
2652     case PutByVal:
2653     case PutByValAlias: {
2654         Edge child1 = m_jit.graph().varArgChild(node, 0);
2655         Edge child2 = m_jit.graph().varArgChild(node, 1);
2656         Edge child3 = m_jit.graph().varArgChild(node, 2);
2657         Edge child4 = m_jit.graph().varArgChild(node, 3);
2658         
2659         ArrayMode arrayMode = node->arrayMode().modeForPut();
2660         bool alreadyHandled = false;
2661         
2662         switch (arrayMode.type()) {
2663         case Array::SelectUsingPredictions:
2664         case Array::ForceExit:
2665             DFG_CRASH(m_jit.graph(), node, "Bad array mode type");
2666             break;
2667         case Array::Generic: {
2668             DFG_ASSERT(m_jit.graph(), node, node->op() == PutByVal || node->op() == PutByValDirect, node->op());
2669
2670             if (child1.useKind() == CellUse) {
2671                 if (child2.useKind() == StringUse) {
2672                     compilePutByValForCellWithString(node, child1, child2, child3);
2673                     alreadyHandled = true;
2674                     break;
2675                 }
2676
2677                 if (child2.useKind() == SymbolUse) {
2678                     compilePutByValForCellWithSymbol(node, child1, child2, child3);
2679                     alreadyHandled = true;
2680                     break;
2681                 }
2682             }
2683             
2684             JSValueOperand arg1(this, child1);
2685             JSValueOperand arg2(this, child2);
2686             JSValueOperand arg3(this, child3);
2687             GPRReg arg1GPR = arg1.gpr();
2688             GPRReg arg2GPR = arg2.gpr();
2689             GPRReg arg3GPR = arg3.gpr();
2690             flushRegisters();
2691             if (node->op() == PutByValDirect)
2692                 callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValDirectStrict : operationPutByValDirectNonStrict, arg1GPR, arg2GPR, arg3GPR);
2693             else
2694                 callOperation(m_jit.isStrictModeFor(node->origin.semantic) ? operationPutByValStrict : operationPutByValNonStrict, arg1GPR, arg2GPR, arg3GPR);
2695             m_jit.exceptionCheck();
2696             
2697             noResult(node);
2698             alreadyHandled = true;
2699             break;
2700         }
2701         default:
2702             break;
2703         }
2704         
2705         if (alreadyHandled)
2706             break;
2707
2708         SpeculateCellOperand base(this, child1);
2709         SpeculateStrictInt32Operand property(this, child2);
2710         
2711         GPRReg baseReg = base.gpr();
2712         GPRReg propertyReg = property.gpr();
2713
2714         switch (arrayMode.type()) {
2715         case Array::Int32:
2716         case Array::Contiguous: {
2717             JSValueOperand value(this, child3, ManualOperandSpeculation);
2718
2719             GPRReg valueReg = value.gpr();
2720         
2721             if (!m_compileOkay)
2722                 return;
2723             
2724             if (arrayMode.type() == Array::Int32) {
2725                 DFG_TYPE_CHECK(
2726                     JSValueRegs(valueReg), child3, SpecInt32Only,
2727                     m_jit.branch64(
2728                         MacroAssembler::Below, valueReg, GPRInfo::tagTypeNumberRegister));
2729             }
2730
2731             StorageOperand storage(this, child4);
2732             GPRReg storageReg = storage.gpr();
2733
2734             if (node->op() == PutByValAlias) {
2735                 // Store the value to the array.
2736                 GPRReg propertyReg = property.gpr();
2737                 GPRReg valueReg = value.gpr();
2738                 m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
2739                 
2740                 noResult(node);
2741                 break;
2742             }
2743             
2744             GPRTemporary temporary;
2745             GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
2746
2747             MacroAssembler::Jump slowCase;
2748             
2749             if (arrayMode.isInBounds()) {
2750                 speculationCheck(
2751                     OutOfBounds, JSValueRegs(), 0,
2752                     m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength())));
2753             } else {
2754                 MacroAssembler::Jump inBounds = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2755                 
2756                 slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfVectorLength()));
2757                 
2758                 if (!arrayMode.isOutOfBounds())
2759                     speculationCheck(OutOfBounds, JSValueRegs(), 0, slowCase);
2760                 
2761                 m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
2762                 m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, Butterfly::offsetOfPublicLength()));
2763
2764                 inBounds.link(&m_jit);
2765             }
2766
2767             m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight));
2768
2769             base.use();
2770             property.use();
2771             value.use();
2772             storage.use();
2773             
2774             if (arrayMode.isOutOfBounds()) {
2775                 addSlowPathGenerator(slowPathCall(
2776                     slowCase, this,
2777                     m_jit.codeBlock()->isStrictMode()
2778                         ? (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsStrict)
2779                         : (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsNonStrict : operationPutByValBeyondArrayBoundsNonStrict),
2780                     NoResult, baseReg, propertyReg, valueReg));
2781             }
2782
2783             noResult(node, UseChildrenCalledExplicitly);
2784             break;
2785         }
2786             
2787         case Array::Double: {
2788             compileDoublePutByVal(node, base, property);
2789             break;
2790         }
2791             
2792         case Array::ArrayStorage:
2793         case Array::SlowPutArrayStorage: {
2794             JSValueOperand value(this, child3);
2795
2796             GPRReg valueReg = value.gpr();
2797         
2798             if (!m_compileOkay)
2799                 return;
2800
2801             StorageOperand storage(this, child4);
2802             GPRReg storageReg = storage.gpr();
2803
2804             if (node->op() == PutByValAlias) {
2805                 // Store the value to the array.
2806                 GPRReg propertyReg = property.gpr();
2807                 GPRReg valueReg = value.gpr();
2808                 m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
2809                 
2810                 noResult(node);
2811                 break;
2812             }
2813             
2814             GPRTemporary temporary;
2815             GPRReg temporaryReg = temporaryRegisterForPutByVal(temporary, node);
2816
2817             MacroAssembler::JumpList slowCases;
2818
2819             MacroAssembler::Jump beyondArrayBounds = m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::vectorLengthOffset()));
2820             if (!arrayMode.isOutOfBounds())
2821                 speculationCheck(OutOfBounds, JSValueRegs(), 0, beyondArrayBounds);
2822             else
2823                 slowCases.append(beyondArrayBounds);
2824
2825             // Check if we're writing to a hole; if so increment m_numValuesInVector.
2826             if (arrayMode.isInBounds()) {
2827                 speculationCheck(
2828                     StoreToHole, JSValueRegs(), 0,
2829                     m_jit.branchTest64(MacroAssembler::Zero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset())));
2830             } else {
2831                 MacroAssembler::Jump notHoleValue = m_jit.branchTest64(MacroAssembler::NonZero, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
2832                 if (arrayMode.isSlowPut()) {
2833                     // This is sort of strange. If we wanted to optimize this code path, we would invert
2834                     // the above branch. But it's simply not worth it since this only happens if we're
2835                     // already having a bad time.
2836                     slowCases.append(m_jit.jump());
2837                 } else {
2838                     m_jit.add32(TrustedImm32(1), MacroAssembler::Address(storageReg, ArrayStorage::numValuesInVectorOffset()));
2839                 
2840                     // If we're writing to a hole we might be growing the array; 
2841                     MacroAssembler::Jump lengthDoesNotNeedUpdate = m_jit.branch32(MacroAssembler::Below, propertyReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2842                     m_jit.add32(TrustedImm32(1), propertyReg, temporaryReg);
2843                     m_jit.store32(temporaryReg, MacroAssembler::Address(storageReg, ArrayStorage::lengthOffset()));
2844                 
2845                     lengthDoesNotNeedUpdate.link(&m_jit);
2846                 }
2847                 notHoleValue.link(&m_jit);
2848             }
2849     
2850             // Store the value to the array.
2851             m_jit.store64(valueReg, MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()));
2852
2853             base.use();
2854             property.use();
2855             value.use();
2856             storage.use();
2857             
2858             if (!slowCases.empty()) {
2859                 addSlowPathGenerator(slowPathCall(
2860                     slowCases, this,
2861                     m_jit.codeBlock()->isStrictMode()
2862                         ? (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsStrict : operationPutByValBeyondArrayBoundsStrict)
2863                         : (node->op() == PutByValDirect ? operationPutByValDirectBeyondArrayBoundsNonStrict : operationPutByValBeyondArrayBoundsNonStrict),
2864                     NoResult, baseReg, propertyReg, valueReg));
2865             }
2866
2867             noResult(node, UseChildrenCalledExplicitly);
2868             break;
2869         }
2870             
2871         default: {
2872             TypedArrayType type = arrayMode.typedArrayType();
2873             if (isInt(type))
2874                 compilePutByValForIntTypedArray(base.gpr(), property.gpr(), node, type);
2875             else
2876                 compilePutByValForFloatTypedArray(base.gpr(), property.gpr(), node, type);
2877         } }
2878
2879         break;
2880     }
2881         
2882     case AtomicsAdd:
2883     case AtomicsAnd:
2884     case AtomicsCompareExchange:
2885     case AtomicsExchange:
2886     case AtomicsLoad:
2887     case AtomicsOr:
2888     case AtomicsStore:
2889     case AtomicsSub:
2890     case AtomicsXor: {
2891         unsigned numExtraArgs = numExtraAtomicsArgs(node->op());
2892         Edge baseEdge = m_jit.graph().child(node, 0);
2893         Edge indexEdge = m_jit.graph().child(node, 1);
2894         Edge argEdges[maxNumExtraAtomicsArgs];
2895         for (unsigned i = numExtraArgs; i--;)
2896             argEdges[i] = m_jit.graph().child(node, 2 + i);
2897         Edge storageEdge = m_jit.graph().child(node, 2 + numExtraArgs);
2898
2899         GPRReg baseGPR;
2900         GPRReg indexGPR;
2901         GPRReg argGPRs[2];
2902         GPRReg resultGPR;
2903
2904         auto callSlowPath = [&] () {
2905             switch (node->op()) {
2906             case AtomicsAdd:
2907                 callOperation(operationAtomicsAdd, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2908                 break;
2909             case AtomicsAnd:
2910                 callOperation(operationAtomicsAnd, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2911                 break;
2912             case AtomicsCompareExchange:
2913                 callOperation(operationAtomicsCompareExchange, resultGPR, baseGPR, indexGPR, argGPRs[0], argGPRs[1]);
2914                 break;
2915             case AtomicsExchange:
2916                 callOperation(operationAtomicsExchange, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2917                 break;
2918             case AtomicsLoad:
2919                 callOperation(operationAtomicsLoad, resultGPR, baseGPR, indexGPR);
2920                 break;
2921             case AtomicsOr:
2922                 callOperation(operationAtomicsOr, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2923                 break;
2924             case AtomicsStore:
2925                 callOperation(operationAtomicsStore, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2926                 break;
2927             case AtomicsSub:
2928                 callOperation(operationAtomicsSub, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2929                 break;
2930             case AtomicsXor:
2931                 callOperation(operationAtomicsXor, resultGPR, baseGPR, indexGPR, argGPRs[0]);
2932                 break;
2933             default:
2934                 RELEASE_ASSERT_NOT_REACHED();
2935                 break;
2936             }
2937         };
2938         
2939         if (!storageEdge) {
2940             // We are in generic mode!
2941             JSValueOperand base(this, baseEdge);
2942             JSValueOperand index(this, indexEdge);
2943             std::optional<JSValueOperand> args[2];
2944             baseGPR = base.gpr();
2945             indexGPR = index.gpr();
2946             for (unsigned i = numExtraArgs; i--;) {
2947                 args[i].emplace(this, argEdges[i]);
2948                 argGPRs[i] = args[i]->gpr();
2949             }
2950             
2951             flushRegisters();
2952             GPRFlushedCallResult result(this);
2953             resultGPR = result.gpr();
2954             callSlowPath();
2955             m_jit.exceptionCheck();
2956             
2957             jsValueResult(resultGPR, node);
2958             break;
2959         }
2960         
2961         TypedArrayType type = node->arrayMode().typedArrayType();
2962         
2963         SpeculateCellOperand base(this, baseEdge);
2964         SpeculateStrictInt32Operand index(this, indexEdge);
2965
2966         baseGPR = base.gpr();
2967         indexGPR = index.gpr();
2968         
2969         emitTypedArrayBoundsCheck(node, baseGPR, indexGPR);
2970         
2971         GPRTemporary args[2];
2972         
2973         JITCompiler::JumpList slowPathCases;
2974         
2975         bool ok = true;
2976         for (unsigned i = numExtraArgs; i--;) {
2977             if (!getIntTypedArrayStoreOperand(args[i], indexGPR, argEdges[i], slowPathCases)) {
2978                 noResult(node);
2979                 ok = false;
2980             }
2981             argGPRs[i] = args[i].gpr();
2982         }
2983         if (!ok)
2984             break;
2985         
2986         StorageOperand storage(this, storageEdge);
2987         GPRTemporary oldValue(this);
2988         GPRTemporary result(this);
2989         GPRTemporary newValue(this);
2990         GPRReg storageGPR = storage.gpr();
2991         GPRReg oldValueGPR = oldValue.gpr();
2992         resultGPR = result.gpr();
2993         GPRReg newValueGPR = newValue.gpr();
2994         
2995         // FIXME: It shouldn't be necessary to nop-pad between register allocation and a jump label.
2996         // https://bugs.webkit.org/show_bug.cgi?id=170974
2997         m_jit.nop();
2998         
2999         JITCompiler::Label loop = m_jit.label();
3000         
3001         loadFromIntTypedArray(storageGPR, indexGPR, oldValueGPR, type);
3002         m_jit.move(oldValueGPR, newValueGPR);
3003         m_jit.move(oldValueGPR, resultGPR);
3004         
3005         switch (node->op()) {
3006         case AtomicsAdd:
3007             m_jit.add32(argGPRs[0], newValueGPR);
3008             break;
3009         case AtomicsAnd:
3010             m_jit.and32(argGPRs[0], newValueGPR);
3011             break;
3012         case AtomicsCompareExchange: {
3013             switch (elementSize(type)) {
3014             case 1:
3015                 if (isSigned(type))
3016                     m_jit.signExtend8To32(argGPRs[0], argGPRs[0]);
3017                 else
3018                     m_jit.and32(TrustedImm32(0xff), argGPRs[0]);
3019                 break;
3020             case 2:
3021                 if (isSigned(type))
3022                     m_jit.signExtend16To32(argGPRs[0], argGPRs[0]);
3023                 else
3024                     m_jit.and32(TrustedImm32(0xffff), argGPRs[0]);
3025                 break;
3026             case 4:
3027                 break;
3028             default:
3029                 RELEASE_ASSERT_NOT_REACHED();
3030                 break;
3031             }
3032             JITCompiler::Jump fail = m_jit.branch32(JITCompiler::NotEqual, oldValueGPR, argGPRs[0]);
3033             m_jit.move(argGPRs[1], newValueGPR);
3034             fail.link(&m_jit);
3035             break;
3036         }
3037         case AtomicsExchange:
3038             m_jit.move(argGPRs[0], newValueGPR);
3039             break;
3040         case AtomicsLoad:
3041             break;
3042         case AtomicsOr:
3043             m_jit.or32(argGPRs[0], newValueGPR);
3044             break;
3045         case AtomicsStore:
3046             m_jit.move(argGPRs[0], newValueGPR);
3047             m_jit.move(argGPRs[0], resultGPR);
3048             break;
3049         case AtomicsSub:
3050             m_jit.sub32(argGPRs[0], newValueGPR);
3051             break;
3052         case AtomicsXor:
3053             m_jit.xor32(argGPRs[0], newValueGPR);
3054             break;
3055         default:
3056             RELEASE_ASSERT_NOT_REACHED();
3057             break;
3058         }
3059         
3060         JITCompiler::JumpList success;
3061         switch (elementSize(type)) {
3062         case 1:
3063             success = m_jit.branchAtomicWeakCAS8(JITCompiler::Success, oldValueGPR, newValueGPR, JITCompiler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesOne));
3064             break;
3065         case 2:
3066             success = m_jit.branchAtomicWeakCAS16(JITCompiler::Success, oldValueGPR, newValueGPR, JITCompiler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesTwo));
3067             break;
3068         case 4:
3069             success = m_jit.branchAtomicWeakCAS32(JITCompiler::Success, oldValueGPR, newValueGPR, JITCompiler::BaseIndex(storageGPR, indexGPR, MacroAssembler::TimesFour));
3070             break;
3071         default:
3072             RELEASE_ASSERT_NOT_REACHED();
3073             break;
3074         }
3075         m_jit.jump().linkTo(loop, &m_jit);
3076         
3077         if (!slowPathCases.empty()) {
3078             slowPathCases.link(&m_jit);
3079             silentSpillAllRegisters(resultGPR);
3080             // Since we spilled, we can do things to registers.
3081             m_jit.boxCell(baseGPR, JSValueRegs(baseGPR));
3082             m_jit.boxInt32(indexGPR, JSValueRegs(indexGPR));
3083             for (unsigned i = numExtraArgs; i--;)
3084                 m_jit.boxInt32(argGPRs[i], JSValueRegs(argGPRs[i]));
3085             callSlowPath();
3086             silentFillAllRegisters();
3087             m_jit.exceptionCheck();
3088         }
3089         
3090         success.link(&m_jit);
3091         setIntTypedArrayLoadResult(node, resultGPR, type);
3092         break;
3093     }
3094         
3095     case AtomicsIsLockFree: {
3096         if (node->child1().useKind() != Int32Use) {
3097             JSValueOperand operand(this, node->child1());
3098             GPRReg operandGPR = operand.gpr();
3099             flushRegisters();
3100             GPRFlushedCallResult result(this);
3101             GPRReg resultGPR = result.gpr();
3102             callOperation(operationAtomicsIsLockFree, resultGPR, operandGPR);
3103             m_jit.exceptionCheck();
3104             jsValueResult(resultGPR, node);
3105             break;
3106         }
3107
3108         SpeculateInt32Operand operand(this, node->child1());
3109         GPRTemporary result(this);
3110         GPRReg operandGPR = operand.gpr();
3111         GPRReg resultGPR = result.gpr();
3112         m_jit.move(TrustedImm32(ValueTrue), resultGPR);
3113         JITCompiler::JumpList done;
3114         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(4)));
3115         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(1)));
3116         done.append(m_jit.branch32(JITCompiler::Equal, operandGPR, TrustedImm32(2)));
3117         m_jit.move(TrustedImm32(ValueFalse), resultGPR);
3118         done.link(&m_jit);
3119         jsValueResult(resultGPR, node);
3120         break;
3121     }
3122
3123     case RegExpExec: {
3124         compileRegExpExec(node);
3125         break;
3126     }
3127
3128     case RegExpExecNonGlobalOrSticky: {
3129         compileRegExpExecNonGlobalOrSticky(node);
3130         break;
3131     }
3132
3133     case RegExpMatchFastGlobal: {
3134         compileRegExpMatchFastGlobal(node);
3135         break;
3136     }
3137
3138     case RegExpTest: {
3139         compileRegExpTest(node);
3140         break;
3141     }
3142
3143     case RegExpMatchFast: {
3144         compileRegExpMatchFast(node);
3145         break;
3146     }
3147
3148     case StringReplace:
3149     case StringReplaceRegExp: {
3150         compileStringReplace(node);
3151         break;
3152     }
3153         
3154     case GetRegExpObjectLastIndex: {
3155         compileGetRegExpObjectLastIndex(node);
3156         break;
3157     }
3158         
3159     case SetRegExpObjectLastIndex: {
3160         compileSetRegExpObjectLastIndex(node);
3161         break;
3162     }
3163
3164     case RecordRegExpCachedResult: {
3165         compileRecordRegExpCachedResult(node);
3166         break;
3167     }
3168         
3169     case ArrayPush: {
3170         compileArrayPush(node);
3171         break;
3172     }
3173
3174     case ArraySlice: {
3175         compileArraySlice(node);
3176         break;
3177     }
3178
3179     case ArrayIndexOf: {
3180         compileArrayIndexOf(node);
3181         break;
3182     }
3183         
3184     case ArrayPop: {
3185         ASSERT(node->arrayMode().isJSArray());
3186
3187         SpeculateCellOperand base(this, node->child1());
3188         StorageOperand storage(this, node->child2());
3189         GPRTemporary value(this);
3190         GPRTemporary storageLength(this);
3191         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().
3192    &