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