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