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