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