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