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