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