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