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