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