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