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