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